diff options
| author | Brian Anderson <banderson@mozilla.com> | 2013-05-30 00:18:49 -0700 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2013-05-30 00:18:49 -0700 |
| commit | 053b38e7e1cba8f7bb649a5fc8d82b0448d33c55 (patch) | |
| tree | 139cb953e1aedd723324a33149279750917c6b34 /src/libstd/rt | |
| parent | 8eb358bb00f161f9e289de6cad8cfecc4c6eb681 (diff) | |
| download | rust-053b38e7e1cba8f7bb649a5fc8d82b0448d33c55.tar.gz rust-053b38e7e1cba8f7bb649a5fc8d82b0448d33c55.zip | |
core::rt: Fix two multithreading bugs and add a threadring test
This properly distributes the load now
Diffstat (limited to 'src/libstd/rt')
| -rw-r--r-- | src/libstd/rt/sched.rs | 66 | ||||
| -rw-r--r-- | src/libstd/rt/test.rs | 2 |
2 files changed, 66 insertions, 2 deletions
diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs index b5b8bb732e7..a57a87ffba7 100644 --- a/src/libstd/rt/sched.rs +++ b/src/libstd/rt/sched.rs @@ -131,6 +131,11 @@ pub impl Scheduler { let mut self_sched = self; + // Always run through the scheduler loop at least once so that + // we enter the sleep state and can then be woken up by other + // schedulers. + self_sched.event_loop.callback(Scheduler::run_sched_once); + unsafe { let event_loop: *mut ~EventLoopObject = { let event_loop: *mut ~EventLoopObject = &mut self_sched.event_loop; @@ -258,7 +263,7 @@ pub impl Scheduler { let mut handle = handle; handle.send(Wake); } - None => (/* pass */) + None => break } } } @@ -781,4 +786,63 @@ mod test { } } } + + #[test] + fn thread_ring() { + use rt::comm::*; + use iter::Times; + use vec::OwnedVector; + use container::Container; + use comm::{GenericPort, GenericChan}; + + do run_in_mt_newsched_task { + let (end_port, end_chan) = oneshot(); + + let n_tasks = 10; + let token = 2000; + + let mut (p, ch1) = stream(); + ch1.send((token, end_chan)); + let mut i = 2; + while i <= n_tasks { + let (next_p, ch) = stream(); + let imm_i = i; + let imm_p = p; + do spawntask_random { + roundtrip(imm_i, n_tasks, &imm_p, &ch); + }; + p = next_p; + i += 1; + } + let imm_p = p; + let imm_ch = ch1; + do spawntask_random { + roundtrip(1, n_tasks, &imm_p, &imm_ch); + } + + end_port.recv(); + } + + fn roundtrip(id: int, n_tasks: int, + p: &Port<(int, ChanOne<()>)>, ch: &Chan<(int, ChanOne<()>)>) { + while (true) { + match p.recv() { + (1, end_chan) => { + debug!("%d\n", id); + end_chan.send(()); + return; + } + (token, end_chan) => { + debug!("thread: %d got token: %d", id, token); + ch.send((token - 1, end_chan)); + if token <= n_tasks { + return; + } + } + } + } + } + + } + } diff --git a/src/libstd/rt/test.rs b/src/libstd/rt/test.rs index 16b0aef5e26..e05e2004e0b 100644 --- a/src/libstd/rt/test.rs +++ b/src/libstd/rt/test.rs @@ -66,7 +66,7 @@ pub fn run_in_mt_newsched_task(f: ~fn()) { let f_cell = Cell(f); do run_in_bare_thread { - static N: uint = 2; + static N: uint = 4; let sleepers = SleeperList::new(); let work_queue = WorkQueue::new(); |
