From 95badabaaf27688175dcd751137423b71728eff6 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Mon, 12 Aug 2013 19:09:46 -0700 Subject: [PATCH] std: Re-optimize tls access on local allocation path I did this once but acciddentally undid it in a later patch. --- src/libstd/rt/local.rs | 6 +----- src/libstd/rt/local_heap.rs | 9 +++++++-- src/libstd/rt/local_ptr.rs | 11 +++++++++-- src/libstd/unstable/lang.rs | 14 +++++++------- 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/libstd/rt/local.rs b/src/libstd/rt/local.rs index 7154066e7b748..1faad913b5025 100644 --- a/src/libstd/rt/local.rs +++ b/src/libstd/rt/local.rs @@ -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::() { - Some(Local::unsafe_borrow()) - } else { - None - } + local_ptr::try_unsafe_borrow() } } diff --git a/src/libstd/rt/local_heap.rs b/src/libstd/rt/local_heap.rs index 11afd03033a90..8715e768e3276 100644 --- a/src/libstd/rt/local_heap.rs +++ b/src/libstd/rt/local_heap.rs @@ -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.heap.free(ptr as *libc::c_void); + // XXX: Unsafe borrow for speed. Lame. + match Local::try_unsafe_borrow::() { + Some(task) => { + (*task).heap.free(ptr as *libc::c_void); + } + None => rtabort!("local free outside of task") } } diff --git a/src/libstd/rt/local_ptr.rs b/src/libstd/rt/local_ptr.rs index 652e39b05c7e0..2ec43980419c9 100644 --- a/src/libstd/rt/local_ptr.rs +++ b/src/libstd/rt/local_ptr.rs @@ -97,16 +97,23 @@ pub unsafe fn borrow(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() -> *mut T { + match try_unsafe_borrow() { + Some(p) => p, + None => rtabort!("thread-local pointer is null. bogus!") + } +} + +pub unsafe fn try_unsafe_borrow() -> 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); } } diff --git a/src/libstd/unstable/lang.rs b/src/libstd/unstable/lang.rs index d8df967a45ca2..956ffb82902de 100644 --- a/src/libstd/unstable/lang.rs +++ b/src/libstd/unstable/lang.rs @@ -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| { - 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::() { + 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