about summary refs log tree commit diff
path: root/src/libcore/task
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2013-01-08 19:46:12 -0800
committerBrian Anderson <banderson@mozilla.com>2013-01-15 18:00:19 -0800
commit090b247056a9dd2d4d4a32c631fe2f0ddd3e744d (patch)
treeb7b9d7ab483fa7150480f90c9a5ad69905753685 /src/libcore/task
parent989667e545cb45265d3cb4b19500224459c3bf8c (diff)
downloadrust-090b247056a9dd2d4d4a32c631fe2f0ddd3e744d.tar.gz
rust-090b247056a9dd2d4d4a32c631fe2f0ddd3e744d.zip
Spawn new tasks onto the primary scheduler by default. #3760
Diffstat (limited to 'src/libcore/task')
-rw-r--r--src/libcore/task/mod.rs100
-rw-r--r--src/libcore/task/spawn.rs23
2 files changed, 55 insertions, 68 deletions
diff --git a/src/libcore/task/mod.rs b/src/libcore/task/mod.rs
index c6b0491786d..86d38a18c50 100644
--- a/src/libcore/task/mod.rs
+++ b/src/libcore/task/mod.rs
@@ -52,7 +52,7 @@ use prelude::*;
 use ptr;
 use result;
 use task::local_data_priv::{local_get, local_set};
-use task::rt::{task_id, rust_task};
+use task::rt::{task_id, sched_id, rust_task};
 use task;
 use util;
 use util::replace;
@@ -62,6 +62,12 @@ pub mod local_data;
 pub mod rt;
 pub mod spawn;
 
