Skip to content

Commit ae1ed4f

Browse files
committed
std: Allow spawners to specify stack size
1 parent f82da81 commit ae1ed4f

File tree

7 files changed

+61
-49
lines changed

7 files changed

+61
-49
lines changed

src/libstd/rt/local.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ impl Local for IoFactoryObject {
126126

127127
#[cfg(test)]
128128
mod test {
129+
use option::None;
129130
use unstable::run_in_bare_thread;
130131
use rt::test::*;
131132
use super::*;
@@ -137,7 +138,7 @@ mod test {
137138
do run_in_bare_thread {
138139
local_ptr::init_tls_key();
139140
let mut sched = ~new_test_uv_sched();
140-
let task = ~Task::new_root(&mut sched.stack_pool, || {});
141+
let task = ~Task::new_root(&mut sched.stack_pool, None, || {});
141142
Local::put(task);
142143
let task: ~Task = Local::take();
143144
cleanup_task(task);
@@ -149,11 +150,11 @@ mod test {
149150
do run_in_bare_thread {
150151
local_ptr::init_tls_key();
151152
let mut sched = ~new_test_uv_sched();
152-
let task = ~Task::new_root(&mut sched.stack_pool, || {});
153+
let task = ~Task::new_root(&mut sched.stack_pool, None, || {});
153154
Local::put(task);
154155
let task: ~Task = Local::take();
155156
cleanup_task(task);
156-
let task = ~Task::new_root(&mut sched.stack_pool, || {});
157+
let task = ~Task::new_root(&mut sched.stack_pool, None, || {});
157158
Local::put(task);
158159
let task: ~Task = Local::take();
159160
cleanup_task(task);
@@ -166,7 +167,7 @@ mod test {
166167
do run_in_bare_thread {
167168
local_ptr::init_tls_key();
168169
let mut sched = ~new_test_uv_sched();
169-
let task = ~Task::new_root(&mut sched.stack_pool, || {});
170+
let task = ~Task::new_root(&mut sched.stack_pool, None, || {});
170171
Local::put(task);
171172

172173
unsafe {
@@ -182,7 +183,7 @@ mod test {
182183
do run_in_bare_thread {
183184
local_ptr::init_tls_key();
184185
let mut sched = ~new_test_uv_sched();
185-
let task = ~Task::new_root(&mut sched.stack_pool, || {});
186+
let task = ~Task::new_root(&mut sched.stack_pool, None, || {});
186187
Local::put(task);
187188

188189
let res = do Local::borrow::<Task,bool> |_task| {

src/libstd/rt/mod.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -331,8 +331,7 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
331331
// In the case where we do not use a main_thread scheduler we
332332
// run the main task in one of our threads.
333333

334-
let mut main_task = ~Task::new_root(&mut scheds[0].stack_pool,
335-
main.take());
334+
let mut main_task = ~Task::new_root(&mut scheds[0].stack_pool, None, main.take());
336335
main_task.death.on_exit = Some(on_exit.take());
337336
let main_task_cell = Cell::new(main_task);
338337

@@ -352,7 +351,7 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
352351
let sched_cell = Cell::new(sched);
353352
let thread = do Thread::start {
354353
let mut sched = sched_cell.take();
355-
let bootstrap_task = ~do Task::new_root(&mut sched.stack_pool) || {
354+
let bootstrap_task = ~do Task::new_root(&mut sched.stack_pool, None) || {
356355
rtdebug!("boostraping a non-primary scheduler");
357356
};
358357
sched.bootstrap(bootstrap_task);
@@ -369,7 +368,7 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
369368
let mut main_sched = main_sched.unwrap();
370369

371370
let home = Sched(main_sched.make_handle());
372-
let mut main_task = ~Task::new_root_homed(&mut main_sched.stack_pool,
371+
let mut main_task = ~Task::new_root_homed(&mut main_sched.stack_pool, None,
373372
home, main.take());
374373
main_task.death.on_exit = Some(on_exit.take());
375374
rtdebug!("boostrapping main_task");

src/libstd/rt/sched.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -833,7 +833,7 @@ mod test {
833833
let mut sched = ~new_test_uv_sched();
834834
let sched_handle = sched.make_handle();
835835

836-
let mut task = ~do Task::new_root_homed(&mut sched.stack_pool,
836+
let mut task = ~do Task::new_root_homed(&mut sched.stack_pool, None,
837837
Sched(sched_handle)) {
838838
unsafe { *task_ran_ptr = true };
839839
assert!(Task::on_appropriate_sched());
@@ -893,21 +893,21 @@ mod test {
893893
// 3) task not homed, sched requeues
894894
// 4) task not home, send home
895895

896-
let task1 = ~do Task::new_root_homed(&mut special_sched.stack_pool,
896+
let task1 = ~do Task::new_root_homed(&mut special_sched.stack_pool, None,
897897
Sched(t1_handle)) || {
898898
rtassert!(Task::on_appropriate_sched());
899899
};
900900
rtdebug!("task1 id: **%u**", borrow::to_uint(task1));
901901

902-
let task2 = ~do Task::new_root(&mut normal_sched.stack_pool) {
902+
let task2 = ~do Task::new_root(&mut normal_sched.stack_pool, None) {
903903
rtassert!(Task::on_appropriate_sched());
904904
};
905905

906-
let task3 = ~do Task::new_root(&mut normal_sched.stack_pool) {
906+
let task3 = ~do Task::new_root(&mut normal_sched.stack_pool, None) {
907907
rtassert!(Task::on_appropriate_sched());
908908
};
909909

910-
let task4 = ~do Task::new_root_homed(&mut special_sched.stack_pool,
910+
let task4 = ~do Task::new_root_homed(&mut special_sched.stack_pool, None,
911911
Sched(t4_handle)) {
912912
rtassert!(Task::on_appropriate_sched());
913913
};
@@ -923,7 +923,7 @@ mod test {
923923
let port = Cell::new(port);
924924
let chan = Cell::new(chan);
925925

926-
let normal_task = ~do Task::new_root(&mut normal_sched.stack_pool) {
926+
let normal_task = ~do Task::new_root(&mut normal_sched.stack_pool, None) {
927927
rtdebug!("*about to submit task2*");
928928
Scheduler::run_task(task2.take());
929929
rtdebug!("*about to submit task4*");
@@ -938,7 +938,7 @@ mod test {
938938

939939
rtdebug!("normal task: %u", borrow::to_uint(normal_task));
940940

941-
let special_task = ~do Task::new_root(&mut special_sched.stack_pool) {
941+
let special_task = ~do Task::new_root(&mut special_sched.stack_pool, None) {
942942
rtdebug!("*about to submit task1*");
943943
Scheduler::run_task(task1.take());
944944
rtdebug!("*about to submit task3*");

src/libstd/rt/task.rs

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -86,38 +86,40 @@ impl Task {
8686

8787
// A helper to build a new task using the dynamically found
8888
// scheduler and task. Only works in GreenTask context.
89-
pub fn build_homed_child(f: ~fn(), home: SchedHome) -> ~Task {
89+
pub fn build_homed_child(stack_size: Option<uint>, f: ~fn(), home: SchedHome) -> ~Task {
9090
let f = Cell::new(f);
9191
let home = Cell::new(home);
9292
do Local::borrow::<Task, ~Task> |running_task| {
9393
let mut sched = running_task.sched.take_unwrap();
9494
let new_task = ~running_task.new_child_homed(&mut sched.stack_pool,
95+
stack_size,
9596
home.take(),
9697
f.take());
9798
running_task.sched = Some(sched);
9899
new_task
99100
}
100101
}
101102

102-
pub fn build_child(f: ~fn()) -> ~Task {
103-
Task::build_homed_child(f, AnySched)
103+
pub fn build_child(stack_size: Option<uint>, f: ~fn()) -> ~Task {
104+
Task::build_homed_child(stack_size, f, AnySched)
104105
}
105106

106-
pub fn build_homed_root(f: ~fn(), home: SchedHome) -> ~Task {
107+
pub fn build_homed_root(stack_size: Option<uint>, f: ~fn(), home: SchedHome) -> ~Task {
107108
let f = Cell::new(f);
108109
let home = Cell::new(home);
109110
do Local::borrow::<Task, ~Task> |running_task| {
110111
let mut sched = running_task.sched.take_unwrap();
111112
let new_task = ~Task::new_root_homed(&mut sched.stack_pool,
112-
home.take(),
113-
f.take());
113+
stack_size,
114+
home.take(),
115+
f.take());
114116
running_task.sched = Some(sched);
115117
new_task
116118
}
117119
}
118120

119-
pub fn build_root(f: ~fn()) -> ~Task {
120-
Task::build_homed_root(f, AnySched)
121+
pub fn build_root(stack_size: Option<uint>, f: ~fn()) -> ~Task {
122+
Task::build_homed_root(stack_size, f, AnySched)
121123
}
122124

123125
pub fn new_sched_task() -> Task {
@@ -138,17 +140,20 @@ impl Task {
138140
}
139141

140142
pub fn new_root(stack_pool: &mut StackPool,
143+
stack_size: Option<uint>,
141144
start: ~fn()) -> Task {
142-
Task::new_root_homed(stack_pool, AnySched, start)
145+
Task::new_root_homed(stack_pool, stack_size, AnySched, start)
143146
}
144147

145148
pub fn new_child(&mut self,
146149
stack_pool: &mut StackPool,
150+
stack_size: Option<uint>,
147151
start: ~fn()) -> Task {
148-
self.new_child_homed(stack_pool, AnySched, start)
152+
self.new_child_homed(stack_pool, stack_size, AnySched, start)
149153
}
150154

151155
pub fn new_root_homed(stack_pool: &mut StackPool,
156+
stack_size: Option<uint>,
152157
home: SchedHome,
153158
start: ~fn()) -> Task {
154159
Task {
@@ -161,14 +166,15 @@ impl Task {
161166
death: Death::new(),
162167
destroyed: false,
163168
name: None,
164-
coroutine: Some(Coroutine::new(stack_pool, start)),
169+
coroutine: Some(Coroutine::new(stack_pool, stack_size, start)),
165170
sched: None,
166171
task_type: GreenTask(Some(~home))
167172
}
168173
}
169174

170175
pub fn new_child_homed(&mut self,
171176
stack_pool: &mut StackPool,
177+
stack_size: Option<uint>,
172178
home: SchedHome,
173179
start: ~fn()) -> Task {
174180
Task {
@@ -182,7 +188,7 @@ impl Task {
182188
death: self.death.new_child(),
183189
destroyed: false,
184190
name: None,
185-
coroutine: Some(Coroutine::new(stack_pool, start)),
191+
coroutine: Some(Coroutine::new(stack_pool, stack_size, start)),
186192
sched: None,
187193
task_type: GreenTask(Some(~home))
188194
}
@@ -326,8 +332,11 @@ impl Drop for Task {
326332

327333
impl Coroutine {
328334

329-
pub fn new(stack_pool: &mut StackPool, start: ~fn()) -> Coroutine {
330-
let stack_size = env::min_stack();
335+
pub fn new(stack_pool: &mut StackPool, stack_size: Option<uint>, start: ~fn()) -> Coroutine {
336+
let stack_size = match stack_size {
337+
Some(size) => size,
338+
None => env::min_stack()
339+
};
331340
let start = Coroutine::build_start_wrapper(start);
332341
let mut stack = stack_pool.take_segment(stack_size);
333342
let initial_context = Context::new(start, &mut stack);

src/libstd/rt/test.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ pub fn run_in_newsched_task_core(f: ~fn()) {
5757
exit_handle.take().send(Shutdown);
5858
rtassert!(exit_status);
5959
};
60-
let mut task = ~Task::new_root(&mut sched.stack_pool, f);
60+
let mut task = ~Task::new_root(&mut sched.stack_pool, None, f);
6161
task.death.on_exit = Some(on_exit);
6262

6363
sched.bootstrap(task);
@@ -190,8 +190,7 @@ pub fn run_in_mt_newsched_task(f: ~fn()) {
190190

191191
rtassert!(exit_status);
192192
};
193-
let mut main_task = ~Task::new_root(&mut scheds[0].stack_pool,
194-
f.take());
193+
let mut main_task = ~Task::new_root(&mut scheds[0].stack_pool, None, f.take());
195194
main_task.death.on_exit = Some(on_exit);
196195

197196
let mut threads = ~[];
@@ -209,7 +208,7 @@ pub fn run_in_mt_newsched_task(f: ~fn()) {
209208

210209
while !scheds.is_empty() {
211210
let mut sched = scheds.pop();
212-
let bootstrap_task = ~do Task::new_root(&mut sched.stack_pool) || {
211+
let bootstrap_task = ~do Task::new_root(&mut sched.stack_pool, None) || {
213212
rtdebug!("bootstrapping non-primary scheduler");
214213
};
215214
let bootstrap_task_cell = Cell::new(bootstrap_task);
@@ -232,12 +231,12 @@ pub fn run_in_mt_newsched_task(f: ~fn()) {
232231

233232
/// Test tasks will abort on failure instead of unwinding
234233
pub fn spawntask(f: ~fn()) {
235-
Scheduler::run_task(Task::build_child(f));
234+
Scheduler::run_task(Task::build_child(None, f));
236235
}
237236

238237
/// Create a new task and run it right now. Aborts on failure
239238
pub fn spawntask_later(f: ~fn()) {
240-
Scheduler::run_task_later(Task::build_child(f));
239+
Scheduler::run_task_later(Task::build_child(None, f));
241240
}
242241

243242
pub fn spawntask_random(f: ~fn()) {
@@ -259,7 +258,7 @@ pub fn spawntask_try(f: ~fn()) -> Result<(),()> {
259258
let chan = Cell::new(chan);
260259
let on_exit: ~fn(bool) = |exit_status| chan.take().send(exit_status);
261260

262-
let mut new_task = Task::build_root(f);
261+
let mut new_task = Task::build_root(None, f);
263262
new_task.death.on_exit = Some(on_exit);
264263

265264
Scheduler::run_task(new_task);
@@ -285,7 +284,7 @@ pub fn spawntask_thread(f: ~fn()) -> Thread {
285284
pub fn with_test_task(blk: ~fn(~Task) -> ~Task) {
286285
do run_in_bare_thread {
287286
let mut sched = ~new_test_uv_sched();
288-
let task = blk(~Task::new_root(&mut sched.stack_pool, ||{}));
287+
let task = blk(~Task::new_root(&mut sched.stack_pool, None, ||{}));
289288
cleanup_task(task);
290289
}
291290
}

src/libstd/task/mod.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ pub struct TaskOpts {
142142
indestructible: bool,
143143
notify_chan: Option<Chan<TaskResult>>,
144144
name: Option<~str>,
145-
sched: SchedOpts
145+
sched: SchedOpts,
146+
stack_size: Option<uint>
146147
}
147148

148149
/**
@@ -197,7 +198,8 @@ impl TaskBuilder {
197198
indestructible: self.opts.indestructible,
198199
notify_chan: notify_chan,
199200
name: name,
200-
sched: self.opts.sched
201+
sched: self.opts.sched,
202+
stack_size: self.opts.stack_size
201203
},
202204
gen_body: gen_body,
203205
can_not_copy: None,
@@ -351,7 +353,8 @@ impl TaskBuilder {
351353
indestructible: x.opts.indestructible,
352354
notify_chan: notify_chan,
353355
name: name,
354-
sched: x.opts.sched
356+
sched: x.opts.sched,
357+
stack_size: x.opts.stack_size
355358
};
356359
let f = match gen_body {
357360
Some(gen) => {
@@ -422,7 +425,8 @@ pub fn default_task_opts() -> TaskOpts {
422425
name: None,
423426
sched: SchedOpts {
424427
mode: DefaultScheduler,
425-
}
428+
},
429+
stack_size: None
426430
}
427431
}
428432

src/libstd/task/spawn.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -713,9 +713,9 @@ fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) {
713713
let mut task = unsafe {
714714
if opts.sched.mode != SingleThreaded {
715715
if opts.watched {
716-
Task::build_child(child_wrapper)
716+
Task::build_child(opts.stack_size, child_wrapper)
717717
} else {
718-
Task::build_root(child_wrapper)
718+
Task::build_root(opts.stack_size, child_wrapper)
719719
}
720720
} else {
721721
// Creating a 1:1 task:thread ...
@@ -736,16 +736,16 @@ fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) {
736736

737737
// Pin the new task to the new scheduler
738738
let new_task = if opts.watched {
739-
Task::build_homed_child(child_wrapper, Sched(new_sched_handle))
739+
Task::build_homed_child(opts.stack_size, child_wrapper, Sched(new_sched_handle))
740740
} else {
741-
Task::build_homed_root(child_wrapper, Sched(new_sched_handle))
741+
Task::build_homed_root(opts.stack_size, child_wrapper, Sched(new_sched_handle))
742742
};
743743

744744
// Create a task that will later be used to join with the new scheduler
745745
// thread when it is ready to terminate
746746
let (thread_port, thread_chan) = oneshot();
747747
let thread_port_cell = Cell::new(thread_port);
748-
let join_task = do Task::build_child() {
748+
let join_task = do Task::build_child(None) {
749749
rtdebug!("running join task");
750750
let thread_port = thread_port_cell.take();
751751
let thread: Thread = thread_port.recv();
@@ -762,8 +762,8 @@ fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) {
762762
let mut orig_sched_handle = orig_sched_handle_cell.take();
763763
let join_task = join_task_cell.take();
764764

765-
let bootstrap_task = ~do Task::new_root(&mut new_sched.stack_pool) || {
766-
rtdebug!("bootstrapping a 1:1 scheduler");
765+
let bootstrap_task = ~do Task::new_root(&mut new_sched.stack_pool, None) || {
766+
rtdebug!("boostrapping a 1:1 scheduler");
767767
};
768768
new_sched.bootstrap(bootstrap_task);
769769

0 commit comments

Comments
 (0)