From 178882d54c16460059431fa303d2597ad4f5d132 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Mon, 23 Mar 2026 17:41:19 +0000 Subject: [PATCH] Use common Timestamp impl in Hermit (attempt 2) --- library/std/src/sys/fs/hermit.rs | 6 +- library/std/src/sys/pal/hermit/mod.rs | 1 + library/std/src/sys/pal/hermit/time.rs | 110 ------------------------- library/std/src/sys/pal/unix/time.rs | 3 +- library/std/src/sys/time/hermit.rs | 22 ++--- 5 files changed, 17 insertions(+), 125 deletions(-) delete mode 100644 library/std/src/sys/pal/hermit/time.rs diff --git a/library/std/src/sys/fs/hermit.rs b/library/std/src/sys/fs/hermit.rs index 1e281eb0d9d18..5992766b5a42d 100644 --- a/library/std/src/sys/fs/hermit.rs +++ b/library/std/src/sys/fs/hermit.rs @@ -109,15 +109,15 @@ pub struct DirBuilder { impl FileAttr { pub fn modified(&self) -> io::Result { - Ok(SystemTime::new(self.stat_val.st_mtim.tv_sec, self.stat_val.st_mtim.tv_nsec)) + SystemTime::new(self.stat_val.st_mtim.tv_sec, self.stat_val.st_mtim.tv_nsec.into()) } pub fn accessed(&self) -> io::Result { - Ok(SystemTime::new(self.stat_val.st_atim.tv_sec, self.stat_val.st_atim.tv_nsec)) + SystemTime::new(self.stat_val.st_atim.tv_sec, self.stat_val.st_atim.tv_nsec.into()) } pub fn created(&self) -> io::Result { - Ok(SystemTime::new(self.stat_val.st_ctim.tv_sec, self.stat_val.st_ctim.tv_nsec)) + SystemTime::new(self.stat_val.st_ctim.tv_sec, self.stat_val.st_ctim.tv_nsec.into()) } pub fn size(&self) -> u64 { diff --git a/library/std/src/sys/pal/hermit/mod.rs b/library/std/src/sys/pal/hermit/mod.rs index b18dc5b103b59..53f6ddd7065d7 100644 --- a/library/std/src/sys/pal/hermit/mod.rs +++ b/library/std/src/sys/pal/hermit/mod.rs @@ -22,6 +22,7 @@ use crate::os::raw::c_char; use crate::sys::env; pub mod futex; +#[path = "../unix/time.rs"] pub mod time; pub fn unsupported() -> io::Result { diff --git a/library/std/src/sys/pal/hermit/time.rs b/library/std/src/sys/pal/hermit/time.rs deleted file mode 100644 index b9851eb6754d6..0000000000000 --- a/library/std/src/sys/pal/hermit/time.rs +++ /dev/null @@ -1,110 +0,0 @@ -use hermit_abi::{self, timespec}; - -use crate::cmp::Ordering; -use crate::hash::{Hash, Hasher}; -use crate::time::Duration; - -const NSEC_PER_SEC: i32 = 1_000_000_000; - -#[derive(Copy, Clone, Debug)] -pub struct Timespec { - pub t: timespec, -} - -impl Timespec { - pub const MAX: Timespec = Self::new(i64::MAX, 1_000_000_000 - 1); - - pub const MIN: Timespec = Self::new(i64::MIN, 0); - - pub const fn zero() -> Timespec { - Timespec { t: timespec { tv_sec: 0, tv_nsec: 0 } } - } - - pub const fn new(tv_sec: i64, tv_nsec: i32) -> Timespec { - assert!(tv_nsec >= 0 && tv_nsec < NSEC_PER_SEC); - // SAFETY: The assert above checks tv_nsec is within the valid range - Timespec { t: timespec { tv_sec, tv_nsec } } - } - - pub fn sub_timespec(&self, other: &Timespec) -> Result { - fn sub_ge_to_unsigned(a: i64, b: i64) -> u64 { - debug_assert!(a >= b); - a.wrapping_sub(b).cast_unsigned() - } - - if self >= other { - // Logic here is identical to Unix version of `Timestamp::sub_timespec`, - // check comments there why operations do not overflow. - Ok(if self.t.tv_nsec >= other.t.tv_nsec { - Duration::new( - sub_ge_to_unsigned(self.t.tv_sec, other.t.tv_sec), - (self.t.tv_nsec - other.t.tv_nsec) as u32, - ) - } else { - Duration::new( - sub_ge_to_unsigned(self.t.tv_sec - 1, other.t.tv_sec), - (self.t.tv_nsec + NSEC_PER_SEC - other.t.tv_nsec) as u32, - ) - }) - } else { - match other.sub_timespec(self) { - Ok(d) => Err(d), - Err(d) => Ok(d), - } - } - } - - pub fn checked_add_duration(&self, other: &Duration) -> Option { - let mut secs = self.t.tv_sec.checked_add_unsigned(other.as_secs())?; - - // Nano calculations can't overflow because nanos are <1B which fit - // in a u32. - let mut nsec = other.subsec_nanos() + u32::try_from(self.t.tv_nsec).unwrap(); - if nsec >= NSEC_PER_SEC.try_into().unwrap() { - nsec -= u32::try_from(NSEC_PER_SEC).unwrap(); - secs = secs.checked_add(1)?; - } - Some(Timespec { t: timespec { tv_sec: secs, tv_nsec: nsec as _ } }) - } - - pub fn checked_sub_duration(&self, other: &Duration) -> Option { - let mut secs = self.t.tv_sec.checked_sub_unsigned(other.as_secs())?; - - // Similar to above, nanos can't overflow. - let mut nsec = self.t.tv_nsec as i32 - other.subsec_nanos() as i32; - if nsec < 0 { - nsec += NSEC_PER_SEC as i32; - secs = secs.checked_sub(1)?; - } - Some(Timespec { t: timespec { tv_sec: secs, tv_nsec: nsec as _ } }) - } -} - -impl PartialEq for Timespec { - fn eq(&self, other: &Timespec) -> bool { - self.t.tv_sec == other.t.tv_sec && self.t.tv_nsec == other.t.tv_nsec - } -} - -impl Eq for Timespec {} - -impl PartialOrd for Timespec { - fn partial_cmp(&self, other: &Timespec) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for Timespec { - fn cmp(&self, other: &Timespec) -> Ordering { - let me = (self.t.tv_sec, self.t.tv_nsec); - let other = (other.t.tv_sec, other.t.tv_nsec); - me.cmp(&other) - } -} - -impl Hash for Timespec { - fn hash(&self, state: &mut H) { - self.t.tv_sec.hash(state); - self.t.tv_nsec.hash(state); - } -} diff --git a/library/std/src/sys/pal/unix/time.rs b/library/std/src/sys/pal/unix/time.rs index fbea94ec84e79..9acc7786b2edd 100644 --- a/library/std/src/sys/pal/unix/time.rs +++ b/library/std/src/sys/pal/unix/time.rs @@ -17,7 +17,7 @@ pub(in crate::sys) const TIMESPEC_MAX_CAPPED: libc::timespec = libc::timespec { tv_nsec: (u64::MAX % NSEC_PER_SEC) as i64, }; -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] pub(crate) struct Timespec { pub tv_sec: i64, pub tv_nsec: Nanoseconds, @@ -66,6 +66,7 @@ impl Timespec { } } + #[allow(dead_code)] pub fn now(clock: libc::clockid_t) -> Timespec { use crate::mem::MaybeUninit; use crate::sys::cvt; diff --git a/library/std/src/sys/time/hermit.rs b/library/std/src/sys/time/hermit.rs index 18ece2e3010d0..8e8a656ab61ee 100644 --- a/library/std/src/sys/time/hermit.rs +++ b/library/std/src/sys/time/hermit.rs @@ -1,18 +1,21 @@ use hermit_abi::{self, CLOCK_MONOTONIC, CLOCK_REALTIME}; -use crate::hash::Hash; +use crate::io; use crate::sys::pal::time::Timespec; use crate::time::Duration; +fn clock_gettime(clock: hermit_abi::clockid_t) -> Timespec { + let mut t = hermit_abi::timespec { tv_sec: 0, tv_nsec: 0 }; + let _ = unsafe { hermit_abi::clock_gettime(clock, &raw mut t) }; + Timespec::new(t.tv_sec, t.tv_nsec.into()).unwrap() +} + #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] pub struct Instant(Timespec); impl Instant { pub fn now() -> Instant { - let mut time: Timespec = Timespec::zero(); - let _ = unsafe { hermit_abi::clock_gettime(CLOCK_MONOTONIC, &raw mut time.t) }; - - Instant(time) + Instant(clock_gettime(CLOCK_MONOTONIC)) } pub fn checked_sub_instant(&self, other: &Instant) -> Option { @@ -38,15 +41,12 @@ impl SystemTime { pub const MIN: SystemTime = SystemTime(Timespec::MIN); - pub fn new(tv_sec: i64, tv_nsec: i32) -> SystemTime { - SystemTime(Timespec::new(tv_sec, tv_nsec)) + pub fn new(tv_sec: i64, tv_nsec: i64) -> Result { + Ok(SystemTime(Timespec::new(tv_sec, tv_nsec)?)) } pub fn now() -> SystemTime { - let mut time: Timespec = Timespec::zero(); - let _ = unsafe { hermit_abi::clock_gettime(CLOCK_REALTIME, &raw mut time.t) }; - - SystemTime(time) + SystemTime(clock_gettime(CLOCK_REALTIME)) } pub fn sub_time(&self, other: &SystemTime) -> Result {