diff --git a/Cargo.lock b/Cargo.lock index 9d8cbe5..80ffa8d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -104,6 +104,7 @@ dependencies = [ "indicatif 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "statistical 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 5614cca..c012bb8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,9 @@ atty = "0.2.2" [target.'cfg(not(target_os = "windows"))'.dependencies] libc = "0.2" +[target.'cfg(target_os = "windows")'.dependencies] +winapi = { version = "0.3.4", features = [ "processthreadsapi", "minwindef", "winnt"] } + [dependencies.clap] version = "2" default-features = false diff --git a/src/hyperfine/timer/cputimer.rs b/src/hyperfine/timer/cputimer.rs index 0ad3c38..a8b4c43 100644 --- a/src/hyperfine/timer/cputimer.rs +++ b/src/hyperfine/timer/cputimer.rs @@ -45,9 +45,50 @@ fn get_cpu_times() -> CPUTimes { /// Read CPU execution times (dummy for now) #[cfg(windows)] fn get_cpu_times() -> CPUTimes { + use winapi::um::processthreadsapi::{GetCurrentProcess, GetProcessTimes}; + use winapi::shared::minwindef::FILETIME; + + // Winapi reports times as per 100 nanosecond + const HUNDRED_NS_PER_MS: i64 = 10; + let mut _ctime = FILETIME { + dwLowDateTime: 0, + dwHighDateTime: 0, + }; + let mut _etime = FILETIME { + dwLowDateTime: 0, + dwHighDateTime: 0, + }; + let mut kernel_time = FILETIME { + dwLowDateTime: 0, + dwHighDateTime: 0, + }; + let mut user_time = FILETIME { + dwLowDateTime: 0, + dwHighDateTime: 0, + }; + + let (user_usec, system_usec) = unsafe { + let handle = GetCurrentProcess(); + let res = GetProcessTimes( + handle, + &mut _ctime, + &mut _etime, + &mut kernel_time, + &mut user_time, + ); + // Extract times as laid out here: https://support.microsoft.com/en-us/help/188768/info-working-with-the-filetime-structure + if res != 0 { + let user: i64 = (((user_time.dwHighDateTime as i64) << 32) + user_time.dwLowDateTime as i64) / HUNDRED_NS_PER_MS; + let kernel: i64 = (((kernel_time.dwHighDateTime as i64) << 32) + kernel_time.dwLowDateTime as i64) / HUNDRED_NS_PER_MS; + (user, kernel) + } else { + (0, 0) + } + }; + CPUTimes { - user_usec: 0, - system_usec: 0, + user_usec, + system_usec, } } diff --git a/src/main.rs b/src/main.rs index 9808d2d..65e3b43 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,6 +8,9 @@ extern crate statistical; #[cfg(not(target_os = "windows"))] extern crate libc; +#[cfg(target_os = "windows")] +extern crate winapi; + #[cfg(test)] #[macro_use] extern crate approx;