use crate::ffi::misc as raw;
use crate::ffi::types::*;
use crate::error::{OsError, Result};
pub use crate::ffi::types::{
CLOCK_REALTIME,
CLOCK_MONOTONIC,
CLOCK_MONOTONIC_RAW,
CLOCK_PROCESS_CPUTIME_ID,
CLOCK_THREAD_CPUTIME_ID,
};
pub fn clock_gettime(clk: clockid_t) -> Result<(i64, i64)> {
let mut ts = Timespec { tv_sec: 0, tv_nsec: 0 };
let r = unsafe { raw::clock_gettime(clk, &mut ts) };
if r < 0 { Err(OsError::last()) } else { Ok((ts.tv_sec as i64, ts.tv_nsec as i64)) }
}
#[inline]
pub fn monotonic_ns() -> Result<u64> {
let (s, ns) = clock_gettime(CLOCK_MONOTONIC)?;
Ok(s as u64 * 1_000_000_000 + ns as u64)
}
#[inline]
pub fn thread_cpu_ns() -> Result<u64> {
let (s, ns) = clock_gettime(CLOCK_THREAD_CPUTIME_ID)?;
Ok(s as u64 * 1_000_000_000 + ns as u64)
}
#[inline]
pub fn realtime() -> Result<(i64, i64)> {
clock_gettime(CLOCK_REALTIME)
}
#[inline]
pub fn realtime_secs() -> Result<i64> {
clock_gettime(CLOCK_REALTIME).map(|(s, _)| s)
}
pub fn sleep_ns(ns: u64) -> Result<()> {
let mut req = Timespec {
tv_sec: (ns / 1_000_000_000) as i64,
tv_nsec: (ns % 1_000_000_000) as i64,
};
loop {
let mut rem = Timespec { tv_sec: 0, tv_nsec: 0 };
let r = unsafe { raw::nanosleep(&req, &mut rem) };
if r == 0 { return Ok(()); }
let e = OsError::last();
if e.is_interrupted() {
req = rem;
continue;
}
return Err(e);
}
}
#[inline]
pub fn sleep_ms(ms: u64) -> Result<()> { sleep_ns(ms * 1_000_000) }
pub fn gettimeofday() -> Result<(i64, i32)> {
let mut tv = Timeval::default();
let r = unsafe { raw::gettimeofday(&mut tv, core::ptr::null_mut()) };
if r < 0 { Err(OsError::last()) } else { Ok((tv.tv_sec as i64, tv.tv_usec as i32)) }
}