auto merge of #8487 : brson/rust/local-opts, r=brson

I did this once but acciddentally undid it in a later patch.
This commit is contained in:
bors 2013-08-12 23:56:26 -07:00
commit 4601ea65f8
4 changed files with 24 additions and 16 deletions

View File

@ -45,11 +45,7 @@ impl Local for Task {
}
unsafe fn unsafe_borrow() -> *mut Task { local_ptr::unsafe_borrow() }
unsafe fn try_unsafe_borrow() -> Option<*mut Task> {
if Local::exists::<Task>() {
Some(Local::unsafe_borrow())
} else {
None
}
local_ptr::try_unsafe_borrow()
}
}

View File

@ -13,6 +13,7 @@
use libc;
use libc::{c_void, uintptr_t, size_t};
use ops::Drop;
use option::{Some, None};
use rt::local::Local;
use rt::task::Task;
use unstable::raw;
@ -84,8 +85,12 @@ impl Drop for LocalHeap {
// A little compatibility function
pub unsafe fn local_free(ptr: *libc::c_char) {
do Local::borrow::<Task,()> |task| {
task.heap.free(ptr as *libc::c_void);
// XXX: Unsafe borrow for speed. Lame.
match Local::try_unsafe_borrow::<Task>() {
Some(task) => {
(*task).heap.free(ptr as *libc::c_void);
}
None => rtabort!("local free outside of task")
}
}

View File

@ -97,16 +97,23 @@ pub unsafe fn borrow<T>(f: &fn(&mut T)) {
/// Because this leaves the value in thread-local storage it is possible
/// For the Scheduler pointer to be aliased
pub unsafe fn unsafe_borrow<T>() -> *mut T {
match try_unsafe_borrow() {
Some(p) => p,
None => rtabort!("thread-local pointer is null. bogus!")
}
}
pub unsafe fn try_unsafe_borrow<T>() -> Option<*mut T> {
let key = tls_key();
let mut void_ptr: *mut c_void = tls::get(key);
if void_ptr.is_null() {
rtabort!("thread-local pointer is null. bogus!");
return None;
}
{
let ptr: *mut *mut c_void = &mut void_ptr;
let ptr: *mut ~T = ptr as *mut ~T;
let ptr: *mut T = &mut **ptr;
return ptr;
return Some(ptr);
}
}

View File

@ -13,6 +13,7 @@
use c_str::ToCStr;
use cast::transmute;
use libc::{c_char, c_void, size_t, uintptr_t};
use option::{Some, None};
use sys;
use rt::task::Task;
use rt::local::Local;
@ -35,14 +36,13 @@ pub fn fail_bounds_check(file: *c_char, line: size_t,
#[lang="malloc"]
pub unsafe fn local_malloc(td: *c_char, size: uintptr_t) -> *c_char {
let mut alloc = ::ptr::null();
do Local::borrow::<Task,()> |task| {
rtdebug!("task pointer: %x, heap pointer: %x",
::borrow::to_uint(task),
::borrow::to_uint(&task.heap));
alloc = task.heap.alloc(td as *c_void, size as uint) as *c_char;
// XXX: Unsafe borrow for speed. Lame.
match Local::try_unsafe_borrow::<Task>() {
Some(task) => {
(*task).heap.alloc(td as *c_void, size as uint) as *c_char
}
None => rtabort!("local malloc outside of task")
}
return alloc;
}
// NB: Calls to free CANNOT be allowed to fail, as throwing an exception from