Skip to content

std: Re-optimize tls access on local allocation path #8487

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions src/libstd/rt/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
}

Expand Down
9 changes: 7 additions & 2 deletions src/libstd/rt/local_heap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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")
}
}

Expand Down
11 changes: 9 additions & 2 deletions src/libstd/rt/local_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand Down
14 changes: 7 additions & 7 deletions src/libstd/unstable/lang.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down