#[allow(unused, reason = "±unsafe")]
use crate::{Duration, Linux, LinuxTimespec};
use crate::{LINUX_ERRNO, LinuxError, LinuxResult as Result, c_int};
#[doc = crate::_tags!(linux time)]
#[doc = crate::_doc_location!("sys/os/linux")]
#[repr(i32)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum LinuxClock {
Realtime = 0,
Monotonic = 1,
ProcessCpuTimeId = 2,
ThreadCpuTimeId = 3,
MonotonicRaw = 4,
RealtimeCoarse = 5,
MonotonicCoarse = 6,
Boottime = 7,
RealtimeAlarm = 8,
BoottimeAlarm = 9,
Tai = 11,
}
impl TryFrom<c_int> for LinuxClock {
type Error = LinuxError;
fn try_from(value: c_int) -> Result<Self> {
Self::from_raw(value).ok_or(LinuxError::Sys(LINUX_ERRNO::EINVAL))
}
}
impl From<LinuxClock> for c_int {
fn from(clock: LinuxClock) -> Self {
clock.as_raw()
}
}
impl LinuxClock {
pub const fn as_raw(self) -> c_int {
self as c_int
}
pub const fn from_raw(value: c_int) -> Option<Self> {
match value {
0 => Some(Self::Realtime),
1 => Some(Self::Monotonic),
2 => Some(Self::ProcessCpuTimeId),
3 => Some(Self::ThreadCpuTimeId),
4 => Some(Self::MonotonicRaw),
5 => Some(Self::RealtimeCoarse),
6 => Some(Self::MonotonicCoarse),
7 => Some(Self::Boottime),
8 => Some(Self::RealtimeAlarm),
9 => Some(Self::BoottimeAlarm),
11 => Some(Self::Tai),
_ => None,
}
}
}
impl LinuxClock {
pub fn is_ntp_adjusted(self) -> bool {
matches!(self, Self::Realtime | Self::RealtimeCoarse)
}
pub fn is_raw_hardware(self) -> bool {
matches!(self, Self::MonotonicRaw)
}
pub fn is_settable(self) -> bool {
!self.is_alarm()
}
pub fn is_monotonic(self) -> bool {
matches!(
self,
Self::Monotonic
| Self::MonotonicRaw
| Self::MonotonicCoarse
| Self::Boottime
| Self::BoottimeAlarm
| Self::ProcessCpuTimeId
| Self::ThreadCpuTimeId
)
}
pub fn is_realtime(self) -> bool {
matches!(self, Self::Realtime | Self::RealtimeCoarse | Self::RealtimeAlarm | Self::Tai)
}
pub fn is_cpu_time(self) -> bool {
matches!(self, Self::ProcessCpuTimeId | Self::ThreadCpuTimeId)
}
pub fn is_alarm(self) -> bool {
matches!(self, Self::RealtimeAlarm | Self::BoottimeAlarm)
}
pub fn includes_suspend_time(self) -> bool {
matches!(self, Self::Boottime | Self::BoottimeAlarm)
}
}
#[cfg_attr(nightly_doc, doc(cfg(feature = "unsafe_syscall")))]
#[cfg(all(feature = "unsafe_syscall", not(miri)))]
impl LinuxClock {
pub fn get_time(self) -> Result<LinuxTimespec> {
Linux::clock_gettime(self)
}
pub fn get_duration(self) -> Result<Duration> {
Linux::clock_gettime(self).and_then(|ts| ts.try_to_duration().map_err(Into::into))
}
pub fn get_resolution(self) -> Result<LinuxTimespec> {
Linux::clock_getres(self)
}
}
#[allow(missing_docs)]
impl LinuxClock {
pub const REALTIME: Self = Self::Realtime;
pub const MONOTONIC: Self = Self::Monotonic;
pub const PROCESS_CPUTIME_ID: Self = Self::ProcessCpuTimeId;
pub const THREAD_CPUTIME_ID: Self = Self::ThreadCpuTimeId;
pub const MONOTONIC_RAW: Self = Self::MonotonicRaw;
pub const REALTIME_COARSE: Self = Self::RealtimeCoarse;
pub const MONOTONIC_COARSE: Self = Self::MonotonicCoarse;
pub const BOOTTIME: Self = Self::Boottime;
pub const REALTIME_ALARM: Self = Self::RealtimeAlarm;
pub const BOOTTIME_ALARM: Self = Self::BoottimeAlarm;
pub const TAI: Self = Self::Tai;
}