use std::io::{Result, Error};
use std::marker::PhantomData;
use std::rc::Rc;
use std::time::Duration;
use libc::{clock_gettime, timespec};
use libc::{CLOCK_PROCESS_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID};
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
pub struct ProcessTime(Duration);
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
pub struct ThreadTime(
Duration,
PhantomData<Rc<()>>,
);
impl ProcessTime {
pub fn try_now() -> Result<Self> {
let mut time = timespec {
tv_sec: 0,
tv_nsec: 0,
};
if unsafe { clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &mut time) } == -1
{
return Err(Error::last_os_error());
}
Ok(ProcessTime(Duration::new(
time.tv_sec as u64,
time.tv_nsec as u32,
)))
}
pub fn now() -> Self {
Self::try_now().expect("CLOCK_PROCESS_CPUTIME_ID unsupported")
}
pub fn try_elapsed(&self) -> Result<Duration> {
Ok(Self::try_now()?.duration_since(*self))
}
pub fn elapsed(&self) -> Duration {
Self::now().duration_since(*self)
}
pub fn duration_since(&self, timestamp: Self) -> Duration {
self.0 - timestamp.0
}
pub fn as_duration(&self) -> Duration {
self.0
}
}
impl ThreadTime {
pub fn try_now() -> Result<Self> {
let mut time = timespec {
tv_sec: 0,
tv_nsec: 0,
};
if unsafe { clock_gettime(CLOCK_THREAD_CPUTIME_ID, &mut time) } == -1
{
return Err(Error::last_os_error());
}
Ok(ThreadTime(
Duration::new(time.tv_sec as u64, time.tv_nsec as u32),
PhantomData,
))
}
pub fn now() -> Self {
Self::try_now().expect("CLOCK_PROCESS_CPUTIME_ID unsupported")
}
pub fn try_elapsed(&self) -> Result<Duration> {
Ok(ThreadTime::try_now()?.duration_since(*self))
}
pub fn elapsed(&self) -> Duration {
Self::now().duration_since(*self)
}
pub fn duration_since(&self, timestamp: ThreadTime) -> Duration {
self.0 - timestamp.0
}
pub fn as_duration(&self) -> Duration {
self.0
}
}