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