mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
auto merge of #11306 : alexcrichton/rust/native-bounds, r=pcwalton
This allows inspection of the current task's bounds regardless of what the underlying task is. Closes #11293
This commit is contained in:
commit
b432e82515
@ -75,6 +75,7 @@ impl Runtime for SimpleTask {
|
||||
fail!()
|
||||
}
|
||||
fn local_io<'a>(&'a mut self) -> Option<rtio::LocalIo<'a>> { None }
|
||||
fn stack_bounds(&self) -> Option<(uint, uint)> { None }
|
||||
fn wrap(~self) -> ~Any { fail!() }
|
||||
}
|
||||
|
||||
|
@ -450,6 +450,13 @@ impl Runtime for GreenTask {
|
||||
}
|
||||
}
|
||||
|
||||
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 wrap(~self) -> ~Any { self as ~Any }
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -159,6 +159,7 @@ pub trait Runtime {
|
||||
// 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)
|
||||
|
||||
// XXX: This is a serious code smell and this should not exist at all.
|
||||
fn wrap(~self) -> ~Any;
|
||||
|
@ -277,6 +277,13 @@ impl Task {
|
||||
pub fn local_io<'a>(&'a mut self) -> Option<LocalIo<'a>> {
|
||||
self.imp.get_mut_ref().local_io()
|
||||
}
|
||||
|
||||
/// 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)> {
|
||||
self.imp.get_ref().stack_bounds()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Task {
|
||||
|
Loading…
Reference in New Issue
Block a user