diff --git a/V2/sleep/Cargo.lock b/V2/sleep/Cargo.lock index c5f4c43..8acea86 100644 --- a/V2/sleep/Cargo.lock +++ b/V2/sleep/Cargo.lock @@ -2,10 +2,16 @@ name = "sleep" version = "0.1.0" dependencies = [ + "argparse 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "shuteye 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "argparse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "kernel32-sys" version = "0.2.2" @@ -52,6 +58,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] +"checksum argparse 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37bb99f5e39ee8b23b6e227f5b8f024207e8616f44aa4b8c76ecd828011667ef" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "88ee81885f9f04bff991e306fea7c1c60a5f0f9e409e99f6b40e3311a3363135" "checksum redox_syscall 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "29dbdfd4b9df8ab31dec47c6087b7b13cbf4a776f335e4de8efba8288dda075b" diff --git a/V2/sleep/Cargo.toml b/V2/sleep/Cargo.toml index 30c2dfa..04986f4 100644 --- a/V2/sleep/Cargo.toml +++ b/V2/sleep/Cargo.toml @@ -4,6 +4,6 @@ version = "0.1.0" authors = ["Simon Wörner "] [dependencies] -# libc = ">=0.2.21" +argparse = ">=0.2.1" shuteye = ">=0.2.0" time = ">=0.1.36" diff --git a/V2/sleep/src/main.rs b/V2/sleep/src/main.rs index 10f8fef..895a51e 100644 --- a/V2/sleep/src/main.rs +++ b/V2/sleep/src/main.rs @@ -1,22 +1,49 @@ +#![feature(step_by)] +extern crate argparse; extern crate shuteye; extern crate time; +use std::io::prelude::*; +use std::fs::File; +use std::path::Path; use std::time::Duration; + +use argparse::{ArgumentParser, Print, Store}; use shuteye::sleep; use time::precise_time_ns; +fn duration_from_ns(duration_ns: u64) -> Duration { + Duration::new(duration_ns / 1_000_000_000, (duration_ns % 1_000_000_000) as u32) +} +fn duration_to_ns(duration: Duration) -> u64 { + duration.as_secs() * 1_000_000_000u64 + duration.subsec_nanos() as u64 +} + fn measure_duration(sleep_duration: Duration) -> Duration { let start = precise_time_ns(); - sleep(sleep_duration); + let remain = sleep(sleep_duration); let end = precise_time_ns(); + #[cfg(debug_assertions)] + println!("remain = {:?}", remain); + let duration = end - start; - Duration::new(duration / 1_000_000_000, (duration % 1_000_000_000) as u32) + let duration = duration_from_ns(duration); + + #[cfg(debug_assertions)] + println!("duration = {:?}", duration); + + duration } fn measure_delay(sleep_duration: Duration) -> (Duration, Duration) { let duration = measure_duration(sleep_duration); - (duration, duration - sleep_duration) + let delay = duration - sleep_duration; + + #[cfg(debug_assertions)] + println!("delay = {:?}", delay); + + (duration, delay) } fn measure_delay_loop(sleep_duration: Duration, count: u64) -> Vec<(Duration, Duration)> { @@ -29,32 +56,76 @@ fn measure_delay_loop(sleep_duration: Duration, count: u64) -> Vec<(Duration, Du for _ in 0..count { let (duration, delay) = measure_delay(sleep_duration); data.push((duration, delay)); - println!("value: {} s {} ns\tdelay: {} s {} ns\trelativ delay = {:.2}%\traw_data: {:?}", - duration.as_secs(), - duration.subsec_nanos(), - delay.as_secs(), - delay.subsec_nanos(), - (delay.subsec_nanos() * 100) as f64 / duration.subsec_nanos() as f64, - delay); + + #[cfg(debug_assertions)] + print_delay(duration, delay); } data } -fn main() { - println!("Hello, world!"); - - let data = measure_delay_loop(Duration::new(0, 10_000_000), 100); - println!("{:?}", data); - - /*let sleep_time = 5000; - println!("sleep_time = {}", sleep_time); - - let start = precise_time_ns(); - sleep(Duration::from_millis(5000)); - let end = precise_time_ns(); - let diff = end-start; - - println!("start = {}ms\nend = {}\ndiff = {}", start, end, diff); - println!("diff - sleep_time = {}", diff - sleep_time * 1000 * 1000);*/ +fn print_delay(duration: Duration, delay: Duration) { + println!("value: {} s {} ns\tdelay: {} s {} ns\trelativ delay = {:.2}%\traw_data: {:?}", + duration.as_secs(), + duration.subsec_nanos(), + delay.as_secs(), + delay.subsec_nanos(), + (delay.subsec_nanos() * 100) as f64 / duration.subsec_nanos() as f64, + delay); +} + +fn main() { + let mut min: u64 = 1_000_000; + let mut max: u64 = 100_000_000; + let mut step: u64 = 1_000_000; + let mut count: u64 = 100; + let mut output: String = "".to_string(); + let mut file: Option = None; + + { + let mut ap = ArgumentParser::new(); + ap.set_description(env!("CARGO_PKG_DESCRIPTION")); + ap.refer(&mut min) + .add_option(&["--min"], Store, + "Sleep period start"); + ap.refer(&mut max) + .add_option(&["--max"], Store, + "Sleep period end"); + ap.refer(&mut step) + .add_option(&["--step"], Store, + "Sleep period step size"); + ap.refer(&mut count) + .add_option(&["--loop"], Store, + "Count of measurements per period"); + ap.refer(&mut output) + .add_option(&["-o", "--out"], Store, + "Output file"); + ap.add_option(&["-V", "--version"], + Print(env!("CARGO_PKG_VERSION").to_string()), "Show version"); + ap.parse_args_or_exit(); + } + + if output != "" { + file = Some(File::create(Path::new(output.as_str())) + .expect(format!("Open file '{}' failed", output).as_str())); + } + + for duration in (min..max+1).step_by(step) { + let data = measure_delay_loop(duration_from_ns(duration), count); + let max_delay = data.iter().max().expect("Max delay not found"); + + #[cfg(debug_assertions)] + println!("max_delay = {:?}", max_delay); + + print_delay(max_delay.0, max_delay.1); + + match file.as_ref() { + Some(mut f) => { + let value = format!("{: >9} {}\n", duration, duration_to_ns(max_delay.1)); + f.write_all(value.as_bytes()) + .expect(format!("Write value '{}' to '{}' file failed", value, output).as_str()); + } + None => {} + } + } }