]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #11360 : huonw/rust/stack_bounds, r=alexcrichton
authorbors <bors@rust-lang.org>
Fri, 10 Jan 2014 04:21:17 +0000 (20:21 -0800)
committerbors <bors@rust-lang.org>
Fri, 10 Jan 2014 04:21:17 +0000 (20:21 -0800)
We just approximate with a 2MB stack for native::start.

src/libgreen/simple.rs
src/libgreen/task.rs
src/libnative/lib.rs
src/libnative/task.rs
src/libstd/rt/mod.rs
src/libstd/rt/task.rs

index ddacc11fd9eddc64ccdb692b2a2dbe962c76ae5a..4a0523fe47a7a72233f3f14d685bd5b1c43c61b4 100644 (file)
@@ -75,7 +75,7 @@ fn spawn_sibling(~self, _cur_task: ~Task, _opts: TaskOpts, _f: proc()) {
         fail!()
     }
     fn local_io<'a>(&'a mut self) -> Option<rtio::LocalIo<'a>> { None }
-    fn stack_bounds(&self) -> Option<(uint, uint)> { None }
+    fn stack_bounds(&self) -> (uint, uint) { fail!() }
     fn wrap(~self) -> ~Any { fail!() }
 }
 
index 62c9ad12535fc998797d5626e4db8c1feba88c46..31752941231cb9328e57a77becc1a6fe3b0e655e 100644 (file)
@@ -454,11 +454,12 @@ fn local_io<'a>(&'a mut self) -> Option<rtio::LocalIo<'a>> {
         }
     }
 
-    fn stack_bounds(&self) -> Option<(uint, uint)> {
-        self.coroutine.as_ref().map(|c| {
-            (c.current_stack_segment.start() as uint,
-             c.current_stack_segment.end() as uint)
-        })
+    fn stack_bounds(&self) -> (uint, uint) {
+        let c = self.coroutine.as_ref()
+            .expect("GreenTask.stack_bounds called without a coroutine");
+
+        (c.current_stack_segment.start() as uint,
+         c.current_stack_segment.end() as uint)
     }
 
     fn wrap(~self) -> ~Any { self as ~Any }
index 80eb8c00cfdf788361967dc726d651da5886f4a1..5acd34955caee30d13af64721481b9abc0084a76 100644 (file)
 pub mod io;
 pub mod task;
 
+#[cfg(windows)]
+#[cfg(android)]
+static OS_DEFAULT_STACK_ESTIMATE: uint = 1 << 20;
+#[cfg(unix, not(android))]
+static OS_DEFAULT_STACK_ESTIMATE: uint = 2 * (1 << 20);
+
+
 // XXX: this should not exist here
 #[cfg(stage0, nativestart)]
 #[lang = "start"]
@@ -66,10 +73,19 @@ pub fn lang_start(main: *u8, argc: int, argv: **u8) -> int {
 /// This function will only return once *all* native threads in the system have
 /// exited.
 pub fn start(argc: int, argv: **u8, main: proc()) -> int {
+    let something_around_the_top_of_the_stack = 1;
+    let addr = &something_around_the_top_of_the_stack as *int;
+    let my_stack_top = addr as uint;
+
+    // FIXME #11359 we just assume that this thread has a stack of a
+    // certain size, and estimate that there's at most 20KB of stack
+    // frames above our current position.
+    let my_stack_bottom = my_stack_top + 20000 - OS_DEFAULT_STACK_ESTIMATE;
+
     rt::init(argc, argv);
     let mut exit_code = None;
     let mut main = Some(main);
-    task::new().run(|| {
+    task::new((my_stack_bottom, my_stack_top)).run(|| {
         exit_code = Some(run(main.take_unwrap()));
     });
     unsafe { rt::cleanup(); }
index 9b6a26291a1c3b7ddf2686b7420f1323b56b182c..e827b495852a45d0db153b92160cb275f5656289 100644 (file)
 use bookeeping;
 
 /// Creates a new Task which is ready to execute as a 1:1 task.
-pub fn new() -> ~Task {
+pub fn new(stack_bounds: (uint, uint)) -> ~Task {
     let mut task = ~Task::new();
-    task.put_runtime(ops() as ~rt::Runtime);
+    let mut ops = ops();
+    ops.stack_bounds = stack_bounds;
+    task.put_runtime(ops as ~rt::Runtime);
     return task;
 }
 
@@ -41,7 +43,8 @@ fn ops() -> ~Ops {
         lock: unsafe { Mutex::new() },
         awoken: false,
         io: io::IoFactory::new(),
-        stack_bounds: None,
+        // these *should* get overwritten
+        stack_bounds: (0, 0),
     }
 }
 
@@ -95,7 +98,7 @@ pub fn spawn_opts(opts: TaskOpts, f: proc()) {
             stack::record_stack_bounds(my_stack - stack + 1024, my_stack);
         }
         let mut ops = ops;
-        ops.stack_bounds = Some((my_stack - stack + 1024, my_stack));
+        ops.stack_bounds = (my_stack - stack + 1024, my_stack);
 
         let mut f = Some(f);
         let mut task = task;
@@ -115,7 +118,7 @@ struct Ops {
     // This field holds the known bounds of the stack in (lo, hi) form. Not all
     // native tasks necessarily know their precise bounds, hence this is
     // optional.
-    stack_bounds: Option<(uint, uint)>,
+    stack_bounds: (uint, uint),
 }
 
 impl rt::Runtime for Ops {
@@ -137,7 +140,7 @@ fn wrap(~self) -> ~Any {
         self as ~Any
     }
 
-    fn stack_bounds(&self) -> Option<(uint, uint)> { self.stack_bounds }
+    fn stack_bounds(&self) -> (uint, uint) { self.stack_bounds }
 
     // This function gets a little interesting. There are a few safety and
     // ownership violations going on here, but this is all done in the name of
index d839ef62af962528d1ae532160a0f43a10fbfc70..e7adb5ad7ddafff8c0b3f7ca878f81c3aeda5447 100644 (file)
@@ -154,7 +154,8 @@ fn deschedule(~self, times: uint, cur_task: ~Task,
     // you're in.
     fn spawn_sibling(~self, cur_task: ~Task, opts: TaskOpts, f: proc());
     fn local_io<'a>(&'a mut self) -> Option<rtio::LocalIo<'a>>;
-    fn stack_bounds(&self) -> Option<(uint, uint)>; // (lo, hi)
+    /// The (low, high) edges of the current stack.
+    fn stack_bounds(&self) -> (uint, uint); // (lo, hi)
 
     // XXX: This is a serious code smell and this should not exist at all.
     fn wrap(~self) -> ~Any;
index 6c94f23778931d358593752f85b6df7e13815f59..b4ead4252ca4158a461da8d94dea3b36a10f82bc 100644 (file)
@@ -289,7 +289,7 @@ pub fn local_io<'a>(&'a mut self) -> Option<LocalIo<'a>> {
     /// Returns the stack bounds for this task in (lo, hi) format. The stack
     /// bounds may not be known for all tasks, so the return value may be
     /// `None`.
-    pub fn stack_bounds(&self) -> Option<(uint, uint)> {
+    pub fn stack_bounds(&self) -> (uint, uint) {
         self.imp.get_ref().stack_bounds()
     }
 }