| [751e2eb] | 1 | use std::io::{self, Write};
 | 
|---|
| [821c534] | 2 | use std::option;
 | 
|---|
| [751e2eb] | 3 | use std::sync::atomic::{AtomicU64, AtomicBool, Ordering};
 | 
|---|
 | 4 | use std::time::{Instant,Duration};
 | 
|---|
| [821c534] | 5 | use std::u128;
 | 
|---|
| [751e2eb] | 6 | 
 | 
|---|
 | 7 | use clap::{Arg, ArgMatches};
 | 
|---|
 | 8 | use isatty::stdout_isatty;
 | 
|---|
 | 9 | 
 | 
|---|
 | 10 | use tokio::time;
 | 
|---|
 | 11 | 
 | 
|---|
 | 12 | 
 | 
|---|
 | 13 | // ==================================================
 | 
|---|
 | 14 | pub fn args<'a, 'b>() -> [Arg<'a, 'b>; 4] {[
 | 
|---|
 | 15 |         Arg::with_name("duration")  .short("d").long("duration")  .takes_value(true).default_value("5").help("Duration of the experiments in seconds"),
 | 
|---|
 | 16 |         Arg::with_name("iterations").short("i").long("iterations").takes_value(true).conflicts_with("duration").help("Number of iterations of the experiments"),
 | 
|---|
 | 17 |         Arg::with_name("nthreads")  .short("t").long("nthreads")  .takes_value(true).default_value("1").help("Number of threads to use"),
 | 
|---|
 | 18 |         Arg::with_name("nprocs")    .short("p").long("nprocs")    .takes_value(true).default_value("1").help("Number of processors to use")
 | 
|---|
 | 19 | ]}
 | 
|---|
 | 20 | 
 | 
|---|
 | 21 | pub struct BenchData {
 | 
|---|
 | 22 |         pub clock_mode: bool,
 | 
|---|
 | 23 |         pub stop: AtomicBool,
 | 
|---|
 | 24 |         pub stop_count: u64,
 | 
|---|
 | 25 |         pub duration: f64,
 | 
|---|
 | 26 |         pub threads_left: AtomicU64,
 | 
|---|
 | 27 |         is_tty: bool,
 | 
|---|
 | 28 | }
 | 
|---|
 | 29 | 
 | 
|---|
 | 30 | impl BenchData {
 | 
|---|
| [821c534] | 31 |         pub fn new(options: ArgMatches, nthreads: usize, default_it: option::Option<u64>) -> BenchData {
 | 
|---|
| [751e2eb] | 32 |                 let (clock_mode, stop_count, duration) = if options.is_present("iterations") {
 | 
|---|
 | 33 |                         (false,
 | 
|---|
 | 34 |                         options.value_of("iterations").unwrap().parse::<u64>().unwrap(),
 | 
|---|
 | 35 |                         -1.0)
 | 
|---|
| [821c534] | 36 |                 } else if !default_it.is_none() {
 | 
|---|
 | 37 |                         (false,
 | 
|---|
 | 38 |                         default_it.unwrap(),
 | 
|---|
 | 39 |                         -1.0)
 | 
|---|
| [751e2eb] | 40 |                 } else {
 | 
|---|
 | 41 |                         (true,
 | 
|---|
 | 42 |                         std::u64::MAX,
 | 
|---|
 | 43 |                         options.value_of("duration").unwrap().parse::<f64>().unwrap())
 | 
|---|
 | 44 |                 };
 | 
|---|
 | 45 | 
 | 
|---|
 | 46 |                 BenchData{
 | 
|---|
 | 47 |                         clock_mode: clock_mode,
 | 
|---|
 | 48 |                         stop: AtomicBool::new(false),
 | 
|---|
 | 49 |                         stop_count: stop_count,
 | 
|---|
 | 50 |                         duration: duration,
 | 
|---|
 | 51 |                         threads_left: AtomicU64::new(nthreads as u64),
 | 
|---|
 | 52 |                         is_tty: stdout_isatty(),
 | 
|---|
 | 53 |                 }
 | 
|---|
 | 54 |         }
 | 
|---|
 | 55 | 
 | 
|---|
| [821c534] | 56 |         #[allow(dead_code)]
 | 
|---|
| [751e2eb] | 57 |         pub async fn wait(&self, start: &Instant) -> Duration{
 | 
|---|
 | 58 |                 loop {
 | 
|---|
 | 59 |                         time::sleep(Duration::from_micros(100000)).await;
 | 
|---|
 | 60 |                         let delta = start.elapsed();
 | 
|---|
 | 61 |                         if self.is_tty {
 | 
|---|
 | 62 |                                 print!(" {:.1}\r", delta.as_secs_f32());
 | 
|---|
 | 63 |                                 io::stdout().flush().unwrap();
 | 
|---|
 | 64 |                         }
 | 
|---|
 | 65 |                         if self.clock_mode && delta >= Duration::from_secs_f64(self.duration)  {
 | 
|---|
 | 66 |                                 break;
 | 
|---|
 | 67 |                         }
 | 
|---|
 | 68 |                         else if !self.clock_mode && self.threads_left.load(Ordering::Relaxed) == 0 {
 | 
|---|
 | 69 |                                 break;
 | 
|---|
 | 70 |                         }
 | 
|---|
 | 71 |                 }
 | 
|---|
 | 72 | 
 | 
|---|
 | 73 |                 self.stop.store(true, Ordering::SeqCst);
 | 
|---|
 | 74 |                 return start.elapsed();
 | 
|---|
 | 75 |         }
 | 
|---|
 | 76 | }
 | 
|---|
 | 77 | 
 | 
|---|
| [821c534] | 78 | // ==================================================
 | 
|---|
 | 79 | pub fn _lehmer64( state: &mut u128 ) -> u64 {
 | 
|---|
 | 80 |         *state = state.wrapping_mul(0xda942042e4dd58b5);
 | 
|---|
 | 81 |         return (*state >> 64) as u64;
 | 
|---|
 | 82 | }
 | 
|---|