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(()); + } + } + } }