diff options
Diffstat (limited to 'library/std/src/sys/cloudabi/time.rs')
-rw-r--r-- | library/std/src/sys/cloudabi/time.rs | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/library/std/src/sys/cloudabi/time.rs b/library/std/src/sys/cloudabi/time.rs new file mode 100644 index 00000000000..c209231cf8c --- /dev/null +++ b/library/std/src/sys/cloudabi/time.rs @@ -0,0 +1,82 @@ +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 }; |