diff options
| author | bors <bors@rust-lang.org> | 2013-07-09 18:28:46 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-07-09 18:28:46 -0700 |
| commit | 41dcec2fe16e272016ae77d10a6a5ff3a737f192 (patch) | |
| tree | 6eebc49e7033a0d696c93c8e23d7caeb28d4eca1 /src/libstd/task | |
| parent | 137d1fb210a844a76f89d7355a1aaf9f7a88af33 (diff) | |
| parent | 413d51e32debf0c3f7dda2434b64d73585df21ef (diff) | |
| download | rust-41dcec2fe16e272016ae77d10a6a5ff3a737f192.tar.gz rust-41dcec2fe16e272016ae77d10a6a5ff3a737f192.zip | |
auto merge of #7265 : brson/rust/io-upstream, r=brson
r? @graydon, @nikomatsakis, @pcwalton, or @catamorphism Sorry this is so huge, but it's been accumulating for about a month. There's lots of stuff here, mostly oriented toward enabling multithreaded scheduling and improving compatibility between the old and new runtimes. Adds task pinning so that we can create the 'platform thread' in servo. [Here](https://github.com/brson/rust/blob/e1555f9b5628af2b6c6ed344cad621399cb7684d/src/libstd/rt/mod.rs#L201) is the current runtime setup code. About half of this has already been reviewed.
Diffstat (limited to 'src/libstd/task')
| -rw-r--r-- | src/libstd/task/mod.rs | 39 | ||||
| -rw-r--r-- | src/libstd/task/spawn.rs | 38 |
2 files changed, 56 insertions, 21 deletions
diff --git a/src/libstd/task/mod.rs b/src/libstd/task/mod.rs index a8e8cfd163a..5a3ff10ae83 100644 --- a/src/libstd/task/mod.rs +++ b/src/libstd/task/mod.rs @@ -497,11 +497,26 @@ pub fn try<T:Send>(f: ~fn() -> T) -> Result<T,()> { pub fn yield() { //! Yield control to the task scheduler + use rt::{context, OldTaskContext}; + use rt::local::Local; + use rt::sched::Scheduler; + unsafe { - let task_ = rt::rust_get_task(); - let killed = rt::rust_task_yield(task_); - if killed && !failing() { - fail!("killed"); + match context() { + OldTaskContext => { + let task_ = rt::rust_get_task(); + let killed = rt::rust_task_yield(task_); + if killed && !failing() { + fail!("killed"); + } + } + _ => { + // XXX: What does yield really mean in newsched? + let sched = Local::take::<Scheduler>(); + do sched.deschedule_running_task_and_then |sched, task| { + sched.enqueue_task(task); + } + } } } } @@ -520,20 +535,9 @@ pub fn failing() -> bool { } } _ => { - let mut unwinding = false; - do Local::borrow::<Task> |local| { - unwinding = match local.unwinder { - Some(unwinder) => { - unwinder.unwinding - } - None => { - // Because there is no unwinder we can't be unwinding. - // (The process will abort on failure) - false - } - } + do Local::borrow::<Task, bool> |local| { + local.unwinder.unwinding } - return unwinding; } } } @@ -1191,3 +1195,4 @@ fn test_simple_newsched_spawn() { spawn(||()) } } + diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs index 190485a720a..bcb7e06bf1f 100644 --- a/src/libstd/task/spawn.rs +++ b/src/libstd/task/spawn.rs @@ -91,6 +91,7 @@ use uint; use util; use unstable::sync::{Exclusive, exclusive}; use rt::local::Local; +use rt::task::Task; use iterator::IteratorUtil; #[cfg(test)] use task::default_task_opts; @@ -581,12 +582,41 @@ pub fn spawn_raw(opts: TaskOpts, f: ~fn()) { } } -fn spawn_raw_newsched(_opts: TaskOpts, f: ~fn()) { +fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) { use rt::sched::*; - let mut sched = Local::take::<Scheduler>(); - let task = ~Coroutine::new(&mut sched.stack_pool, f); - sched.schedule_new_task(task); + let f = Cell::new(f); + + let mut task = unsafe { + let sched = Local::unsafe_borrow::<Scheduler>(); + rtdebug!("unsafe borrowed sched"); + + if opts.linked { + do Local::borrow::<Task, ~Task>() |running_task| { + ~running_task.new_child(&mut (*sched).stack_pool, f.take()) + } + } else { + // An unlinked task is a new root in the task tree + ~Task::new_root(&mut (*sched).stack_pool, f.take()) + } + }; + + if opts.notify_chan.is_some() { + let notify_chan = opts.notify_chan.swap_unwrap(); + let notify_chan = Cell::new(notify_chan); + let on_exit: ~fn(bool) = |success| { + notify_chan.take().send( + if success { Success } else { Failure } + ) + }; + task.on_exit = Some(on_exit); + } + + rtdebug!("spawn about to take scheduler"); + + let sched = Local::take::<Scheduler>(); + rtdebug!("took sched in spawn"); + sched.schedule_task(task); } fn spawn_raw_oldsched(mut opts: TaskOpts, f: ~fn()) { |
