@@ -32,12 +32,17 @@ use bookeeping;
32
32
/// Creates a new Task which is ready to execute as a 1:1 task.
33
33
pub fn new ( ) -> ~Task {
34
34
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 {
36
41
lock : unsafe { Mutex :: new ( ) } ,
37
42
awoken : false ,
38
43
io : io:: IoFactory :: new ( ) ,
39
- } as ~rt :: Runtime ) ;
40
- return task ;
44
+ stack_bounds : None ,
45
+ }
41
46
}
42
47
43
48
/// Spawns a function with the default configuration
@@ -53,7 +58,7 @@ pub fn spawn_opts(opts: TaskOpts, f: proc()) {
53
58
notify_chan, name, stack_size
54
59
} = opts;
55
60
56
- let mut task = new ( ) ;
61
+ let mut task = ~ Task :: new ( ) ;
57
62
task. name = name;
58
63
match notify_chan {
59
64
Some ( chan) => {
@@ -65,6 +70,7 @@ pub fn spawn_opts(opts: TaskOpts, f: proc()) {
65
70
66
71
let stack = stack_size. unwrap_or ( env:: min_stack ( ) ) ;
67
72
let task = task;
73
+ let ops = ops ( ) ;
68
74
69
75
// Spawning a new OS thread guarantees that __morestack will never get
70
76
// 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()) {
75
81
Thread :: spawn_stack ( stack, proc ( ) {
76
82
let something_around_the_top_of_the_stack = 1 ;
77
83
let addr = & something_around_the_top_of_the_stack as * int ;
84
+ let my_stack = addr as uint ;
78
85
unsafe {
79
- let my_stack = addr as uint ;
80
86
stack:: record_stack_bounds ( my_stack - stack + 1024 , my_stack) ;
81
87
}
88
+ let mut ops = ops;
89
+ ops. stack_bounds = Some ( ( my_stack - stack + 1024 , my_stack) ) ;
82
90
83
91
bookeeping:: increment ( ) ;
84
92
let mut f = Some ( f) ;
93
+ let mut task = task;
94
+ task. put_runtime ( ops as ~rt:: Runtime ) ;
85
95
task. run ( || { f. take_unwrap ( ) ( ) } ) ;
86
96
bookeeping:: decrement ( ) ;
87
97
} )
@@ -93,6 +103,11 @@ struct Ops {
93
103
lock : Mutex , // native synchronization
94
104
awoken : bool , // used to prevent spurious wakeups
95
105
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 ) > ,
96
111
}
97
112
98
113
impl rt:: Runtime for Ops {
@@ -114,6 +129,8 @@ impl rt::Runtime for Ops {
114
129
self as ~Any
115
130
}
116
131
132
+ fn stack_bounds ( & self ) -> Option < ( uint , uint ) > { self . stack_bounds }
133
+
117
134
// This function gets a little interesting. There are a few safety and
118
135
// ownership violations going on here, but this is all done in the name of
119
136
// shared state. Additionally, all of the violations are protected with a
0 commit comments