std: Allow spawners to specify stack size
This commit is contained in:
parent
f82da818a7
commit
ae1ed4fd78
7 changed files with 61 additions and 49 deletions
|
@ -126,6 +126,7 @@ impl Local for IoFactoryObject {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use option::None;
|
||||
use unstable::run_in_bare_thread;
|
||||
use rt::test::*;
|
||||
use super::*;
|
||||
|
@ -137,7 +138,7 @@ mod test {
|
|||
do run_in_bare_thread {
|
||||
local_ptr::init_tls_key();
|
||||
let mut sched = ~new_test_uv_sched();
|
||||
let task = ~Task::new_root(&mut sched.stack_pool, || {});
|
||||
let task = ~Task::new_root(&mut sched.stack_pool, None, || {});
|
||||
Local::put(task);
|
||||
let task: ~Task = Local::take();
|
||||
cleanup_task(task);
|
||||
|
@ -149,11 +150,11 @@ mod test {
|
|||
do run_in_bare_thread {
|
||||
local_ptr::init_tls_key();
|
||||
let mut sched = ~new_test_uv_sched();
|
||||
let task = ~Task::new_root(&mut sched.stack_pool, || {});
|
||||
let task = ~Task::new_root(&mut sched.stack_pool, None, || {});
|
||||
Local::put(task);
|
||||
let task: ~Task = Local::take();
|
||||
cleanup_task(task);
|
||||
let task = ~Task::new_root(&mut sched.stack_pool, || {});
|
||||
let task = ~Task::new_root(&mut sched.stack_pool, None, || {});
|
||||
Local::put(task);
|
||||
let task: ~Task = Local::take();
|
||||
cleanup_task(task);
|
||||
|
@ -166,7 +167,7 @@ mod test {
|
|||
do run_in_bare_thread {
|
||||
local_ptr::init_tls_key();
|
||||
let mut sched = ~new_test_uv_sched();
|
||||
let task = ~Task::new_root(&mut sched.stack_pool, || {});
|
||||
let task = ~Task::new_root(&mut sched.stack_pool, None, || {});
|
||||
Local::put(task);
|
||||
|
||||
unsafe {
|
||||
|
@ -182,7 +183,7 @@ mod test {
|
|||
do run_in_bare_thread {
|
||||
local_ptr::init_tls_key();
|
||||
let mut sched = ~new_test_uv_sched();
|
||||
let task = ~Task::new_root(&mut sched.stack_pool, || {});
|
||||
let task = ~Task::new_root(&mut sched.stack_pool, None, || {});
|
||||
Local::put(task);
|
||||
|
||||
let res = do Local::borrow::<Task,bool> |_task| {
|
||||
|
|
|
@ -331,8 +331,7 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
|
|||
// In the case where we do not use a main_thread scheduler we
|
||||
// run the main task in one of our threads.
|
||||
|
||||
let mut main_task = ~Task::new_root(&mut scheds[0].stack_pool,
|
||||
main.take());
|
||||
let mut main_task = ~Task::new_root(&mut scheds[0].stack_pool, None, main.take());
|
||||
main_task.death.on_exit = Some(on_exit.take());
|
||||
let main_task_cell = Cell::new(main_task);
|
||||
|
||||
|
@ -352,7 +351,7 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
|
|||
let sched_cell = Cell::new(sched);
|
||||
let thread = do Thread::start {
|
||||
let mut sched = sched_cell.take();
|
||||
let bootstrap_task = ~do Task::new_root(&mut sched.stack_pool) || {
|
||||
let bootstrap_task = ~do Task::new_root(&mut sched.stack_pool, None) || {
|
||||
rtdebug!("boostraping a non-primary scheduler");
|
||||
};
|
||||
sched.bootstrap(bootstrap_task);
|
||||
|
@ -369,7 +368,7 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
|
|||
let mut main_sched = main_sched.unwrap();
|
||||
|
||||
let home = Sched(main_sched.make_handle());
|
||||
let mut main_task = ~Task::new_root_homed(&mut main_sched.stack_pool,
|
||||
let mut main_task = ~Task::new_root_homed(&mut main_sched.stack_pool, None,
|
||||
home, main.take());
|
||||
main_task.death.on_exit = Some(on_exit.take());
|
||||
rtdebug!("boostrapping main_task");
|
||||
|
|
|
@ -833,7 +833,7 @@ mod test {
|
|||
let mut sched = ~new_test_uv_sched();
|
||||
let sched_handle = sched.make_handle();
|
||||
|
||||
let mut task = ~do Task::new_root_homed(&mut sched.stack_pool,
|
||||
let mut task = ~do Task::new_root_homed(&mut sched.stack_pool, None,
|
||||
Sched(sched_handle)) {
|
||||
unsafe { *task_ran_ptr = true };
|
||||
assert!(Task::on_appropriate_sched());
|
||||
|
@ -893,21 +893,21 @@ mod test {
|
|||
// 3) task not homed, sched requeues
|
||||
// 4) task not home, send home
|
||||
|
||||
let task1 = ~do Task::new_root_homed(&mut special_sched.stack_pool,
|
||||
let task1 = ~do Task::new_root_homed(&mut special_sched.stack_pool, None,
|
||||
Sched(t1_handle)) || {
|
||||
rtassert!(Task::on_appropriate_sched());
|
||||
};
|
||||
rtdebug!("task1 id: **%u**", borrow::to_uint(task1));
|
||||
|
||||
let task2 = ~do Task::new_root(&mut normal_sched.stack_pool) {
|
||||
let task2 = ~do Task::new_root(&mut normal_sched.stack_pool, None) {
|
||||
rtassert!(Task::on_appropriate_sched());
|
||||
};
|
||||
|
||||
let task3 = ~do Task::new_root(&mut normal_sched.stack_pool) {
|
||||
let task3 = ~do Task::new_root(&mut normal_sched.stack_pool, None) {
|
||||
rtassert!(Task::on_appropriate_sched());
|
||||
};
|
||||
|
||||
let task4 = ~do Task::new_root_homed(&mut special_sched.stack_pool,
|
||||
let task4 = ~do Task::new_root_homed(&mut special_sched.stack_pool, None,
|
||||
Sched(t4_handle)) {
|
||||
rtassert!(Task::on_appropriate_sched());
|
||||
};
|
||||
|
@ -923,7 +923,7 @@ mod test {
|
|||
let port = Cell::new(port);
|
||||
let chan = Cell::new(chan);
|
||||
|
||||
let normal_task = ~do Task::new_root(&mut normal_sched.stack_pool) {
|
||||
let normal_task = ~do Task::new_root(&mut normal_sched.stack_pool, None) {
|
||||
rtdebug!("*about to submit task2*");
|
||||
Scheduler::run_task(task2.take());
|
||||
rtdebug!("*about to submit task4*");
|
||||
|
@ -938,7 +938,7 @@ mod test {
|
|||
|
||||
rtdebug!("normal task: %u", borrow::to_uint(normal_task));
|
||||
|
||||
let special_task = ~do Task::new_root(&mut special_sched.stack_pool) {
|
||||
let special_task = ~do Task::new_root(&mut special_sched.stack_pool, None) {
|
||||
rtdebug!("*about to submit task1*");
|
||||
Scheduler::run_task(task1.take());
|
||||
rtdebug!("*about to submit task3*");
|
||||
|
|
|
@ -86,12 +86,13 @@ impl Task {
|
|||
|
||||
// A helper to build a new task using the dynamically found
|
||||
// scheduler and task. Only works in GreenTask context.
|
||||
pub fn build_homed_child(f: ~fn(), home: SchedHome) -> ~Task {
|
||||
pub fn build_homed_child(stack_size: Option<uint>, f: ~fn(), home: SchedHome) -> ~Task {
|
||||
let f = Cell::new(f);
|
||||
let home = Cell::new(home);
|
||||
do Local::borrow::<Task, ~Task> |running_task| {
|
||||
let mut sched = running_task.sched.take_unwrap();
|
||||
let new_task = ~running_task.new_child_homed(&mut sched.stack_pool,
|
||||
stack_size,
|
||||
home.take(),
|
||||
f.take());
|
||||
running_task.sched = Some(sched);
|
||||
|
@ -99,25 +100,26 @@ impl Task {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn build_child(f: ~fn()) -> ~Task {
|
||||
Task::build_homed_child(f, AnySched)
|
||||
pub fn build_child(stack_size: Option<uint>, f: ~fn()) -> ~Task {
|
||||
Task::build_homed_child(stack_size, f, AnySched)
|
||||
}
|
||||
|
||||
pub fn build_homed_root(f: ~fn(), home: SchedHome) -> ~Task {
|
||||
pub fn build_homed_root(stack_size: Option<uint>, f: ~fn(), home: SchedHome) -> ~Task {
|
||||
let f = Cell::new(f);
|
||||
let home = Cell::new(home);
|
||||
do Local::borrow::<Task, ~Task> |running_task| {
|
||||
let mut sched = running_task.sched.take_unwrap();
|
||||
let new_task = ~Task::new_root_homed(&mut sched.stack_pool,
|
||||
home.take(),
|
||||
f.take());
|
||||
stack_size,
|
||||
home.take(),
|
||||
f.take());
|
||||
running_task.sched = Some(sched);
|
||||
new_task
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build_root(f: ~fn()) -> ~Task {
|
||||
Task::build_homed_root(f, AnySched)
|
||||
pub fn build_root(stack_size: Option<uint>, f: ~fn()) -> ~Task {
|
||||
Task::build_homed_root(stack_size, f, AnySched)
|
||||
}
|
||||
|
||||
pub fn new_sched_task() -> Task {
|
||||
|
@ -138,17 +140,20 @@ impl Task {
|
|||
}
|
||||
|
||||
pub fn new_root(stack_pool: &mut StackPool,
|
||||
stack_size: Option<uint>,
|
||||
start: ~fn()) -> Task {
|
||||
Task::new_root_homed(stack_pool, AnySched, start)
|
||||
Task::new_root_homed(stack_pool, stack_size, AnySched, start)
|
||||
}
|
||||
|
||||
pub fn new_child(&mut self,
|
||||
stack_pool: &mut StackPool,
|
||||
stack_size: Option<uint>,
|
||||
start: ~fn()) -> Task {
|
||||
self.new_child_homed(stack_pool, AnySched, start)
|
||||
self.new_child_homed(stack_pool, stack_size, AnySched, start)
|
||||
}
|
||||
|
||||
pub fn new_root_homed(stack_pool: &mut StackPool,
|
||||
stack_size: Option<uint>,
|
||||
home: SchedHome,
|
||||
start: ~fn()) -> Task {
|
||||
Task {
|
||||
|
@ -161,7 +166,7 @@ impl Task {
|
|||
death: Death::new(),
|
||||
destroyed: false,
|
||||
name: None,
|
||||
coroutine: Some(Coroutine::new(stack_pool, start)),
|
||||
coroutine: Some(Coroutine::new(stack_pool, stack_size, start)),
|
||||
sched: None,
|
||||
task_type: GreenTask(Some(~home))
|
||||
}
|
||||
|
@ -169,6 +174,7 @@ impl Task {
|
|||
|
||||
pub fn new_child_homed(&mut self,
|
||||
stack_pool: &mut StackPool,
|
||||
stack_size: Option<uint>,
|
||||
home: SchedHome,
|
||||
start: ~fn()) -> Task {
|
||||
Task {
|
||||
|
@ -182,7 +188,7 @@ impl Task {
|
|||
death: self.death.new_child(),
|
||||
destroyed: false,
|
||||
name: None,
|
||||
coroutine: Some(Coroutine::new(stack_pool, start)),
|
||||
coroutine: Some(Coroutine::new(stack_pool, stack_size, start)),
|
||||
sched: None,
|
||||
task_type: GreenTask(Some(~home))
|
||||
}
|
||||
|
@ -326,8 +332,11 @@ impl Drop for Task {
|
|||
|
||||
impl Coroutine {
|
||||
|
||||
pub fn new(stack_pool: &mut StackPool, start: ~fn()) -> Coroutine {
|
||||
let stack_size = env::min_stack();
|
||||
pub fn new(stack_pool: &mut StackPool, stack_size: Option<uint>, start: ~fn()) -> Coroutine {
|
||||
let stack_size = match stack_size {
|
||||
Some(size) => size,
|
||||
None => env::min_stack()
|
||||
};
|
||||
let start = Coroutine::build_start_wrapper(start);
|
||||
let mut stack = stack_pool.take_segment(stack_size);
|
||||
let initial_context = Context::new(start, &mut stack);
|
||||
|
|
|
@ -57,7 +57,7 @@ pub fn run_in_newsched_task_core(f: ~fn()) {
|
|||
exit_handle.take().send(Shutdown);
|
||||
rtassert!(exit_status);
|
||||
};
|
||||
let mut task = ~Task::new_root(&mut sched.stack_pool, f);
|
||||
let mut task = ~Task::new_root(&mut sched.stack_pool, None, f);
|
||||
task.death.on_exit = Some(on_exit);
|
||||
|
||||
sched.bootstrap(task);
|
||||
|
@ -190,8 +190,7 @@ pub fn run_in_mt_newsched_task(f: ~fn()) {
|
|||
|
||||
rtassert!(exit_status);
|
||||
};
|
||||
let mut main_task = ~Task::new_root(&mut scheds[0].stack_pool,
|
||||
f.take());
|
||||
let mut main_task = ~Task::new_root(&mut scheds[0].stack_pool, None, f.take());
|
||||
main_task.death.on_exit = Some(on_exit);
|
||||
|
||||
let mut threads = ~[];
|
||||
|
@ -209,7 +208,7 @@ pub fn run_in_mt_newsched_task(f: ~fn()) {
|
|||
|
||||
while !scheds.is_empty() {
|
||||
let mut sched = scheds.pop();
|
||||
let bootstrap_task = ~do Task::new_root(&mut sched.stack_pool) || {
|
||||
let bootstrap_task = ~do Task::new_root(&mut sched.stack_pool, None) || {
|
||||
rtdebug!("bootstrapping non-primary scheduler");
|
||||
};
|
||||
let bootstrap_task_cell = Cell::new(bootstrap_task);
|
||||
|
@ -232,12 +231,12 @@ pub fn run_in_mt_newsched_task(f: ~fn()) {
|
|||
|
||||
/// Test tasks will abort on failure instead of unwinding
|
||||
pub fn spawntask(f: ~fn()) {
|
||||
Scheduler::run_task(Task::build_child(f));
|
||||
Scheduler::run_task(Task::build_child(None, f));
|
||||
}
|
||||
|
||||
/// Create a new task and run it right now. Aborts on failure
|
||||
pub fn spawntask_later(f: ~fn()) {
|
||||
Scheduler::run_task_later(Task::build_child(f));
|
||||
Scheduler::run_task_later(Task::build_child(None, f));
|
||||
}
|
||||
|
||||
pub fn spawntask_random(f: ~fn()) {
|
||||
|
@ -259,7 +258,7 @@ pub fn spawntask_try(f: ~fn()) -> Result<(),()> {
|
|||
let chan = Cell::new(chan);
|
||||
let on_exit: ~fn(bool) = |exit_status| chan.take().send(exit_status);
|
||||
|
||||
let mut new_task = Task::build_root(f);
|
||||
let mut new_task = Task::build_root(None, f);
|
||||
new_task.death.on_exit = Some(on_exit);
|
||||
|
||||
Scheduler::run_task(new_task);
|
||||
|
@ -285,7 +284,7 @@ pub fn spawntask_thread(f: ~fn()) -> Thread {
|
|||
pub fn with_test_task(blk: ~fn(~Task) -> ~Task) {
|
||||
do run_in_bare_thread {
|
||||
let mut sched = ~new_test_uv_sched();
|
||||
let task = blk(~Task::new_root(&mut sched.stack_pool, ||{}));
|
||||
let task = blk(~Task::new_root(&mut sched.stack_pool, None, ||{}));
|
||||
cleanup_task(task);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -142,7 +142,8 @@ pub struct TaskOpts {
|
|||
indestructible: bool,
|
||||
notify_chan: Option<Chan<TaskResult>>,
|
||||
name: Option<~str>,
|
||||
sched: SchedOpts
|
||||
sched: SchedOpts,
|
||||
stack_size: Option<uint>
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -197,7 +198,8 @@ impl TaskBuilder {
|
|||
indestructible: self.opts.indestructible,
|
||||
notify_chan: notify_chan,
|
||||
name: name,
|
||||
sched: self.opts.sched
|
||||
sched: self.opts.sched,
|
||||
stack_size: self.opts.stack_size
|
||||
},
|
||||
gen_body: gen_body,
|
||||
can_not_copy: None,
|
||||
|
@ -351,7 +353,8 @@ impl TaskBuilder {
|
|||
indestructible: x.opts.indestructible,
|
||||
notify_chan: notify_chan,
|
||||
name: name,
|
||||
sched: x.opts.sched
|
||||
sched: x.opts.sched,
|
||||
stack_size: x.opts.stack_size
|
||||
};
|
||||
let f = match gen_body {
|
||||
Some(gen) => {
|
||||
|
@ -422,7 +425,8 @@ pub fn default_task_opts() -> TaskOpts {
|
|||
name: None,
|
||||
sched: SchedOpts {
|
||||
mode: DefaultScheduler,
|
||||
}
|
||||
},
|
||||
stack_size: None
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -713,9 +713,9 @@ fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) {
|
|||
let mut task = unsafe {
|
||||
if opts.sched.mode != SingleThreaded {
|
||||
if opts.watched {
|
||||
Task::build_child(child_wrapper)
|
||||
Task::build_child(opts.stack_size, child_wrapper)
|
||||
} else {
|
||||
Task::build_root(child_wrapper)
|
||||
Task::build_root(opts.stack_size, child_wrapper)
|
||||
}
|
||||
} else {
|
||||
// Creating a 1:1 task:thread ...
|
||||
|
@ -736,16 +736,16 @@ fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) {
|
|||
|
||||
// Pin the new task to the new scheduler
|
||||
let new_task = if opts.watched {
|
||||
Task::build_homed_child(child_wrapper, Sched(new_sched_handle))
|
||||
Task::build_homed_child(opts.stack_size, child_wrapper, Sched(new_sched_handle))
|
||||
} else {
|
||||
Task::build_homed_root(child_wrapper, Sched(new_sched_handle))
|
||||
Task::build_homed_root(opts.stack_size, child_wrapper, Sched(new_sched_handle))
|
||||
};
|
||||
|
||||
// Create a task that will later be used to join with the new scheduler
|
||||
// thread when it is ready to terminate
|
||||
let (thread_port, thread_chan) = oneshot();
|
||||
let thread_port_cell = Cell::new(thread_port);
|
||||
let join_task = do Task::build_child() {
|
||||
let join_task = do Task::build_child(None) {
|
||||
rtdebug!("running join task");
|
||||
let thread_port = thread_port_cell.take();
|
||||
let thread: Thread = thread_port.recv();
|
||||
|
@ -762,8 +762,8 @@ fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) {
|
|||
let mut orig_sched_handle = orig_sched_handle_cell.take();
|
||||
let join_task = join_task_cell.take();
|
||||
|
||||
let bootstrap_task = ~do Task::new_root(&mut new_sched.stack_pool) || {
|
||||
rtdebug!("bootstrapping a 1:1 scheduler");
|
||||
let bootstrap_task = ~do Task::new_root(&mut new_sched.stack_pool, None) || {
|
||||
rtdebug!("boostrapping a 1:1 scheduler");
|
||||
};
|
||||
new_sched.bootstrap(bootstrap_task);
|
||||
|
||||
|
|
Loading…
Reference in a new issue