about summary refs log tree commit diff
path: root/src/libstd/task/spawn.rs
diff options
context:
space:
mode:
authortoddaaro <github@opprobrio.us>2013-07-19 14:25:05 -0700
committertoddaaro <github@opprobrio.us>2013-08-01 15:14:00 -0700
commitf7eed223873a4280c9abea937e60ef1aaedf0162 (patch)
treed1dea92a84b12741e7796cf91938edbae906fd8e /src/libstd/task/spawn.rs
parent82b24559e6aa0914f8a49e0a9dbfb3cf35372515 (diff)
downloadrust-f7eed223873a4280c9abea937e60ef1aaedf0162.tar.gz
rust-f7eed223873a4280c9abea937e60ef1aaedf0162.zip
A major refactoring that changes the way the runtime uses TLS. In the
old design the TLS held the scheduler struct, and the scheduler struct
held the active task. This posed all sorts of weird problems due to
how we wanted to use the contents of TLS. The cleaner approach is to
leave the active task in TLS and have the task hold the scheduler. To
make this work out the scheduler has to run inside a regular task, and
then once that is the case the context switching code is massively
simplified, as instead of three possible paths there is only one. The
logical flow is also easier to follow, as the scheduler struct acts
somewhat like a "token" indicating what is active.

These changes also necessitated changing a large number of runtime
tests, and rewriting most of the runtime testing helpers.

Polish level is "low", as I will very soon start on more scheduler
changes that will require wiping the polish off. That being said there
should be sufficient comments around anything complex to make this
entirely respectable as a standalone commit.
Diffstat (limited to 'src/libstd/task/spawn.rs')
-rw-r--r--src/libstd/task/spawn.rs43
1 files changed, 13 insertions, 30 deletions
diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs
index 4558f8e32c1..88f214ef4c0 100644
--- a/src/libstd/task/spawn.rs
+++ b/src/libstd/task/spawn.rs
@@ -653,22 +653,16 @@ fn enlist_many(child: TaskHandle, child_arc: &TaskGroupArc,
 
 pub fn spawn_raw(opts: TaskOpts, f: ~fn()) {
     match context() {
-        OldTaskContext => {
-            spawn_raw_oldsched(opts, f)
-        }
-        TaskContext => {
-            spawn_raw_newsched(opts, f)
-        }
-        SchedulerContext => {
-            fail!("can't spawn from scheduler context")
-        }
-        GlobalContext => {
-            fail!("can't spawn from global context")
-        }
+        OldTaskContext   => spawn_raw_oldsched(opts, f),
+        TaskContext      => spawn_raw_newsched(opts, f),
+        SchedulerContext => fail!("can't spawn from scheduler context"),
+        GlobalContext    => fail!("can't spawn from global context"),
     }
 }
 
 fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) {
+    use rt::sched::*;
+
     let child_data = Cell::new(gen_child_taskgroup(opts.linked, opts.supervised));
     let indestructible = opts.indestructible;
 
@@ -700,19 +694,11 @@ fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) {
         }
     };
 
-    let mut task = unsafe {
-        let sched = Local::unsafe_borrow::<Scheduler>();
-        rtdebug!("unsafe borrowed sched");
-
-        if opts.watched {
-            let child_wrapper = Cell::new(child_wrapper);
-            do Local::borrow::<Task, ~Task>() |running_task| {
-                ~running_task.new_child(&mut (*sched).stack_pool, child_wrapper.take())
-            }
-        } else {
-            // An unwatched task is a new root in the exit-code propagation tree
-            ~Task::new_root(&mut (*sched).stack_pool, child_wrapper)
-        }
+    let mut task = if opts.watched {
+        Task::build_child(child_wrapper)
+    } else {
+        // An unwatched task is a new root in the exit-code propagation tree
+        Task::build_root(child_wrapper)
     };
 
     if opts.notify_chan.is_some() {
@@ -727,12 +713,9 @@ fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) {
     }
 
     task.name = opts.name.take();
+    rtdebug!("spawn calling run_task");
+    Scheduler::run_task(task);
 
-    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()) {