]> git.lizzy.rs Git - rust.git/blob - src/test/bench/msgsend-ring-mutex-arcs.rs
test: Make manual changes to deal with the fallout from removal of
[rust.git] / src / test / bench / msgsend-ring-mutex-arcs.rs
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 tasks 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 extern crate sync;
19 extern crate time;
20
21 use sync::Arc;
22 use sync::MutexArc;
23 use sync::Future;
24 use std::os;
25 use std::uint;
26 use std::vec_ng::Vec;
27
28 // A poor man's pipe.
29 type pipe = MutexArc<Vec<uint> >;
30
31 fn send(p: &pipe, msg: uint) {
32     unsafe {
33         p.access_cond(|state, cond| {
34             state.push(msg);
35             cond.signal();
36         })
37     }
38 }
39 fn recv(p: &pipe) -> uint {
40     unsafe {
41         p.access_cond(|state, cond| {
42             while state.is_empty() {
43                 cond.wait();
44             }
45             state.pop().unwrap()
46         })
47     }
48 }
49
50 fn init() -> (pipe,pipe) {
51     let m = MutexArc::new(Vec::new());
52     ((&m).clone(), m)
53 }
54
55
56 fn thread_ring(i: uint, count: uint, num_chan: pipe, num_port: pipe) {
57     let mut num_chan = Some(num_chan);
58     let mut num_port = Some(num_port);
59     // Send/Receive lots of messages.
60     for j in range(0u, count) {
61         //println!("task %?, iter %?", i, j);
62         let num_chan2 = num_chan.take_unwrap();
63         let num_port2 = num_port.take_unwrap();
64         send(&num_chan2, i * j);
65         num_chan = Some(num_chan2);
66         let _n = recv(&num_port2);
67         //log(error, _n);
68         num_port = Some(num_port2);
69     };
70 }
71
72 fn main() {
73     let args = os::args();
74     let args = if os::getenv("RUST_BENCH").is_some() {
75         vec!(~"", ~"100", ~"10000")
76     } else if args.len() <= 1u {
77         vec!(~"", ~"10", ~"100")
78     } else {
79         args.clone().move_iter().collect()
80     };
81
82     let num_tasks = from_str::<uint>(*args.get(1)).unwrap();
83     let msg_per_task = from_str::<uint>(*args.get(2)).unwrap();
84
85     let (mut num_chan, num_port) = init();
86
87     let start = time::precise_time_s();
88
89     // create the ring
90     let mut futures = Vec::new();
91
92     for i in range(1u, num_tasks) {
93         //println!("spawning %?", i);
94         let (new_chan, num_port) = init();
95         let num_chan_2 = num_chan.clone();
96         let new_future = Future::spawn(proc() {
97             thread_ring(i, msg_per_task, num_chan_2, num_port)
98         });
99         futures.push(new_future);
100         num_chan = new_chan;
101     };
102
103     // do our iteration
104     thread_ring(0, msg_per_task, num_chan, num_port);
105
106     // synchronize
107     for f in futures.mut_iter() {
108         f.get()
109     }
110
111     let stop = time::precise_time_s();
112
113     // all done, report stats.
114     let num_msgs = num_tasks * msg_per_task;
115     let elapsed = (stop - start);
116     let rate = (num_msgs as f64) / elapsed;
117
118     println!("Sent {} messages in {} seconds", num_msgs, elapsed);
119     println!("  {} messages / second", rate);
120     println!("  {} μs / message", 1000000. / rate);
121 }