about summary refs log tree commit diff
path: root/src/libstd/rt
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2013-09-04 16:54:05 -0700
committerBrian Anderson <banderson@mozilla.com>2013-09-19 19:48:58 -0700
commitc767643f2b7f3b47b98acf424ceaf6826c0475bc (patch)
tree2b606bba5adf27315593f7fb5e3395624bd346df /src/libstd/rt
parent85c0fb7b8a81fc48a2155decd20abf16b1c5eeb6 (diff)
downloadrust-c767643f2b7f3b47b98acf424ceaf6826c0475bc.tar.gz
rust-c767643f2b7f3b47b98acf424ceaf6826c0475bc.zip
std::rt: Try stealing from all schedulers
This guarantees that if there is work to do it will be found
Diffstat (limited to 'src/libstd/rt')
-rw-r--r--src/libstd/rt/sched.rs37
1 files changed, 27 insertions, 10 deletions
diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs
index 854fdadfb00..22888d79984 100644
--- a/src/libstd/rt/sched.rs
+++ b/src/libstd/rt/sched.rs
@@ -379,21 +379,20 @@ impl Scheduler {
                 return Some(task)
             }
             None => {
-                // Our naive stealing, try kinda hard.
                 rtdebug!("scheduler trying to steal");
-                let len = self.work_queues.len();
-                return self.try_steals(len/2);
+                return self.try_steals();
             }
         }
     }
 
-    // With no backoff try stealing n times from the queues the
-    // scheduler knows about. This naive implementation can steal from
-    // our own queue or from other special schedulers.
-    fn try_steals(&mut self, n: uint) -> Option<~Task> {
-        for _ in range(0, n) {
-            let index = self.rng.gen_uint_range(0, self.work_queues.len());
-            let work_queues = &mut self.work_queues;
+    // Try stealing from all queues the scheduler knows about. This
+    // naive implementation can steal from our own queue or from other
+    // special schedulers.
+    fn try_steals(&mut self) -> Option<~Task> {
+        let work_queues = &mut self.work_queues;
+        let len = work_queues.len();
+        let start_index = self.rng.gen_uint_range(0, len);
+        for index in range(0, len).map(|i| (i + start_index) % len) {
             match work_queues[index].steal() {
                 Some(task) => {
                     rtdebug!("found task by stealing");
@@ -1213,4 +1212,22 @@ mod test {
         }
     }
 
+    #[test]
+    fn dont_starve_1() {
+        use rt::comm::oneshot;
+
+        do stress_factor().times {
+            do run_in_mt_newsched_task {
+                let (port, chan) = oneshot();
+
+                // This task should not be able to starve the sender;
+                // The sender should get stolen to another thread.
+                do spawntask {
+                    while !port.peek() { }
+                }
+
+                chan.send(());
+            }
+        }
+    }
 }