| [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 | } | 
|---|