std::rt: Try stealing from all schedulers
This guarantees that if there is work to do it will be found
This commit is contained in:
parent
85c0fb7b8a
commit
c767643f2b
|
@ -379,21 +379,20 @@ impl Scheduler {
|
||||||
return Some(task)
|
return Some(task)
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// Our naive stealing, try kinda hard.
|
|
||||||
rtdebug!("scheduler trying to steal");
|
rtdebug!("scheduler trying to steal");
|
||||||
let len = self.work_queues.len();
|
return self.try_steals();
|
||||||
return self.try_steals(len/2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// With no backoff try stealing n times from the queues the
|
// Try stealing from all queues the scheduler knows about. This
|
||||||
// scheduler knows about. This naive implementation can steal from
|
// naive implementation can steal from our own queue or from other
|
||||||
// our own queue or from other special schedulers.
|
// special schedulers.
|
||||||
fn try_steals(&mut self, n: uint) -> Option<~Task> {
|
fn try_steals(&mut self) -> Option<~Task> {
|
||||||
for _ in range(0, n) {
|
let work_queues = &mut self.work_queues;
|
||||||
let index = self.rng.gen_uint_range(0, self.work_queues.len());
|
let len = work_queues.len();
|
||||||
let work_queues = &mut self.work_queues;
|
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() {
|
match work_queues[index].steal() {
|
||||||
Some(task) => {
|
Some(task) => {
|
||||||
rtdebug!("found task by stealing");
|
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(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue