From 6d8330afb6c925d1092f27919f61d4ce6a3fb1d4 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 17 Oct 2013 01:40:33 -0700 Subject: Use __morestack to detect stack overflow This commit resumes management of the stack boundaries and limits when switching between tasks. This additionally leverages the __morestack function to run code on "stack overflow". The current behavior is to abort the process, but this is probably not the best behavior in the long term (for deails, see the comment I wrote up in the stack exhaustion routine). --- src/libstd/rt/thread.rs | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) (limited to 'src/libstd/rt/thread.rs') diff --git a/src/libstd/rt/thread.rs b/src/libstd/rt/thread.rs index 8b64fda2136..e774b81da35 100644 --- a/src/libstd/rt/thread.rs +++ b/src/libstd/rt/thread.rs @@ -8,8 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use cast; use libc; use ops::Drop; +use unstable::raw; +use uint; #[allow(non_camel_case_types)] // runtime type type raw_thread = libc::c_void; @@ -17,21 +20,38 @@ type raw_thread = libc::c_void; pub struct Thread { main: ~fn(), raw_thread: *raw_thread, - joined: bool + joined: bool, } impl Thread { + #[fixed_stack_segment] #[inline(never)] pub fn start(main: ~fn()) -> Thread { - fn substart(main: &~fn()) -> *raw_thread { - #[fixed_stack_segment]; #[inline(never)]; - - unsafe { rust_raw_thread_start(main) } + // This is the starting point of rust os threads. The first thing we do + // is make sure that we don't trigger __morestack (also why this has a + // no_split_stack annotation), and then we re-build the main function + // and invoke it from there. + #[no_split_stack] + extern "C" fn thread_start(code: *(), env: *()) { + use rt::context; + unsafe { + context::record_stack_bounds(0, uint::max_value); + let f: &fn() = cast::transmute(raw::Closure { + code: code, + env: env, + }); + f(); + } } - let raw = substart(&main); + + let raw_thread = unsafe { + let c: raw::Closure = cast::transmute_copy(&main); + let raw::Closure { code, env } = c; + rust_raw_thread_start(thread_start, code, env) + }; Thread { main: main, - raw_thread: raw, - joined: false + raw_thread: raw_thread, + joined: false, } } @@ -55,7 +75,8 @@ impl Drop for Thread { } extern { - pub fn rust_raw_thread_start(f: &(~fn())) -> *raw_thread; - pub fn rust_raw_thread_join(thread: *raw_thread); - pub fn rust_raw_thread_delete(thread: *raw_thread); + fn rust_raw_thread_start(f: extern "C" fn(*(), *()), + code: *(), env: *()) -> *raw_thread; + fn rust_raw_thread_join(thread: *raw_thread); + fn rust_raw_thread_delete(thread: *raw_thread); } -- cgit 1.4.1-3-g733a5