diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2014-01-04 00:06:13 -0800 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2014-01-04 00:08:03 -0800 |
| commit | dcaf10f8de7be79d7ef8aa5e048bf6535108dc16 (patch) | |
| tree | 2a5a09d84e6db2421076fe36f407f736e989266e /src/libnative/task.rs | |
| parent | a1cb8dc30c6adc88703763a8703b6a3027598b2d (diff) | |
| download | rust-dcaf10f8de7be79d7ef8aa5e048bf6535108dc16.tar.gz rust-dcaf10f8de7be79d7ef8aa5e048bf6535108dc16.zip | |
Add a stack_bounds function to the Runtime trait
This allows inspection of the current task's bounds regardless of what the underlying task is. Closes #11293
Diffstat (limited to 'src/libnative/task.rs')
| -rw-r--r-- | src/libnative/task.rs | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/src/libnative/task.rs b/src/libnative/task.rs index c4d3f651777..661358a64e9 100644 --- a/src/libnative/task.rs +++ b/src/libnative/task.rs @@ -32,12 +32,17 @@ use bookeeping; /// Creates a new Task which is ready to execute as a 1:1 task. pub fn new() -> ~Task { let mut task = ~Task::new(); - task.put_runtime(~Ops { + task.put_runtime(ops() as ~rt::Runtime); + return task; +} + +fn ops() -> ~Ops { + ~Ops { lock: unsafe { Mutex::new() }, awoken: false, io: io::IoFactory::new(), - } as ~rt::Runtime); - return task; + stack_bounds: None, + } } /// Spawns a function with the default configuration @@ -53,7 +58,7 @@ pub fn spawn_opts(opts: TaskOpts, f: proc()) { notify_chan, name, stack_size } = opts; - let mut task = new(); + let mut task = ~Task::new(); task.name = name; match notify_chan { Some(chan) => { @@ -65,6 +70,7 @@ pub fn spawn_opts(opts: TaskOpts, f: proc()) { let stack = stack_size.unwrap_or(env::min_stack()); let task = task; + let ops = ops(); // Spawning a new OS thread guarantees that __morestack will never get // triggered, but we must manually set up the actual stack bounds once this @@ -75,13 +81,17 @@ pub fn spawn_opts(opts: TaskOpts, f: proc()) { Thread::spawn_stack(stack, proc() { let something_around_the_top_of_the_stack = 1; let addr = &something_around_the_top_of_the_stack as *int; + let my_stack = addr as uint; unsafe { - let my_stack = addr as uint; stack::record_stack_bounds(my_stack - stack + 1024, my_stack); } + let mut ops = ops; + ops.stack_bounds = Some((my_stack - stack + 1024, my_stack)); bookeeping::increment(); let mut f = Some(f); + let mut task = task; + task.put_runtime(ops as ~rt::Runtime); task.run(|| { f.take_unwrap()() }); bookeeping::decrement(); }) @@ -93,6 +103,11 @@ struct Ops { lock: Mutex, // native synchronization awoken: bool, // used to prevent spurious wakeups io: io::IoFactory, // local I/O factory + + // 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)>, } impl rt::Runtime for Ops { @@ -114,6 +129,8 @@ impl rt::Runtime for Ops { self as ~Any } + fn stack_bounds(&self) -> Option<(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 // shared state. Additionally, all of the violations are protected with a |
