about summary refs log tree commit diff
path: root/src/libstd/rt
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-09-21 18:31:01 -0700
committerbors <bors@rust-lang.org>2013-09-21 18:31:01 -0700
commit11f68f51f0d2dfc94450a6caa9f5582285e31205 (patch)
tree3a7419ad6b845f7dbad83c3b28b9d6d36e806e62 /src/libstd/rt
parent635a38189694e71dc9dd267f208c0a8bc8b0c7f1 (diff)
parentc767643f2b7f3b47b98acf424ceaf6826c0475bc (diff)
downloadrust-11f68f51f0d2dfc94450a6caa9f5582285e31205.tar.gz
rust-11f68f51f0d2dfc94450a6caa9f5582285e31205.zip
auto merge of #9353 : brson/rust/sched, r=alexcrichton,cmr
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(());
+            }
+        }
+    }
 }