// Copyright 2012 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. // A port of the simplistic benchmark from // // http://github.com/PaulKeeble/ScalaVErlangAgents // // I *think* it's the same, more or less. use std::sync::mpsc::{channel, Sender, Receiver}; use std::os; use std::thread::Thread; use std::time::Duration; enum request { get_count, bytes(uint), stop } fn server(requests: &Receiver, responses: &Sender) { let mut count: uint = 0; let mut done = false; while !done { match requests.recv() { Ok(request::get_count) => { responses.send(count.clone()); } Ok(request::bytes(b)) => { //println!("server: received {} bytes", b); count += b; } Err(..) => { done = true; } _ => { } } } responses.send(count).unwrap(); //println!("server exiting"); } fn run(args: &[String]) { let (to_parent, from_child) = channel(); let size = args[1].parse::().unwrap(); let workers = args[2].parse::().unwrap(); let num_bytes = 100; let mut result = None; let mut to_parent = Some(to_parent); let dur = Duration::span(|| { let to_parent = to_parent.take().unwrap(); let mut worker_results = Vec::new(); let from_parent = if workers == 1 { let (to_child, from_parent) = channel(); worker_results.push(Thread::scoped(move|| { for _ in 0u..size / workers { //println!("worker {}: sending {} bytes", i, num_bytes); to_child.send(request::bytes(num_bytes)); } //println!("worker {} exiting", i); })); from_parent } else { let (to_child, from_parent) = channel(); for _ in 0u..workers { let to_child = to_child.clone(); worker_results.push(Thread::scoped(move|| { for _ in 0u..size / workers { //println!("worker {}: sending {} bytes", i, num_bytes); to_child.send(request::bytes(num_bytes)); } //println!("worker {} exiting", i); })); } from_parent }; Thread::spawn(move|| { server(&from_parent, &to_parent); }); for r in worker_results { let _ = r.join(); } //println!("sending stop message"); //to_child.send(stop); //move_out(to_child); result = Some(from_child.recv().unwrap()); }); let result = result.unwrap(); print!("Count is {}\n", result); print!("Test took {} ms\n", dur.num_milliseconds()); let thruput = ((size / workers * workers) as f64) / (dur.num_milliseconds() as f64); print!("Throughput={} per sec\n", thruput / 1000.0); assert_eq!(result, num_bytes * size); } fn main() { let args = os::args(); let args = if os::getenv("RUST_BENCH").is_some() { vec!("".to_string(), "1000000".to_string(), "8".to_string()) } else if args.len() <= 1u { vec!("".to_string(), "10000".to_string(), "4".to_string()) } else { args.clone().into_iter().map(|x| x.to_string()).collect() }; println!("{:?}", args); run(&args); }