@@ -32,12 +32,17 @@ use bookeeping;
3232/// Creates a new Task which is ready to execute as a 1:1 task.
3333pub fn new ( ) -> ~Task {
3434 let mut task = ~Task :: new ( ) ;
35- task. put_runtime ( ~Ops {
35+ task. put_runtime ( ops ( ) as ~rt:: Runtime ) ;
36+ return task;
37+ }
38+
39+ fn ops ( ) -> ~Ops {
40+ ~Ops {
3641 lock : unsafe { Mutex :: new ( ) } ,
3742 awoken : false ,
3843 io : io:: IoFactory :: new ( ) ,
39- } as ~rt :: Runtime ) ;
40- return task ;
44+ stack_bounds : None ,
45+ }
4146}
4247
4348/// Spawns a function with the default configuration
@@ -53,7 +58,7 @@ pub fn spawn_opts(opts: TaskOpts, f: proc()) {
5358 notify_chan, name, stack_size
5459 } = opts;
5560
56- let mut task = new ( ) ;
61+ let mut task = ~ Task :: new ( ) ;
5762 task. name = name;
5863 match notify_chan {
5964 Some ( chan) => {
@@ -65,6 +70,7 @@ pub fn spawn_opts(opts: TaskOpts, f: proc()) {
6570
6671 let stack = stack_size. unwrap_or ( env:: min_stack ( ) ) ;
6772 let task = task;
73+ let ops = ops ( ) ;
6874
6975 // Spawning a new OS thread guarantees that __morestack will never get
7076 // 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()) {
7581 Thread :: spawn_stack ( stack, proc ( ) {
7682 let something_around_the_top_of_the_stack = 1 ;
7783 let addr = & something_around_the_top_of_the_stack as * int ;
84+ let my_stack = addr as uint ;
7885 unsafe {
79- let my_stack = addr as uint ;
8086 stack:: record_stack_bounds ( my_stack - stack + 1024 , my_stack) ;
8187 }
88+ let mut ops = ops;
89+ ops. stack_bounds = Some ( ( my_stack - stack + 1024 , my_stack) ) ;
8290
8391 bookeeping:: increment ( ) ;
8492 let mut f = Some ( f) ;
93+ let mut task = task;
94+ task. put_runtime ( ops as ~rt:: Runtime ) ;
8595 task. run ( || { f. take_unwrap ( ) ( ) } ) ;
8696 bookeeping:: decrement ( ) ;
8797 } )
@@ -93,6 +103,11 @@ struct Ops {
93103 lock : Mutex , // native synchronization
94104 awoken : bool , // used to prevent spurious wakeups
95105 io : io:: IoFactory , // local I/O factory
106+
107+ // This field holds the known bounds of the stack in (lo, hi) form. Not all
108+ // native tasks necessarily know their precise bounds, hence this is
109+ // optional.
110+ stack_bounds : Option < ( uint , uint ) > ,
96111}
97112
98113impl rt:: Runtime for Ops {
@@ -114,6 +129,8 @@ impl rt::Runtime for Ops {
114129 self as ~Any
115130 }
116131
132+ fn stack_bounds ( & self ) -> Option < ( uint , uint ) > { self . stack_bounds }
133+
117134 // This function gets a little interesting. There are a few safety and
118135 // ownership violations going on here, but this is all done in the name of
119136 // shared state. Additionally, all of the violations are protected with a
0 commit comments