diff options
| author | Brian Anderson <banderson@mozilla.com> | 2013-08-09 01:15:31 -0700 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2013-08-09 01:15:31 -0700 |
| commit | d39255616004ea43dfabcf33b20ed2a80cd31dff (patch) | |
| tree | 9ff8806f2fe5e92546a6f769f08e798f16863f08 /src/libstd/rt | |
| parent | a931e04b757a795e3867ea98c81cee731bd54ac1 (diff) | |
| download | rust-d39255616004ea43dfabcf33b20ed2a80cd31dff.tar.gz rust-d39255616004ea43dfabcf33b20ed2a80cd31dff.zip | |
std: Fix perf of local allocations in newsched
Mostly optimizing TLS accesses to bring local heap allocation performance closer to that of oldsched. It's not completely at parity but removing the branches involved in supporting oldsched and optimizing pthread_get/setspecific to instead use our dedicated TCB slot will probably make up for it.
Diffstat (limited to 'src/libstd/rt')
| -rw-r--r-- | src/libstd/rt/comm.rs | 4 | ||||
| -rw-r--r-- | src/libstd/rt/local_heap.rs | 22 | ||||
| -rw-r--r-- | src/libstd/rt/mod.rs | 51 |
3 files changed, 49 insertions, 28 deletions
diff --git a/src/libstd/rt/comm.rs b/src/libstd/rt/comm.rs index 936a6526508..793e244bec7 100644 --- a/src/libstd/rt/comm.rs +++ b/src/libstd/rt/comm.rs @@ -15,6 +15,7 @@ use cast; use ops::Drop; use rt::kill::BlockedTask; use kinds::Send; +use rt; use rt::sched::Scheduler; use rt::local::Local; use rt::select::{Select, SelectPort}; @@ -24,7 +25,6 @@ use util::Void; use comm::{GenericChan, GenericSmartChan, GenericPort, Peekable}; use cell::Cell; use clone::Clone; -use rt::{context, SchedulerContext}; use tuple::ImmutableTuple; /// A combined refcount / BlockedTask-as-uint pointer. @@ -113,7 +113,7 @@ impl<T> ChanOne<T> { // 'do_resched' configures whether the scheduler immediately switches to // the receiving task, or leaves the sending task still running. fn try_send_inner(self, val: T, do_resched: bool) -> bool { - rtassert!(context() != SchedulerContext); + rtassert!(!rt::in_sched_context()); let mut this = self; let mut recvr_active = true; diff --git a/src/libstd/rt/local_heap.rs b/src/libstd/rt/local_heap.rs index e1e7ceacc38..8832597f40c 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; use rt::OldTaskContext; use rt::local::Local; @@ -86,8 +87,12 @@ impl Drop for LocalHeap { // A little compatibility function pub unsafe fn local_free(ptr: *libc::c_char) { - match rt::context() { - OldTaskContext => { + // XXX: Unsafe borrow for speed. Lame. + match Local::try_unsafe_borrow::<Task>() { + Some(task) => { + (*task).heap.free(ptr as *libc::c_void); + } + None => { rust_upcall_free_noswitch(ptr); extern { @@ -95,11 +100,6 @@ pub unsafe fn local_free(ptr: *libc::c_char) { fn rust_upcall_free_noswitch(ptr: *libc::c_char); } } - _ => { - do Local::borrow::<Task,()> |task| { - task.heap.free(ptr as *libc::c_void); - } - } } } @@ -119,20 +119,28 @@ pub fn live_allocs() -> *raw::Box<()> { } extern { + #[fast_ffi] fn rust_new_memory_region(synchronized: uintptr_t, detailed_leaks: uintptr_t, poison_on_free: uintptr_t) -> *MemoryRegion; + #[fast_ffi] fn rust_delete_memory_region(region: *MemoryRegion); + #[fast_ffi] fn rust_new_boxed_region(region: *MemoryRegion, poison_on_free: uintptr_t) -> *BoxedRegion; + #[fast_ffi] fn rust_delete_boxed_region(region: *BoxedRegion); + #[fast_ffi] fn rust_boxed_region_malloc(region: *BoxedRegion, td: *TypeDesc, size: size_t) -> *OpaqueBox; + #[fast_ffi] fn rust_boxed_region_realloc(region: *BoxedRegion, ptr: *OpaqueBox, size: size_t) -> *OpaqueBox; + #[fast_ffi] fn rust_boxed_region_free(region: *BoxedRegion, box: *OpaqueBox); + #[fast_ffi] fn rust_current_boxed_region() -> *BoxedRegion; } diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index 01a52892f63..be71bc651df 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -407,14 +407,10 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int { /// or the old scheduler. #[deriving(Eq)] pub enum RuntimeContext { - // Only the exchange heap is available - GlobalContext, - // The scheduler may be accessed - SchedulerContext, - // Full task services, e.g. local heap, unwinding - TaskContext, // Running in an old-style task - OldTaskContext + OldTaskContext, + // Not old task context + NewRtContext } /// Determine the current RuntimeContext @@ -424,19 +420,8 @@ pub fn context() -> RuntimeContext { if unsafe { rust_try_get_task().is_not_null() } { return OldTaskContext; - } else if Local::exists::<Task>() { - // In this case we know it is a new runtime context, but we - // need to check which one. Going to try borrowing task to - // check. Task should always be in TLS, so hopefully this - // doesn't conflict with other ops that borrow. - return do Local::borrow::<Task,RuntimeContext> |task| { - match task.task_type { - SchedTask => SchedulerContext, - GreenTask(_) => TaskContext - } - }; } else { - return GlobalContext; + return NewRtContext; } extern { @@ -444,3 +429,31 @@ pub fn context() -> RuntimeContext { pub fn rust_try_get_task() -> *rust_task; } } + +pub fn in_sched_context() -> bool { + unsafe { + match Local::try_unsafe_borrow::<Task>() { + Some(task) => { + match (*task).task_type { + SchedTask => true, + _ => false + } + } + None => false + } + } +} + +pub fn in_green_task_context() -> bool { + unsafe { + match Local::try_unsafe_borrow::<Task>() { + Some(task) => { + match (*task).task_type { + GreenTask(_) => true, + _ => false + } + } + None => false + } + } +} \ No newline at end of file |
