Skip to content

Commit f78293c

Browse files
committed
auto merge of #11360 : huonw/rust/stack_bounds, r=alexcrichton
We just approximate with a 2MB stack for native::start.
2 parents 28ddc65 + 65ce505 commit f78293c

File tree

6 files changed

+36
-15
lines changed

6 files changed

+36
-15
lines changed

src/libgreen/simple.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ impl Runtime for SimpleTask {
7575
fail!()
7676
}
7777
fn local_io<'a>(&'a mut self) -> Option<rtio::LocalIo<'a>> { None }
78-
fn stack_bounds(&self) -> Option<(uint, uint)> { None }
78+
fn stack_bounds(&self) -> (uint, uint) { fail!() }
7979
fn wrap(~self) -> ~Any { fail!() }
8080
}
8181

src/libgreen/task.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -454,11 +454,12 @@ impl Runtime for GreenTask {
454454
}
455455
}
456456

457-
fn stack_bounds(&self) -> Option<(uint, uint)> {
458-
self.coroutine.as_ref().map(|c| {
459-
(c.current_stack_segment.start() as uint,
460-
c.current_stack_segment.end() as uint)
461-
})
457+
fn stack_bounds(&self) -> (uint, uint) {
458+
let c = self.coroutine.as_ref()
459+
.expect("GreenTask.stack_bounds called without a coroutine");
460+
461+
(c.current_stack_segment.start() as uint,
462+
c.current_stack_segment.end() as uint)
462463
}
463464

464465
fn wrap(~self) -> ~Any { self as ~Any }

src/libnative/lib.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ mod bookeeping;
3333
pub mod io;
3434
pub mod task;
3535

36+
#[cfg(windows)]
37+
#[cfg(android)]
38+
static OS_DEFAULT_STACK_ESTIMATE: uint = 1 << 20;
39+
#[cfg(unix, not(android))]
40+
static OS_DEFAULT_STACK_ESTIMATE: uint = 2 * (1 << 20);
41+
42+
3643
// XXX: this should not exist here
3744
#[cfg(stage0, nativestart)]
3845
#[lang = "start"]
@@ -66,10 +73,19 @@ pub fn lang_start(main: *u8, argc: int, argv: **u8) -> int {
6673
/// This function will only return once *all* native threads in the system have
6774
/// exited.
6875
pub fn start(argc: int, argv: **u8, main: proc()) -> int {
76+
let something_around_the_top_of_the_stack = 1;
77+
let addr = &something_around_the_top_of_the_stack as *int;
78+
let my_stack_top = addr as uint;
79+
80+
// FIXME #11359 we just assume that this thread has a stack of a
81+
// certain size, and estimate that there's at most 20KB of stack
82+
// frames above our current position.
83+
let my_stack_bottom = my_stack_top + 20000 - OS_DEFAULT_STACK_ESTIMATE;
84+
6985
rt::init(argc, argv);
7086
let mut exit_code = None;
7187
let mut main = Some(main);
72-
task::new().run(|| {
88+
task::new((my_stack_bottom, my_stack_top)).run(|| {
7389
exit_code = Some(run(main.take_unwrap()));
7490
});
7591
unsafe { rt::cleanup(); }

src/libnative/task.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@ use task;
3030
use bookeeping;
3131

3232
/// Creates a new Task which is ready to execute as a 1:1 task.
33-
pub fn new() -> ~Task {
33+
pub fn new(stack_bounds: (uint, uint)) -> ~Task {
3434
let mut task = ~Task::new();
35-
task.put_runtime(ops() as ~rt::Runtime);
35+
let mut ops = ops();
36+
ops.stack_bounds = stack_bounds;
37+
task.put_runtime(ops as ~rt::Runtime);
3638
return task;
3739
}
3840

@@ -41,7 +43,8 @@ fn ops() -> ~Ops {
4143
lock: unsafe { Mutex::new() },
4244
awoken: false,
4345
io: io::IoFactory::new(),
44-
stack_bounds: None,
46+
// these *should* get overwritten
47+
stack_bounds: (0, 0),
4548
}
4649
}
4750

@@ -95,7 +98,7 @@ pub fn spawn_opts(opts: TaskOpts, f: proc()) {
9598
stack::record_stack_bounds(my_stack - stack + 1024, my_stack);
9699
}
97100
let mut ops = ops;
98-
ops.stack_bounds = Some((my_stack - stack + 1024, my_stack));
101+
ops.stack_bounds = (my_stack - stack + 1024, my_stack);
99102

100103
let mut f = Some(f);
101104
let mut task = task;
@@ -115,7 +118,7 @@ struct Ops {
115118
// This field holds the known bounds of the stack in (lo, hi) form. Not all
116119
// native tasks necessarily know their precise bounds, hence this is
117120
// optional.
118-
stack_bounds: Option<(uint, uint)>,
121+
stack_bounds: (uint, uint),
119122
}
120123

121124
impl rt::Runtime for Ops {
@@ -137,7 +140,7 @@ impl rt::Runtime for Ops {
137140
self as ~Any
138141
}
139142

140-
fn stack_bounds(&self) -> Option<(uint, uint)> { self.stack_bounds }
143+
fn stack_bounds(&self) -> (uint, uint) { self.stack_bounds }
141144

142145
// This function gets a little interesting. There are a few safety and
143146
// ownership violations going on here, but this is all done in the name of

src/libstd/rt/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,8 @@ pub trait Runtime {
154154
// you're in.
155155
fn spawn_sibling(~self, cur_task: ~Task, opts: TaskOpts, f: proc());
156156
fn local_io<'a>(&'a mut self) -> Option<rtio::LocalIo<'a>>;
157-
fn stack_bounds(&self) -> Option<(uint, uint)>; // (lo, hi)
157+
/// The (low, high) edges of the current stack.
158+
fn stack_bounds(&self) -> (uint, uint); // (lo, hi)
158159

159160
// XXX: This is a serious code smell and this should not exist at all.
160161
fn wrap(~self) -> ~Any;

src/libstd/rt/task.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ impl Task {
289289
/// Returns the stack bounds for this task in (lo, hi) format. The stack
290290
/// bounds may not be known for all tasks, so the return value may be
291291
/// `None`.
292-
pub fn stack_bounds(&self) -> Option<(uint, uint)> {
292+
pub fn stack_bounds(&self) -> (uint, uint) {
293293
self.imp.get_ref().stack_bounds()
294294
}
295295
}

0 commit comments

Comments
 (0)