cap_time_ext/system_clock.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
#[cfg(not(windows))]
use rustix::time::{clock_getres, ClockId};
use std::time::{self, Duration};
/// Extension trait for `cap_std::time::SystemClock`.
pub trait SystemClockExt {
/// A system clock datapoint.
type SystemTime;
/// Similar to `SystemClock::now`, but takes an additional `precision`
/// parameter allowing callers to inform the implementation when they
/// don't need full precision. The implementation need not make any
/// effort to provide a time with greater precision.
fn now_with(&self, precision: Duration) -> Self::SystemTime;
/// Return the resolution of the clock.
fn resolution(&self) -> Duration;
}
#[cfg(not(windows))]
impl SystemClockExt for cap_primitives::time::SystemClock {
type SystemTime = cap_primitives::time::SystemTime;
#[cfg(not(target_os = "wasi"))]
#[inline]
fn now_with(&self, _precision: Duration) -> Self::SystemTime {
// On systems with no optimized form of `clock_gettime`, ignore the
// precision argument.
Self::SystemTime::from_std(time::SystemTime::now())
}
fn resolution(&self) -> Duration {
let spec = clock_getres(ClockId::Realtime);
Duration::new(
spec.tv_sec.try_into().unwrap(),
spec.tv_nsec.try_into().unwrap(),
)
}
}
#[cfg(windows)]
impl SystemClockExt for cap_primitives::time::SystemClock {
type SystemTime = cap_primitives::time::SystemTime;
#[inline]
fn now_with(&self, _precision: Duration) -> Self::SystemTime {
// On systems with no optimized form of `clock_gettime`, ignore the
// precision argument.
Self::SystemTime::from_std(time::SystemTime::now())
}
fn resolution(&self) -> Duration {
// According to [this blog post], the system timer resolution is 55ms
// or 10ms. Use the more conservative of the two.
//
// [this blog post]: https://devblogs.microsoft.com/oldnewthing/20170921-00/?p=97057
Duration::new(0, 55_000_000)
}
}