+/// A handle to a scheduler
+#[deriving_eq]
+pub enum Scheduler {
+    SchedulerHandle(sched_id)
+}
+
 /// A handle to a task
 #[deriving_eq]
 pub enum Task {
@@ -95,7 +101,21 @@ impl TaskResult : Eq {
 }
 
 /// Scheduler modes
+#[deriving_eq]
 pub enum SchedMode {
+    /// Run task on the default scheduler
+    DefaultScheduler,
+    /// Run task on the current scheduler
+    CurrentScheduler,
+    /// Run task on a specific scheduler
+    ExistingScheduler(Scheduler),
+    /**
+     * Tasks are scheduled on the main OS thread
+     *
+     * The main OS thread is the thread used to launch the runtime which,
+     * in most cases, is the process's initial thread as created by the OS.
+     */
+    PlatformThread,
     /// All tasks run in the same OS thread
     SingleThreaded,
     /// Tasks are distributed among available CPUs
@@ -104,53 +124,6 @@ pub enum SchedMode {
     ThreadPerTask,
     /// Tasks are distributed among a fixed number of OS threads
     ManualThreads(uint),
-    /**
-     * Tasks are scheduled on the main OS thread
-     *
-     * The main OS thread is the thread used to launch the runtime which,
-     * in most cases, is the process's initial thread as created by the OS.
-     */
-    PlatformThread
-}
-
-impl SchedMode : cmp::Eq {
-    pure fn eq(&self, other: &SchedMode) -> bool {
-        match (*self) {
-            SingleThreaded => {
-                match (*other) {
-                    SingleThreaded => true,
-                    _ => false
-                }
-            }
-            ThreadPerCore => {
-                match (*other) {
-                    ThreadPerCore => true,
-                    _ => false
-                }
-            }
-            ThreadPerTask => {
-                match (*other) {
-                    ThreadPerTask => true,
-                    _ => false
-                }
-            }
-            ManualThreads(e0a) => {
-                match (*other) {
-                    ManualThreads(e0b) => e0a == e0b,
-                    _ => false
-                }
-            }
-            PlatformThread => {
-                match (*other) {
-                    PlatformThread => true,
-                    _ => false
-                }
-            }
-        }
-    }
-    pure fn ne(&self, other: &SchedMode) -> bool {
-        !(*self).eq(other)
-    }
 }
 
 /**
@@ -204,7 +177,7 @@ pub type TaskOpts = {
     linked: bool,
     supervised: bool,
     mut notify_chan: Option<Chan<TaskResult>>,
-    sched: Option<SchedOpts>,
+    sched: SchedOpts,
 };
 
 /**
@@ -370,7 +343,7 @@ impl TaskBuilder {
                 linked: self.opts.linked,
                 supervised: self.opts.supervised,
                 mut notify_chan: move notify_chan,
-                sched: Some({ mode: mode, foreign_stack_size: None})
+                sched: { mode: mode, foreign_stack_size: None}
             },
             can_not_copy: None,
             .. self.consume()
@@ -486,7 +459,10 @@ pub fn default_task_opts() -> TaskOpts {
         linked: true,
         supervised: false,
         mut notify_chan: None,
-        sched: None
+        sched: {
+            mode: DefaultScheduler,
+            foreign_stack_size: None
+        }
     }
 }
 
@@ -539,10 +515,9 @@ pub fn spawn_with<A:Owned>(arg: A, f: fn~(v: A)) {
 
 pub fn spawn_sched(mode: SchedMode, f: fn~()) {
     /*!
-     * Creates a new scheduler and executes a task on it
-     *
-     * Tasks subsequently spawned by that task will also execute on
-     * the new scheduler. When there are no more tasks to execute the
+     * Creates a new task on a new or existing scheduler
+
+     * When there are no more tasks to execute the
      * scheduler terminates.
      *
      * # Failure
@@ -590,6 +565,10 @@ pub fn get_task() -> Task {
     TaskHandle(rt::get_task_id())
 }
 
+pub fn get_scheduler() -> Scheduler {
+    SchedulerHandle(rt::rust_get_sched_id())
+}
+
 /**
  * Temporarily make the task unkillable
  *
@@ -927,16 +906,19 @@ fn test_spawn_sched() {
 }
 
 #[test]
-fn test_spawn_sched_childs_on_same_sched() {
+fn test_spawn_sched_childs_on_default_sched() {
     let po = oldcomm::Port();
     let ch = oldcomm::Chan(&po);
 
+    // Assuming tests run on the default scheduler
+    let default_id = rt::rust_get_sched_id();
+
     do spawn_sched(SingleThreaded) {
         let parent_sched_id = rt::rust_get_sched_id();
         do spawn {
             let child_sched_id = rt::rust_get_sched_id();
-            // This should be on the same scheduler
-            assert parent_sched_id == child_sched_id;
+            assert parent_sched_id != child_sched_id;
+            assert child_sched_id == default_id;
             oldcomm::send(ch, ());
         };
     };
@@ -1206,7 +1188,7 @@ fn test_spawn_thread_on_demand() {
 
         let (port2, chan2) = pipes::stream();
 
-        do spawn() |move chan2| {
+        do spawn_sched(CurrentScheduler) |move chan2| {
             chan2.send(());
         }
 
diff --git a/src/libcore/task/spawn.rs b/src/libcore/task/spawn.rs
index 1c5531303e1..e3afa7c4535 100644
--- a/src/libcore/task/spawn.rs
+++ b/src/libcore/task/spawn.rs
@@ -88,6 +88,7 @@ use task::rt::rust_closure;
 use task::rt;
 use task::{Failure, ManualThreads, PlatformThread, SchedOpts, SingleThreaded};
 use task::{Success, TaskOpts, TaskResult, ThreadPerCore, ThreadPerTask};
+use task::{ExistingScheduler, SchedulerHandle};
 use task::{default_task_opts, unkillable};
 use uint;
 use util;
@@ -525,9 +526,9 @@ pub fn spawn_raw(opts: TaskOpts, f: fn~()) {
             // Agh. Get move-mode items into the closure. FIXME (#2829)
             let (child_tg, ancestors, f) = option::swap_unwrap(child_data);
             // Create child task.
-            let new_task = match opts.sched {
-              None             => rt::new_task(),
-              Some(sched_opts) => new_task_in_new_sched(sched_opts)
+            let new_task = match opts.sched.mode {
+                DefaultScheduler => rt::new_task(),
+                _ => new_task_in_sched(opts.sched)
             };
             assert !new_task.is_null();
             // Getting killed after here would leak the task.
@@ -631,12 +632,16 @@ pub fn spawn_raw(opts: TaskOpts, f: fn~()) {
         }
     }
 
-    fn new_task_in_new_sched(opts: SchedOpts) -> *rust_task {
+    fn new_task_in_sched(opts: SchedOpts) -> *rust_task {
         if opts.foreign_stack_size != None {
             fail ~"foreign_stack_size scheduler option unimplemented";
         }
 
         let num_threads = match opts.mode {
+          DefaultScheduler
+          | CurrentScheduler
+          | ExistingScheduler(*)
+          | PlatformThread => 0u, /* Won't be used */
           SingleThreaded => 1u,
           ThreadPerCore => rt::rust_num_threads(),
           ThreadPerTask => {
@@ -648,13 +653,13 @@ pub fn spawn_raw(opts: TaskOpts, f: fn~()) {
             }
             threads
           }
-          PlatformThread => 0u /* Won't be used */
         };
 
-        let sched_id = if opts.mode != PlatformThread {
-            rt::rust_new_sched(num_threads)
-        } else {
-            rt::rust_osmain_sched_id()
+        let sched_id = match opts.mode {
+            CurrentScheduler => rt::rust_get_sched_id(),
+            ExistingScheduler(SchedulerHandle(id)) => id,
+            PlatformThread => rt::rust_osmain_sched_id(),
+            _ => rt::rust_new_sched(num_threads)
         };
         rt::rust_new_task_in_sched(sched_id)
     }