| use crate::mem; |
| use crate::sys::cloudabi::abi; |
| use crate::time::Duration; |
| |
| const NSEC_PER_SEC: abi::timestamp = 1_000_000_000; |
| |
| #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] |
| pub struct Instant { |
| t: abi::timestamp, |
| } |
| |
| pub fn checked_dur2intervals(dur: &Duration) -> Option<abi::timestamp> { |
| dur.as_secs().checked_mul(NSEC_PER_SEC)?.checked_add(dur.subsec_nanos() as abi::timestamp) |
| } |
| |
| impl Instant { |
| pub fn now() -> Instant { |
| unsafe { |
| let mut t: mem::MaybeUninit<abi::timestamp> = mem::MaybeUninit::uninit(); |
| let ret = abi::clock_time_get(abi::clockid::MONOTONIC, 0, t.as_mut_ptr()); |
| assert_eq!(ret, abi::errno::SUCCESS); |
| Instant { t: t.assume_init() } |
| } |
| } |
| |
| pub fn actually_monotonic() -> bool { |
| true |
| } |
| |
| pub const fn zero() -> Instant { |
| Instant { t: 0 } |
| } |
| |
| pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> { |
| let diff = self.t.checked_sub(other.t)?; |
| Some(Duration::new(diff / NSEC_PER_SEC, (diff % NSEC_PER_SEC) as u32)) |
| } |
| |
| pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> { |
| Some(Instant { t: self.t.checked_add(checked_dur2intervals(other)?)? }) |
| } |
| |
| pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> { |
| Some(Instant { t: self.t.checked_sub(checked_dur2intervals(other)?)? }) |
| } |
| } |
| |
| #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] |
| pub struct SystemTime { |
| t: abi::timestamp, |
| } |
| |
| impl SystemTime { |
| pub fn now() -> SystemTime { |
| unsafe { |
| let mut t: mem::MaybeUninit<abi::timestamp> = mem::MaybeUninit::uninit(); |
| let ret = abi::clock_time_get(abi::clockid::REALTIME, 0, t.as_mut_ptr()); |
| assert_eq!(ret, abi::errno::SUCCESS); |
| SystemTime { t: t.assume_init() } |
| } |
| } |
| |
| pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> { |
| if self.t >= other.t { |
| let diff = self.t - other.t; |
| Ok(Duration::new(diff / NSEC_PER_SEC, (diff % NSEC_PER_SEC) as u32)) |
| } else { |
| let diff = other.t - self.t; |
| Err(Duration::new(diff / NSEC_PER_SEC, (diff % NSEC_PER_SEC) as u32)) |
| } |
| } |
| |
| pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> { |
| Some(SystemTime { t: self.t.checked_add(checked_dur2intervals(other)?)? }) |
| } |
| |
| pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> { |
| Some(SystemTime { t: self.t.checked_sub(checked_dur2intervals(other)?)? }) |
| } |
| } |
| |
| pub const UNIX_EPOCH: SystemTime = SystemTime { t: 0 }; |