std: move time implementations to sys (Solid)

On SOLID, the conversion functions are also used to implement helpers for
timeout conversion, so these stay in the PAL. The `Instant` (µITRON) and
`SystemTime` (SOLID-specific) implementations are merged into one. While it was
nice to have the µITRON parts in a separate module, there really isn't a need
for this currently, as there is no other µITRON target. Let's not worry about
this until such a target gets added...

Note that I've extracted the `get_tim` call from `Instant` into a wrapper
function in the PAL to avoid the need to make the inner `Instant` field public
for use in the PAL.
This commit is contained in:
joboet 2026-01-15 14:47:05 +01:00
parent 5978e19456
commit bd754c7119
No known key found for this signature in database
GPG key ID: 704E0149B0194B3C
4 changed files with 47 additions and 40 deletions

View file

@ -3,38 +3,16 @@ use super::error::expect_success;
use crate::mem::MaybeUninit;
use crate::time::Duration;
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
pub struct Instant(abi::SYSTIM);
#[cfg(test)]
mod tests;
impl Instant {
pub fn now() -> Instant {
// Safety: The provided pointer is valid
unsafe {
let mut out = MaybeUninit::uninit();
expect_success(abi::get_tim(out.as_mut_ptr()), &"get_tim");
Instant(out.assume_init())
}
}
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()?)?))
#[inline]
pub fn get_tim() -> abi::SYSTIM {
// Safety: The provided pointer is valid
unsafe {
let mut out = MaybeUninit::uninit();
expect_success(abi::get_tim(out.as_mut_ptr()), &"get_tim");
out.assume_init()
}
}
@ -98,7 +76,7 @@ pub fn with_tmos_strong(dur: Duration, mut f: impl FnMut(abi::TMO) -> abi::ER) -
// a problem in practice. (`u64::MAX` μs ≈ 584942 years)
let ticks = dur.as_micros().min(abi::SYSTIM::MAX as u128) as abi::SYSTIM;
let start = Instant::now().0;
let start = get_tim();
let mut elapsed = 0;
let mut er = abi::E_TMOUT;
while elapsed <= ticks {
@ -106,11 +84,8 @@ pub fn with_tmos_strong(dur: Duration, mut f: impl FnMut(abi::TMO) -> abi::ER) -
if er != abi::E_TMOUT {
break;
}
elapsed = Instant::now().0.wrapping_sub(start);
elapsed = get_tim().wrapping_sub(start);
}
er
}
#[cfg(test)]
mod tests;

View file

@ -21,7 +21,6 @@ pub mod itron {
pub(crate) mod error;
pub mod os;
pub use self::itron::thread_parking;
pub mod time;
// SAFETY: must be called only once during runtime initialization.
// NOTE: this is not guaranteed to run, for example when Rust code is called externally.

View file

@ -6,6 +6,10 @@ cfg_select! {
mod sgx;
use sgx as imp;
}
target_os = "solid_asp3" => {
mod solid;
use solid as imp;
}
target_os = "vexos" => {
mod vexos;
#[expect(unused)]

View file

@ -1,9 +1,38 @@
use super::abi;
use super::error::expect_success;
pub use super::itron::time::Instant;
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);