diff options
| author | toddaaro <github@opprobrio.us> | 2013-06-12 14:55:32 -0700 |
|---|---|---|
| committer | toddaaro <github@opprobrio.us> | 2013-06-12 14:55:32 -0700 |
| commit | 4224fc7aad3cfbd7093e55812e5a566d7aad3325 (patch) | |
| tree | 9c04690212581ccaac9359e7eda0377e4dc6e963 /src/libstd | |
| parent | 84280819585fb65bf18903aef9364579f3552522 (diff) | |
| download | rust-4224fc7aad3cfbd7093e55812e5a566d7aad3325.tar.gz rust-4224fc7aad3cfbd7093e55812e5a566d7aad3325.zip | |
added functionality to tell schedulers to refuse to run tasks that are not pinned to them
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/rt/sched.rs | 48 | ||||
| -rw-r--r-- | src/libstd/rt/test.rs | 30 |
2 files changed, 60 insertions, 18 deletions
diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs index 698cafdf8c6..4bc61d63824 100644 --- a/src/libstd/rt/sched.rs +++ b/src/libstd/rt/sched.rs @@ -70,7 +70,9 @@ pub struct Scheduler { /// An action performed after a context switch on behalf of the /// code running before the context switch priv cleanup_job: Option<CleanupJob>, - metrics: SchedMetrics + metrics: SchedMetrics, + /// Should this scheduler run any task, or only pinned tasks? + run_anything: bool } pub struct SchedHandle { @@ -136,6 +138,16 @@ pub impl Scheduler { sleeper_list: SleeperList) -> Scheduler { + Scheduler::new_special(event_loop, work_queue, sleeper_list, true) + + } + + fn new_special(event_loop: ~EventLoopObject, + work_queue: WorkQueue<~Coroutine>, + sleeper_list: SleeperList, + run_anything: bool) + -> Scheduler { + // Lazily initialize the runtime TLS key local_ptr::init_tls_key(); @@ -150,7 +162,8 @@ pub impl Scheduler { saved_context: Context::empty(), current_task: None, cleanup_job: None, - metrics: SchedMetrics::new() + metrics: SchedMetrics::new(), + run_anything: run_anything } } @@ -429,19 +442,28 @@ pub impl Scheduler { assert!(!self.in_task_context()); rtdebug!("looking in work queue for task to schedule"); - let mut this = self; - match this.work_queue.pop() { - Some(task) => { - rtdebug!("resuming task from work queue"); - this.resume_task_immediately(task); - return true; - } - None => { - rtdebug!("no tasks in queue"); - Local::put(this); - return false; + + if this.run_anything { + match this.work_queue.pop() { + Some(task) => { + rtdebug!("resuming task from work queue"); + this.resume_task_immediately(task); + return true; + } + None => { + rtdebug!("no tasks in queue"); + Local::put(this); + return false; + } } + } else { + // In this branch we have a scheduler that is not allowed + // to run unpinned tasks. As such it will only get tasks + // to run from the message queue. + rtdebug!("skipping resume_task_from_queue"); + Local::put(this); + return false; } } diff --git a/src/libstd/rt/test.rs b/src/libstd/rt/test.rs index 97aa76d7db6..ecef505ce57 100644 --- a/src/libstd/rt/test.rs +++ b/src/libstd/rt/test.rs @@ -157,23 +157,43 @@ pub fn run_in_mt_newsched_task_random_homed() { let mut handles = ~[]; let mut scheds = ~[]; - for uint::range(0, nthreads) |_| { + // create a few special schedulers, those with even indicies + // will be pinned-only + for uint::range(0, nthreads) |i| { + let special = (i % 2) == 0; let loop_ = ~UvEventLoop::new(); - let mut sched = ~Scheduler::new(loop_, work_queue.clone(), sleepers.clone()); + let mut sched = ~Scheduler::new_special(loop_, work_queue.clone(), sleepers.clone(), special); let handle = sched.make_handle(); handles.push(handle); scheds.push(sched); - } + } // Schedule a pile o tasks - let n = 120*stress_factor(); + let n = 5*stress_factor(); for uint::range(0,n) |_i| { rtdebug!("creating task: %u", _i); let hf: ~fn() = || { assert!(true) }; spawntask_homed(&mut scheds, hf); } - let f: ~fn() = || { assert!(true); }; + // Now we want another pile o tasks that do not ever run on a + // special scheduler, because they are normal tasks. Because + // we can we put these in the "main" task. + + let n = 5*stress_factor(); + + let f: ~fn() = || { + for uint::range(0,n) |_| { + let f: ~fn() = || { + // Borrow the scheduler we run on and check if it is + // privliged. + do Local::borrow::<Scheduler,()> |sched| { + assert!(sched.run_anything); + }; + }; + spawntask_random(f); + }; + }; let f_cell = Cell(f); let handles = Cell(handles); |
