use std::time::Duration;
use std::rc::Rc;
use std::marker::PhantomData;
use winapi::um::processthreadsapi::{GetProcessTimes, GetThreadTimes};
use winapi::um::processthreadsapi::{GetCurrentProcess, GetCurrentThread};
use winapi::shared::minwindef::FILETIME;
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
pub struct ProcessTime(Duration);
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
pub struct ThreadTime(Duration,
PhantomData<Rc<()>>);
fn to_duration(kernel_time: FILETIME, user_time: FILETIME) -> Duration {
let kns100 = ((kernel_time.dwHighDateTime as u64) << 32) +
kernel_time.dwLowDateTime as u64;
let uns100 = ((user_time.dwHighDateTime as u64) << 32) +
user_time.dwLowDateTime as u64;
return Duration::new(
(kns100 + uns100) / 10_000_000,
(((kns100 + uns100) * 100) % 1000_000_000) as u32);
}
fn zero() -> FILETIME {
FILETIME {
dwLowDateTime: 0,
dwHighDateTime: 0,
}
}
impl ProcessTime {
pub fn now() -> ProcessTime {
let mut kernel_time = zero();
let mut user_time = zero();
let process = unsafe { GetCurrentProcess() };
let ok = unsafe { GetProcessTimes(process,
&mut zero(), &mut zero(),
&mut kernel_time, &mut user_time) };
if ok == 0 {
panic!("Can't get process times");
}
return ProcessTime(to_duration(kernel_time, user_time));
}
pub fn elapsed(&self) -> Duration {
ProcessTime::now().duration_since(*self)
}
pub fn duration_since(&self, timestamp: ProcessTime) -> Duration {
self.0 - timestamp.0
}
}
impl ThreadTime {
pub fn now() -> ThreadTime {
let mut kernel_time = zero();
let mut user_time = zero();
let thread = unsafe { GetCurrentThread() };
let ok = unsafe { GetThreadTimes(thread,
&mut zero(), &mut zero(),
&mut kernel_time, &mut user_time) };
if ok == 0 {
panic!("Can't get trhad times");
}
return ThreadTime(to_duration(kernel_time, user_time), PhantomData);
}
pub fn elapsed(&self) -> Duration {
ThreadTime::now().duration_since(*self)
}
pub fn duration_since(&self, timestamp: ThreadTime) -> Duration {
self.0 - timestamp.0
}
}