]>
Commit | Line | Data |
---|---|---|
223e47cc LB |
1 | // Copyright 2012 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
bd371182 | 11 | // This test creates a bunch of threads that simultaneously send to each |
223e47cc LB |
12 | // other in a ring. The messages should all be basically |
13 | // independent. | |
1a4d82fc | 14 | // This is like msgsend-ring-pipes but adapted to use Arcs. |
223e47cc | 15 | |
1a4d82fc | 16 | // This also serves as a pipes test, because Arcs are implemented with pipes. |
223e47cc | 17 | |
1a4d82fc | 18 | // no-pretty-expanded FIXME #15189 |
970d7e83 | 19 | |
d9579d0f | 20 | #![feature(duration, duration_span, std_misc)] |
c34b1796 | 21 | |
85aaf69f | 22 | use std::env; |
1a4d82fc JJ |
23 | use std::sync::{Arc, Future, Mutex, Condvar}; |
24 | use std::time::Duration; | |
223e47cc LB |
25 | |
26 | // A poor man's pipe. | |
c34b1796 | 27 | type pipe = Arc<(Mutex<Vec<usize>>, Condvar)>; |
223e47cc | 28 | |
c34b1796 | 29 | fn send(p: &pipe, msg: usize) { |
1a4d82fc JJ |
30 | let &(ref lock, ref cond) = &**p; |
31 | let mut arr = lock.lock().unwrap(); | |
32 | arr.push(msg); | |
33 | cond.notify_one(); | |
223e47cc | 34 | } |
c34b1796 | 35 | fn recv(p: &pipe) -> usize { |
1a4d82fc JJ |
36 | let &(ref lock, ref cond) = &**p; |
37 | let mut arr = lock.lock().unwrap(); | |
38 | while arr.is_empty() { | |
39 | arr = cond.wait(arr).unwrap(); | |
223e47cc | 40 | } |
1a4d82fc | 41 | arr.pop().unwrap() |
223e47cc LB |
42 | } |
43 | ||
44 | fn init() -> (pipe,pipe) { | |
1a4d82fc | 45 | let m = Arc::new((Mutex::new(Vec::new()), Condvar::new())); |
223e47cc LB |
46 | ((&m).clone(), m) |
47 | } | |
48 | ||
49 | ||
c34b1796 | 50 | fn thread_ring(i: usize, count: usize, num_chan: pipe, num_port: pipe) { |
223e47cc LB |
51 | let mut num_chan = Some(num_chan); |
52 | let mut num_port = Some(num_port); | |
53 | // Send/Receive lots of messages. | |
85aaf69f | 54 | for j in 0..count { |
bd371182 | 55 | //println!("thread %?, iter %?", i, j); |
1a4d82fc JJ |
56 | let num_chan2 = num_chan.take().unwrap(); |
57 | let num_port2 = num_port.take().unwrap(); | |
223e47cc LB |
58 | send(&num_chan2, i * j); |
59 | num_chan = Some(num_chan2); | |
60 | let _n = recv(&num_port2); | |
61 | //log(error, _n); | |
62 | num_port = Some(num_port2); | |
63 | }; | |
64 | } | |
65 | ||
66 | fn main() { | |
85aaf69f SL |
67 | let args = env::args(); |
68 | let args = if env::var_os("RUST_BENCH").is_some() { | |
1a4d82fc | 69 | vec!("".to_string(), "100".to_string(), "10000".to_string()) |
85aaf69f | 70 | } else if args.len() <= 1 { |
1a4d82fc | 71 | vec!("".to_string(), "10".to_string(), "100".to_string()) |
223e47cc | 72 | } else { |
85aaf69f | 73 | args.collect() |
970d7e83 | 74 | }; |
223e47cc | 75 | |
c34b1796 AL |
76 | let num_tasks = args[1].parse::<usize>().unwrap(); |
77 | let msg_per_task = args[2].parse::<usize>().unwrap(); | |
223e47cc | 78 | |
85aaf69f | 79 | let (num_chan, num_port) = init(); |
223e47cc | 80 | |
1a4d82fc JJ |
81 | let mut p = Some((num_chan, num_port)); |
82 | let dur = Duration::span(|| { | |
83 | let (mut num_chan, num_port) = p.take().unwrap(); | |
223e47cc | 84 | |
1a4d82fc JJ |
85 | // create the ring |
86 | let mut futures = Vec::new(); | |
223e47cc | 87 | |
85aaf69f | 88 | for i in 1..num_tasks { |
1a4d82fc JJ |
89 | //println!("spawning %?", i); |
90 | let (new_chan, num_port) = init(); | |
91 | let num_chan_2 = num_chan.clone(); | |
92 | let new_future = Future::spawn(move|| { | |
93 | thread_ring(i, msg_per_task, num_chan_2, num_port) | |
94 | }); | |
95 | futures.push(new_future); | |
96 | num_chan = new_chan; | |
223e47cc | 97 | }; |
223e47cc | 98 | |
1a4d82fc JJ |
99 | // do our iteration |
100 | thread_ring(0, msg_per_task, num_chan, num_port); | |
223e47cc | 101 | |
1a4d82fc | 102 | // synchronize |
85aaf69f | 103 | for f in &mut futures { |
1a4d82fc JJ |
104 | f.get() |
105 | } | |
106 | }); | |
223e47cc LB |
107 | |
108 | // all done, report stats. | |
109 | let num_msgs = num_tasks * msg_per_task; | |
d9579d0f | 110 | let rate = (num_msgs as f64) / (dur.secs() as f64); |
223e47cc | 111 | |
d9579d0f AL |
112 | println!("Sent {} messages in {}", num_msgs, dur); |
113 | println!(" {} messages / second", rate); | |
114 | println!(" {} μs / message", 1000000. / rate); | |
223e47cc | 115 | } |