Files
hyperfine/src/timer/windows_timer.rs
T

82 lines
2.3 KiB
Rust
Raw Normal View History

2018-02-05 18:22:59 -05:00
#![cfg(windows)]
use std::mem;
use std::os::windows::io::{AsRawHandle, RawHandle};
use std::process::Child;
2018-02-05 18:22:59 -05:00
2021-08-24 21:33:48 +02:00
use winapi::um::processthreadsapi::GetProcessTimes;
use winapi::um::winnt::HANDLE;
2021-08-24 21:48:10 +02:00
use crate::timer::{CPUTimes, TimerStart, TimerStop};
2022-02-06 20:01:41 +01:00
use crate::util::units::Second;
2021-08-24 21:33:48 +02:00
2018-02-05 18:22:59 -05:00
const HUNDRED_NS_PER_MS: i64 = 10;
2020-01-04 11:12:49 +01:00
pub fn get_cpu_timer(process: &Child) -> Box<dyn TimerStop<Result = (Second, Second)>> {
Box::new(CPUTimer::start_for_process(process))
2018-02-05 18:22:59 -05:00
}
struct CPUTimer {
2018-02-05 18:22:59 -05:00
handle: RawHandle,
}
impl TimerStart for CPUTimer {
fn start() -> Self {
panic!()
2018-02-05 18:22:59 -05:00
}
fn start_for_process(process: &Child) -> Self {
CPUTimer {
handle: process.as_raw_handle(),
}
}
}
impl TimerStop for CPUTimer {
type Result = (Second, Second);
2018-02-05 18:22:59 -05:00
fn stop(&self) -> Self::Result {
let times = get_cpu_times(self.handle);
(
times.user_usec as f64 * 1e-6,
times.system_usec as f64 * 1e-6,
)
2018-02-05 18:22:59 -05:00
}
}
2022-02-22 10:08:15 +01:00
/// Read CPU execution times
2018-02-05 18:22:59 -05:00
fn get_cpu_times(handle: RawHandle) -> CPUTimes {
let (user_usec, system_usec) = unsafe {
let mut _ctime = mem::zeroed();
let mut _etime = mem::zeroed();
let mut kernel_time = mem::zeroed();
let mut user_time = mem::zeroed();
let res = GetProcessTimes(
handle as HANDLE,
&mut _ctime,
&mut _etime,
&mut kernel_time,
&mut user_time,
);
// GetProcessTimes will exit with non-zero if success as per: https://msdn.microsoft.com/en-us/library/windows/desktop/ms683223(v=vs.85).aspx
if res != 0 {
// Extract times as laid out here: https://support.microsoft.com/en-us/help/188768/info-working-with-the-filetime-structure
// Both user_time and kernel_time are spans that the proces spent in either.
let user: i64 = (((user_time.dwHighDateTime as i64) << 32)
2019-10-02 18:56:55 +05:45
+ 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;
2018-02-05 18:22:59 -05:00
(user, kernel)
} else {
(0, 0)
}
};
CPUTimes {
user_usec,
system_usec,
2018-02-05 18:22:59 -05:00
}
}