blob: fa929c67241e34dbbf744aa58ff783d880c87049 [file] [log] [blame]
use crate::mem::MaybeUninit;
use crate::sys::pal::error::expect_success;
use crate::sys::pal::{abi, itron};
use crate::time::Duration;
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
pub struct Instant(itron::abi::SYSTIM);
impl Instant {
pub fn now() -> Instant {
Instant(itron::time::get_tim())
}
pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> {
self.0.checked_sub(other.0).map(|ticks| {
// `SYSTIM` is measured in microseconds
Duration::from_micros(ticks)
})
}
pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
// `SYSTIM` is measured in microseconds
let ticks = other.as_micros();
Some(Instant(self.0.checked_add(ticks.try_into().ok()?)?))
}
pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
// `SYSTIM` is measured in microseconds
let ticks = other.as_micros();
Some(Instant(self.0.checked_sub(ticks.try_into().ok()?)?))
}
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
pub struct SystemTime(abi::time_t);
pub const UNIX_EPOCH: SystemTime = SystemTime(0);
impl SystemTime {
pub const MAX: SystemTime = SystemTime(abi::time_t::MAX);
pub const MIN: SystemTime = SystemTime(abi::time_t::MIN);
pub fn now() -> SystemTime {
let rtc = unsafe {
let mut out = MaybeUninit::zeroed();
expect_success(abi::SOLID_RTC_ReadTime(out.as_mut_ptr()), &"SOLID_RTC_ReadTime");
out.assume_init()
};
let t = unsafe {
libc::mktime(&mut libc::tm {
tm_sec: rtc.tm_sec,
tm_min: rtc.tm_min,
tm_hour: rtc.tm_hour,
tm_mday: rtc.tm_mday,
tm_mon: rtc.tm_mon - 1,
tm_year: rtc.tm_year,
tm_wday: rtc.tm_wday,
tm_yday: 0,
tm_isdst: 0,
tm_gmtoff: 0,
tm_zone: crate::ptr::null_mut(),
})
};
assert_ne!(t, -1, "mktime failed");
SystemTime(t)
}
pub fn from_time_t(t: abi::time_t) -> Self {
Self(t)
}
pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
if self.0 >= other.0 {
Ok(Duration::from_secs((self.0 as u64).wrapping_sub(other.0 as u64)))
} else {
Err(Duration::from_secs((other.0 as u64).wrapping_sub(self.0 as u64)))
}
}
pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime(self.0.checked_add_unsigned(other.as_secs())?))
}
pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime(self.0.checked_sub_unsigned(other.as_secs())?))
}
}