std::rt: Change the Task constructors to reflect a tree

This commit is contained in:
Brian Anderson 2013-06-13 22:43:20 -07:00
parent abc3a8aa1e
commit fd148cd3e2
5 changed files with 81 additions and 26 deletions

View file

@ -167,7 +167,7 @@ pub fn start(_argc: int, _argv: **u8, crate_map: *u8, main: ~fn()) -> int {
let sleepers = SleeperList::new();
let mut sched = ~Scheduler::new(loop_, work_queue, sleepers);
sched.no_sleep = true;
let main_task = ~Coroutine::new(&mut sched.stack_pool, main);
let main_task = ~Coroutine::new_root(&mut sched.stack_pool, main);
sched.enqueue_task(main_task);
sched.run();
@ -241,7 +241,7 @@ fn test_context() {
do run_in_bare_thread {
assert_eq!(context(), GlobalContext);
let mut sched = ~new_test_uv_sched();
let task = ~do Coroutine::new(&mut sched.stack_pool) {
let task = ~do Coroutine::new_root(&mut sched.stack_pool) {
assert_eq!(context(), TaskContext);
let sched = Local::take::<Scheduler>();
do sched.deschedule_running_task_and_then() |sched, task| {

View file

@ -518,8 +518,8 @@ impl SchedHandle {
}
pub impl Coroutine {
fn new(stack_pool: &mut StackPool, start: ~fn()) -> Coroutine {
Coroutine::with_task(stack_pool, ~Task::new(), start)
fn new_root(stack_pool: &mut StackPool, start: ~fn()) -> Coroutine {
Coroutine::with_task(stack_pool, ~Task::new_root(), start)
}
fn with_task(stack_pool: &mut StackPool,
@ -614,7 +614,7 @@ mod test {
let task_ran_ptr: *mut bool = &mut task_ran;
let mut sched = ~new_test_uv_sched();
let task = ~do Coroutine::new(&mut sched.stack_pool) {
let task = ~do Coroutine::new_root(&mut sched.stack_pool) {
unsafe { *task_ran_ptr = true; }
};
sched.enqueue_task(task);
@ -632,7 +632,7 @@ mod test {
let mut sched = ~new_test_uv_sched();
for int::range(0, total) |_| {
let task = ~do Coroutine::new(&mut sched.stack_pool) {
let task = ~do Coroutine::new_root(&mut sched.stack_pool) {
unsafe { *task_count_ptr = *task_count_ptr + 1; }
};
sched.enqueue_task(task);
@ -649,10 +649,10 @@ mod test {
let count_ptr: *mut int = &mut count;
let mut sched = ~new_test_uv_sched();
let task1 = ~do Coroutine::new(&mut sched.stack_pool) {
let task1 = ~do Coroutine::new_root(&mut sched.stack_pool) {
unsafe { *count_ptr = *count_ptr + 1; }
let mut sched = Local::take::<Scheduler>();
let task2 = ~do Coroutine::new(&mut sched.stack_pool) {
let task2 = ~do Coroutine::new_root(&mut sched.stack_pool) {
unsafe { *count_ptr = *count_ptr + 1; }
};
// Context switch directly to the new task
@ -677,7 +677,7 @@ mod test {
let mut sched = ~new_test_uv_sched();
let start_task = ~do Coroutine::new(&mut sched.stack_pool) {
let start_task = ~do Coroutine::new_root(&mut sched.stack_pool) {
run_task(count_ptr);
};
sched.enqueue_task(start_task);
@ -687,7 +687,7 @@ mod test {
fn run_task(count_ptr: *mut int) {
do Local::borrow::<Scheduler> |sched| {
let task = ~do Coroutine::new(&mut sched.stack_pool) {
let task = ~do Coroutine::new_root(&mut sched.stack_pool) {
unsafe {
*count_ptr = *count_ptr + 1;
if *count_ptr != MAX {
@ -705,7 +705,7 @@ mod test {
fn test_block_task() {
do run_in_bare_thread {
let mut sched = ~new_test_uv_sched();
let task = ~do Coroutine::new(&mut sched.stack_pool) {
let task = ~do Coroutine::new_root(&mut sched.stack_pool) {
let sched = Local::take::<Scheduler>();
assert!(sched.in_task_context());
do sched.deschedule_running_task_and_then() |sched, task| {
@ -752,13 +752,13 @@ mod test {
let mut sched1 = ~new_test_uv_sched();
let handle1 = sched1.make_handle();
let handle1_cell = Cell(handle1);
let task1 = ~do Coroutine::new(&mut sched1.stack_pool) {
let task1 = ~do Coroutine::new_root(&mut sched1.stack_pool) {
chan_cell.take().send(());
};
sched1.enqueue_task(task1);
let mut sched2 = ~new_test_uv_sched();
let task2 = ~do Coroutine::new(&mut sched2.stack_pool) {
let task2 = ~do Coroutine::new_root(&mut sched2.stack_pool) {
port_cell.take().recv();
// Release the other scheduler's handle so it can exit
handle1_cell.take();

View file

@ -37,7 +37,7 @@ pub struct Unwinder {
}
impl Task {
pub fn new() -> Task {
pub fn new_root() -> Task {
Task {
heap: LocalHeap::new(),
gc: GarbageCollector,
@ -48,7 +48,29 @@ impl Task {
}
}
pub fn without_unwinding() -> Task {
pub fn new_root_without_unwinding() -> Task {
Task {
heap: LocalHeap::new(),
gc: GarbageCollector,
storage: LocalStorage(ptr::null(), None),
logger: StdErrLogger,
unwinder: None,
destroyed: false
}
}
pub fn new_child(&mut self) -> Task {
Task {
heap: LocalHeap::new(),
gc: GarbageCollector,
storage: LocalStorage(ptr::null(), None),
logger: StdErrLogger,
unwinder: Some(Unwinder { unwinding: false }),
destroyed: false
}
}
pub fn new_child_without_unwinding(&mut self) -> Task {
Task {
heap: LocalHeap::new(),
gc: GarbageCollector,

View file

@ -48,7 +48,7 @@ pub fn run_in_newsched_task(f: ~fn()) {
do run_in_bare_thread {
let mut sched = ~new_test_uv_sched();
let task = ~Coroutine::with_task(&mut sched.stack_pool,
~Task::without_unwinding(),
~Task::new_root_without_unwinding(),
f.take());
sched.enqueue_task(task);
sched.run();
@ -94,7 +94,7 @@ pub fn run_in_mt_newsched_task(f: ~fn()) {
let f_cell = Cell(f_cell.take());
let handles = Cell(handles);
let main_task = ~do Coroutine::new(&mut scheds[0].stack_pool) {
let main_task = ~do Coroutine::new_root(&mut scheds[0].stack_pool) {
f_cell.take()();
let mut handles = handles.take();
@ -132,9 +132,14 @@ pub fn run_in_mt_newsched_task(f: ~fn()) {
pub fn spawntask(f: ~fn()) {
use super::sched::*;
let mut task = None;
do Local::borrow::<Task>() |running_task| {
task = Some(~running_task.new_child_without_unwinding());
}
let mut sched = Local::take::<Scheduler>();
let task = ~Coroutine::with_task(&mut sched.stack_pool,
~Task::without_unwinding(),
task.swap_unwrap(),
f);
sched.schedule_new_task(task);
}
@ -143,9 +148,14 @@ pub fn spawntask(f: ~fn()) {
pub fn spawntask_immediately(f: ~fn()) {
use super::sched::*;
let mut task = None;
do Local::borrow::<Task>() |running_task| {
task = Some(~running_task.new_child_without_unwinding());
}
let mut sched = Local::take::<Scheduler>();
let task = ~Coroutine::with_task(&mut sched.stack_pool,
~Task::without_unwinding(),
task.swap_unwrap(),
f);
do sched.switch_running_tasks_and_then(task) |sched, task| {
sched.enqueue_task(task);
@ -156,9 +166,14 @@ pub fn spawntask_immediately(f: ~fn()) {
pub fn spawntask_later(f: ~fn()) {
use super::sched::*;
let mut task = None;
do Local::borrow::<Task>() |running_task| {
task = Some(~running_task.new_child_without_unwinding());
}
let mut sched = Local::take::<Scheduler>();
let task = ~Coroutine::with_task(&mut sched.stack_pool,
~Task::without_unwinding(),
task.swap_unwrap(),
f);
sched.enqueue_task(task);
@ -170,14 +185,19 @@ pub fn spawntask_random(f: ~fn()) {
use super::sched::*;
use rand::{Rand, rng};
let mut rng = rng();
let run_now: bool = Rand::rand(&mut rng);
let mut task = None;
do Local::borrow::<Task>() |running_task| {
task = Some(~running_task.new_child_without_unwinding());
}
let mut sched = Local::take::<Scheduler>();
let task = ~Coroutine::with_task(&mut sched.stack_pool,
~Task::without_unwinding(),
task.swap_unwrap(),
f);
let mut rng = rng();
let run_now: bool = Rand::rand(&mut rng);
if run_now {
do sched.switch_running_tasks_and_then(task) |sched, task| {
sched.enqueue_task(task);
@ -206,7 +226,7 @@ pub fn spawntask_try(f: ~fn()) -> Result<(), ()> {
do sched.deschedule_running_task_and_then() |sched, old_task| {
let old_task = Cell(old_task);
let f = f.take();
let new_task = ~do Coroutine::new(&mut sched.stack_pool) {
let new_task = ~do Coroutine::new_root(&mut sched.stack_pool) {
do (|| {
(f.take())()
}).finally {
@ -229,11 +249,17 @@ pub fn spawntask_try(f: ~fn()) -> Result<(), ()> {
pub fn spawntask_thread(f: ~fn()) -> Thread {
use rt::sched::*;
let mut task = None;
do Local::borrow::<Task>() |running_task| {
task = Some(~running_task.new_child_without_unwinding());
}
let task = Cell(task.swap_unwrap());
let f = Cell(f);
let thread = do Thread::start {
let mut sched = ~new_test_uv_sched();
let task = ~Coroutine::with_task(&mut sched.stack_pool,
~Task::without_unwinding(),
task.take(),
f.take());
sched.enqueue_task(task);
sched.run();

View file

@ -91,6 +91,7 @@ use uint;
use util;
use unstable::sync::{Exclusive, exclusive};
use rt::local::Local;
use rt::task::Task;
#[cfg(test)] use task::default_task_opts;
@ -576,8 +577,14 @@ pub fn spawn_raw(opts: TaskOpts, f: ~fn()) {
fn spawn_raw_newsched(_opts: TaskOpts, f: ~fn()) {
use rt::sched::*;
let mut task = None;
do Local::borrow::<Task>() |running_task| {
task = Some(~running_task.new_child_without_unwinding());
}
let mut sched = Local::take::<Scheduler>();
let task = ~Coroutine::new(&mut sched.stack_pool, f);
let task = ~Coroutine::with_task(&mut sched.stack_pool,
task.swap_unwrap(), f);
sched.schedule_new_task(task);
}