]>
Commit | Line | Data |
---|---|---|
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 | ||
11 | // This test creates a bunch of threads that simultaneously send to each | |
12 | // other in a ring. The messages should all be basically | |
13 | // independent. | |
14 | // This is like msgsend-ring-pipes but adapted to use Arcs. | |
15 | ||
16 | // This also serves as a pipes test, because Arcs are implemented with pipes. | |
17 | ||
18 | // no-pretty-expanded FIXME #15189 | |
19 | ||
20 | #![feature(duration, duration_span, std_misc)] | |
21 | ||
22 | use std::env; | |
23 | use std::sync::{Arc, Future, Mutex, Condvar}; | |
24 | use std::time::Duration; | |
25 | ||
26 | // A poor man's pipe. | |
27 | type pipe = Arc<(Mutex<Vec<usize>>, Condvar)>; | |
28 | ||
29 | fn send(p: &pipe, msg: usize) { | |
30 | let &(ref lock, ref cond) = &**p; | |
31 | let mut arr = lock.lock().unwrap(); | |
32 | arr.push(msg); | |
33 | cond.notify_one(); | |
34 | } | |
35 | fn recv(p: &pipe) -> usize { | |
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(); | |
40 | } | |
41 | arr.pop().unwrap() | |
42 | } | |
43 | ||
44 | fn init() -> (pipe,pipe) { | |
45 | let m = Arc::new((Mutex::new(Vec::new()), Condvar::new())); | |
46 | ((&m).clone(), m) | |
47 | } | |
48 | ||
49 | ||
50 | fn thread_ring(i: usize, count: usize, num_chan: pipe, num_port: pipe) { | |
51 | let mut num_chan = Some(num_chan); | |
52 | let mut num_port = Some(num_port); | |
53 | // Send/Receive lots of messages. | |
54 | for j in 0..count { | |
55 | //println!("thread %?, iter %?", i, j); | |
56 | let num_chan2 = num_chan.take().unwrap(); | |
57 | let num_port2 = num_port.take().unwrap(); | |
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() { | |
67 | let args = env::args(); | |
68 | let args = if env::var_os("RUST_BENCH").is_some() { | |
69 | vec!("".to_string(), "100".to_string(), "10000".to_string()) | |
70 | } else if args.len() <= 1 { | |
71 | vec!("".to_string(), "10".to_string(), "100".to_string()) | |
72 | } else { | |
73 | args.collect() | |
74 | }; | |
75 | ||
76 | let num_tasks = args[1].parse::<usize>().unwrap(); | |
77 | let msg_per_task = args[2].parse::<usize>().unwrap(); | |
78 | ||
79 | let (num_chan, num_port) = init(); | |
80 | ||
81 | let mut p = Some((num_chan, num_port)); | |
82 | let dur = Duration::span(|| { | |
83 | let (mut num_chan, num_port) = p.take().unwrap(); | |
84 | ||
85 | // create the ring | |
86 | let mut futures = Vec::new(); | |
87 | ||
88 | for i in 1..num_tasks { | |
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; | |
97 | }; | |
98 | ||
99 | // do our iteration | |
100 | thread_ring(0, msg_per_task, num_chan, num_port); | |
101 | ||
102 | // synchronize | |
103 | for f in &mut futures { | |
104 | f.get() | |
105 | } | |
106 | }); | |
107 | ||
108 | // all done, report stats. | |
109 | let num_msgs = num_tasks * msg_per_task; | |
110 | let rate = (num_msgs as f64) / (dur.secs() as f64); | |
111 | ||
112 | println!("Sent {} messages in {}", num_msgs, dur); | |
113 | println!(" {} messages / second", rate); | |
114 | println!(" {} μs / message", 1000000. / rate); | |
115 | } |