#[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848 pubuse libc::{suseconds_t, time_t}; use libc::{timespec, timeval}; use std::time::Duration; use std::{cmp, fmt, ops};
constfn zero_init_timespec() -> timespec { // `std::mem::MaybeUninit::zeroed()` is not yet a const fn // (https://github.com/rust-lang/rust/issues/91850) so we will instead initialize an array of // the appropriate size to zero and then transmute it to a timespec value. unsafe { std::mem::transmute([0u8; std::mem::size_of::<timespec>()]) }
}
/// An enumeration allowing the definition of the expiration time of an alarm, /// recurring or not. #[derive(Debug, Clone, Copy, Eq, PartialEq)] pubenum Expiration { /// Alarm will trigger once after the time given in `TimeSpec`
OneShot(TimeSpec), /// Alarm will trigger after a specified delay and then every interval of /// time.
IntervalDelayed(TimeSpec, TimeSpec), /// Alarm will trigger every specified interval of time.
Interval(TimeSpec),
}
#[cfg(linux_android)]
bitflags! { /// Flags that are used for arming the timer. #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] pubstruct TimerSetTimeFlags: libc::c_int { const TFD_TIMER_ABSTIME = libc::TFD_TIMER_ABSTIME; const TFD_TIMER_CANCEL_ON_SET = libc::TFD_TIMER_CANCEL_ON_SET;
}
} #[cfg(any(freebsdlike, target_os = "netbsd", solarish))]
bitflags! { /// Flags that are used for arming the timer. #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] pubstruct TimerSetTimeFlags: libc::c_int { const TFD_TIMER_ABSTIME = libc::TIMER_ABSTIME;
}
}
impl Ord for TimeSpec { // The implementation of cmp is simplified by assuming that the struct is // normalized. That is, tv_nsec must always be within [0, 1_000_000_000) fn cmp(&self, other: &TimeSpec) -> cmp::Ordering { ifself.tv_sec() == other.tv_sec() { self.tv_nsec().cmp(&other.tv_nsec())
} else { self.tv_sec().cmp(&other.tv_sec())
}
}
}
impl TimeValLike for TimeSpec { #[inline] #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848 fn seconds(seconds: i64) -> TimeSpec {
assert!(
(TS_MIN_SECONDS..=TS_MAX_SECONDS).contains(&seconds), "TimeSpec out of bounds; seconds={seconds}",
); letmut ts = zero_init_timespec();
ts.tv_sec = seconds as time_t;
TimeSpec(ts)
}
#[inline] fn milliseconds(milliseconds: i64) -> TimeSpec { let nanoseconds = milliseconds
.checked_mul(1_000_000)
.expect("TimeSpec::milliseconds out of bounds");
TimeSpec::nanoseconds(nanoseconds)
}
/// Makes a new `TimeSpec` with given number of microseconds. #[inline] fn microseconds(microseconds: i64) -> TimeSpec { let nanoseconds = microseconds
.checked_mul(1_000)
.expect("TimeSpec::milliseconds out of bounds");
TimeSpec::nanoseconds(nanoseconds)
}
/// Makes a new `TimeSpec` with given number of nanoseconds. #[inline] #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848 fn nanoseconds(nanoseconds: i64) -> TimeSpec { let (secs, nanos) = div_mod_floor_64(nanoseconds, NANOS_PER_SEC);
assert!(
(TS_MIN_SECONDS..=TS_MAX_SECONDS).contains(&secs), "TimeSpec out of bounds"
); letmut ts = zero_init_timespec();
ts.tv_sec = secs as time_t;
ts.tv_nsec = nanos as timespec_tv_nsec_t;
TimeSpec(ts)
}
// The cast is not unnecessary on all platforms. #[allow(clippy::unnecessary_cast)] fn num_seconds(&self) -> i64 { ifself.tv_sec() < 0 && self.tv_nsec() > 0 {
(self.tv_sec() + 1) as i64
} else { self.tv_sec() as i64
}
}
// The cast is not unnecessary on all platforms. #[allow(clippy::unnecessary_cast)] fn num_nanoseconds(&self) -> i64 { let secs = self.num_seconds() * 1_000_000_000; let nsec = self.nanos_mod_sec();
secs + nsec as i64
}
}
impl TimeSpec { /// Leave the timestamp unchanged. #[cfg(not(target_os = "redox"))] // At the time of writing this PR, redox does not support this feature pubconst UTIME_OMIT: TimeSpec =
TimeSpec::new(0, libc::UTIME_OMIT as timespec_tv_nsec_t); /// Update the timestamp to `Now` // At the time of writing this PR, redox does not support this feature #[cfg(not(target_os = "redox"))] pubconst UTIME_NOW: TimeSpec =
TimeSpec::new(0, libc::UTIME_NOW as timespec_tv_nsec_t);
/// Construct a new `TimeSpec` from its components #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848 pubconstfn new(seconds: time_t, nanoseconds: timespec_tv_nsec_t) -> Self { letmut ts = zero_init_timespec();
ts.tv_sec = seconds;
ts.tv_nsec = nanoseconds; Self(ts)
}
impl Ord for TimeVal { // The implementation of cmp is simplified by assuming that the struct is // normalized. That is, tv_usec must always be within [0, 1_000_000) fn cmp(&self, other: &TimeVal) -> cmp::Ordering { ifself.tv_sec() == other.tv_sec() { self.tv_usec().cmp(&other.tv_usec())
} else { self.tv_sec().cmp(&other.tv_sec())
}
}
}
impl TimeValLike for TimeVal { #[inline] fn seconds(seconds: i64) -> TimeVal {
assert!(
(TV_MIN_SECONDS..=TV_MAX_SECONDS).contains(&seconds), "TimeVal out of bounds; seconds={seconds}"
); #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848
TimeVal(timeval {
tv_sec: seconds as time_t,
tv_usec: 0,
})
}
#[inline] fn milliseconds(milliseconds: i64) -> TimeVal { let microseconds = milliseconds
.checked_mul(1_000)
.expect("TimeVal::milliseconds out of bounds");
TimeVal::microseconds(microseconds)
}
/// Makes a new `TimeVal` with given number of microseconds. #[inline] fn microseconds(microseconds: i64) -> TimeVal { let (secs, micros) = div_mod_floor_64(microseconds, MICROS_PER_SEC);
assert!(
(TV_MIN_SECONDS..=TV_MAX_SECONDS).contains(&secs), "TimeVal out of bounds"
); #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848
TimeVal(timeval {
tv_sec: secs as time_t,
tv_usec: micros as suseconds_t,
})
}
/// Makes a new `TimeVal` with given number of nanoseconds. Some precision /// will be lost #[inline] fn nanoseconds(nanoseconds: i64) -> TimeVal { let microseconds = nanoseconds / 1000; let (secs, micros) = div_mod_floor_64(microseconds, MICROS_PER_SEC);
assert!(
(TV_MIN_SECONDS..=TV_MAX_SECONDS).contains(&secs), "TimeVal out of bounds"
); #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848
TimeVal(timeval {
tv_sec: secs as time_t,
tv_usec: micros as suseconds_t,
})
}
// The cast is not unnecessary on all platforms. #[allow(clippy::unnecessary_cast)] fn num_seconds(&self) -> i64 { ifself.tv_sec() < 0 && self.tv_usec() > 0 {
(self.tv_sec() + 1) as i64
} else { self.tv_sec() as i64
}
}
// The cast is not unnecessary on all platforms. #[allow(clippy::unnecessary_cast)] fn num_microseconds(&self) -> i64 { let secs = self.num_seconds() * 1_000_000; let usec = self.micros_mod_sec();
secs + usec as i64
}
#[inline] fn div_floor_64(this: i64, other: i64) -> i64 { match div_rem_64(this, other) {
(d, r) if (r > 0 && other < 0) || (r < 0 && other > 0) => d - 1,
(d, _) => d,
}
}
#[inline] fn mod_floor_64(this: i64, other: i64) -> i64 { match this % other {
r if (r > 0 && other < 0) || (r < 0 && other > 0) => r + other,
r => r,
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.