| 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())?)) | |
| } | |
| } |