From 14c1a103bc3f78721df1dc860a75a477c8275e3a Mon Sep 17 00:00:00 2001 From: Aaron Turon Date: Sun, 7 Dec 2014 00:32:50 -0800 Subject: [PATCH] Revise rt::unwind --- src/libstd/rt/mod.rs | 4 --- src/libstd/rt/unwind.rs | 42 ++++------------------------ src/libstd/sys/common/thread_info.rs | 30 ++++++++++++++++---- 3 files changed, 30 insertions(+), 46 deletions(-) diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index a3b1d831a385e..44794d2b957ce 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -72,10 +72,6 @@ mod macros; // These should be refactored/moved/made private over time pub mod util; -<<<<<<< HEAD -======= -pub mod task; ->>>>>>> Remove rt::{local, local_data, thread_local_storage} pub mod unwind; mod args; diff --git a/src/libstd/rt/unwind.rs b/src/libstd/rt/unwind.rs index 1ac06270851c5..decf7cfb60a27 100644 --- a/src/libstd/rt/unwind.rs +++ b/src/libstd/rt/unwind.rs @@ -72,16 +72,9 @@ use mem; use raw::Closure; use libc::c_void; -use rt::local::Local; -use rt::task::Task; - +use sys_common::thread_info; use rt::libunwind as uw; -#[allow(missing_copy_implementations)] -pub struct Unwinder { - unwinding: bool, -} - struct Exception { uwe: uw::_Unwind_Exception, cause: Option>, @@ -104,18 +97,6 @@ static CALLBACKS: [atomic::AtomicUint, ..MAX_CALLBACKS] = atomic::INIT_ATOMIC_UINT, atomic::INIT_ATOMIC_UINT]; static CALLBACK_CNT: atomic::AtomicUint = atomic::INIT_ATOMIC_UINT; -impl Unwinder { - pub fn new() -> Unwinder { - Unwinder { - unwinding: false, - } - } - - pub fn unwinding(&self) -> bool { - self.unwinding - } -} - /// Invoke a closure, capturing the cause of panic if one occurs. /// /// This function will return `None` if the closure did not panic, and will @@ -556,7 +537,7 @@ pub fn begin_unwind(msg: M, file_line: &(&'static str, uint)) -> /// we need the `Any` object anyway, we're not just creating it to /// avoid being generic.) /// -/// Do this split took the LLVM IR line counts of `fn main() { panic!() +/// Doing this split took the LLVM IR line counts of `fn main() { panic!() /// }` from ~1900/3700 (-O/no opts) to 180/590. #[inline(never)] #[cold] // this is the slow path, please never inline this fn begin_unwind_inner(msg: Box, file_line: &(&'static str, uint)) -> ! { @@ -583,27 +564,16 @@ fn begin_unwind_inner(msg: Box, file_line: &(&'static str, uint)) -> }; // Now that we've run all the necessary unwind callbacks, we actually - // perform the unwinding. If we don't have a task, then it's time to die - // (hopefully someone printed something about this). - let mut task: Box = match Local::try_take() { - Some(task) => task, - None => rust_panic(msg), - }; - - if task.unwinder.unwinding { - // If a task panics while it's already unwinding then we + // perform the unwinding. + if thread_info::unwinding() { + // If a thread panics while it's already unwinding then we // have limited options. Currently our preference is to // just abort. In the future we may consider resuming // unwinding or otherwise exiting the task cleanly. rterrln!("task failed during unwinding. aborting."); unsafe { intrinsics::abort() } } - task.unwinder.unwinding = true; - - // Put the task back in TLS because the unwinding process may run code which - // requires the task. We need a handle to its unwinder, however, so after - // this we unsafely extract it and continue along. - Local::put(task); + thread_info::set_unwinding(true); rust_panic(msg); } diff --git a/src/libstd/sys/common/thread_info.rs b/src/libstd/sys/common/thread_info.rs index fb0231b44ba73..f88fd49ab99f5 100644 --- a/src/libstd/sys/common/thread_info.rs +++ b/src/libstd/sys/common/thread_info.rs @@ -8,30 +8,36 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use core::prelude::*; + +use thread::Thread; +use cell::RefCell; +use string::String; + struct ThreadInfo { // This field holds the known bounds of the stack in (lo, hi) // form. Not all threads necessarily know their precise bounds, // hence this is optional. stack_bounds: (uint, uint), stack_guard: uint, - unwinder: Unwinder, + unwinding: bool, thread: Thread, } -thread_local!(static THREAD_INFO: RefCell> = RefCell::new(None)); +thread_local!(static THREAD_INFO: RefCell> = RefCell::new(None)) impl ThreadInfo { - fn with(f: |&ThreadInfo| -> R) -> R { + fn with(f: |&mut ThreadInfo| -> R) -> R { THREAD_INFO.with(|c| { if c.borrow().is_none() { *c.borrow_mut() = Some(ThreadInfo { stack_bounds: (0, 0), stack_guard: 0, - unwinder: Unwinder::new(), + unwinder: false, thread: Thread::new(None), }) } - f(c.borrow().as_ref().unwrap()) + f(c.borrow_mut().as_ref().unwrap()) }) } } @@ -44,12 +50,24 @@ pub fn panicking() -> bool { ThreadInfo::with(|info| info.unwinder.unwinding()) } +pub fn stack_guard() -> uint { + ThreadInfo::with(|info| info.stack_guard) +} + +pub fn unwinding() -> bool { + ThreadInfo::with(|info| info.unwinder.unwinding) +} + +pub fn set_unwinding(unwinding: bool) { + ThreadInfo::with(|info| info.unwinding = unwinding) +} + pub fn set(stack_bounds: (uint, uint), stack_guard: uint, thread: Thread) { THREAD_INFO.with(|c| assert!(c.borrow().is_none())); THREAD_INFO.with(|c| *c.borrow_mut() = Some(ThreadInfo{ stack_bounds: stack_bounds, stack_guard: stack_guard, - unwinder: Unwinder::new(), + unwinding: false, thread: thread, })); }