rustix/
clockid.rs

1use crate::backend::c;
2use crate::fd::BorrowedFd;
3use crate::io;
4
5/// `CLOCK_*` constants for use with [`clock_gettime`].
6///
7/// These constants are always supported at runtime, so `clock_gettime` never
8/// has to fail with `INVAL` due to an unsupported clock. See
9/// [`DynamicClockId`] for a greater set of clocks, with the caveat that not
10/// all of them are always supported.
11///
12/// [`clock_gettime`]: crate::time::clock_gettime
13#[cfg(not(any(apple, target_os = "wasi")))]
14#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
15#[cfg_attr(
16    not(any(target_os = "aix", target_os = "cygwin", target_os = "dragonfly")),
17    repr(i32)
18)]
19#[cfg_attr(any(target_os = "cygwin", target_os = "dragonfly"), repr(u64))]
20#[cfg_attr(target_os = "aix", repr(i64))]
21#[non_exhaustive]
22pub enum ClockId {
23    /// `CLOCK_REALTIME`
24    #[doc(alias = "CLOCK_REALTIME")]
25    Realtime = bitcast!(c::CLOCK_REALTIME),
26
27    /// `CLOCK_MONOTONIC`
28    #[doc(alias = "CLOCK_MONOTONIC")]
29    Monotonic = bitcast!(c::CLOCK_MONOTONIC),
30
31    /// `CLOCK_UPTIME`
32    ///
33    /// On FreeBSD, this is an alias for [`Self::Boottime`].
34    ///
35    /// On OpenBSD, this differs from `Self::Boottime`; it only advances when
36    /// the system is not suspended.
37    ///
38    /// [`Self::Uptime`]: https://docs.rs/rustix/*/x86_64-unknown-freebsd/rustix/time/enum.ClockId.html#variant.Uptime
39    #[cfg(any(freebsdlike, target_os = "openbsd"))]
40    #[doc(alias = "CLOCK_UPTIME")]
41    Uptime = c::CLOCK_UPTIME,
42
43    /// `CLOCK_PROCESS_CPUTIME_ID`
44    #[cfg(not(any(
45        solarish,
46        target_os = "horizon",
47        target_os = "netbsd",
48        target_os = "redox",
49        target_os = "vita"
50    )))]
51    #[doc(alias = "CLOCK_PROCESS_CPUTIME_ID")]
52    ProcessCPUTime = c::CLOCK_PROCESS_CPUTIME_ID,
53
54    /// `CLOCK_THREAD_CPUTIME_ID`
55    #[cfg(not(any(
56        solarish,
57        target_os = "horizon",
58        target_os = "netbsd",
59        target_os = "redox",
60        target_os = "vita"
61    )))]
62    #[doc(alias = "CLOCK_THREAD_CPUTIME_ID")]
63    ThreadCPUTime = c::CLOCK_THREAD_CPUTIME_ID,
64
65    /// `CLOCK_REALTIME_COARSE`
66    #[cfg(any(linux_kernel, target_os = "freebsd"))]
67    #[doc(alias = "CLOCK_REALTIME_COARSE")]
68    RealtimeCoarse = c::CLOCK_REALTIME_COARSE,
69
70    /// `CLOCK_MONOTONIC_COARSE`
71    #[cfg(any(linux_kernel, target_os = "freebsd"))]
72    #[doc(alias = "CLOCK_MONOTONIC_COARSE")]
73    MonotonicCoarse = c::CLOCK_MONOTONIC_COARSE,
74
75    /// `CLOCK_MONOTONIC_RAW`
76    #[cfg(linux_kernel)]
77    #[doc(alias = "CLOCK_MONOTONIC_RAW")]
78    MonotonicRaw = c::CLOCK_MONOTONIC_RAW,
79
80    /// `CLOCK_REALTIME_ALARM`
81    #[cfg(linux_kernel)]
82    #[doc(alias = "CLOCK_REALTIME_ALARM")]
83    RealtimeAlarm = bitcast!(c::CLOCK_REALTIME_ALARM),
84
85    /// `CLOCK_TAI`, available on Linux ≥ 3.10
86    #[cfg(all(linux_kernel, feature = "linux_4_11"))]
87    #[doc(alias = "CLOCK_TAI")]
88    Tai = bitcast!(c::CLOCK_TAI),
89
90    /// `CLOCK_BOOTTIME`
91    #[cfg(any(linux_kernel, target_os = "fuchsia", target_os = "openbsd"))]
92    #[doc(alias = "CLOCK_BOOTTIME")]
93    Boottime = bitcast!(c::CLOCK_BOOTTIME),
94
95    /// `CLOCK_BOOTTIME_ALARM`
96    #[cfg(any(linux_kernel, target_os = "fuchsia"))]
97    #[doc(alias = "CLOCK_BOOTTIME_ALARM")]
98    BoottimeAlarm = bitcast!(c::CLOCK_BOOTTIME_ALARM),
99}
100
101#[cfg(not(any(apple, target_os = "wasi")))]
102impl TryFrom<c::clockid_t> for ClockId {
103    type Error = io::Errno;
104
105    fn try_from(value: c::clockid_t) -> Result<Self, Self::Error> {
106        match value {
107            c::CLOCK_REALTIME => Ok(ClockId::Realtime),
108            c::CLOCK_MONOTONIC => Ok(ClockId::Monotonic),
109            #[cfg(any(freebsdlike, target_os = "openbsd"))]
110            c::CLOCK_UPTIME => Ok(ClockId::Uptime),
111            #[cfg(not(any(
112                solarish,
113                target_os = "horizon",
114                target_os = "netbsd",
115                target_os = "redox",
116                target_os = "vita"
117            )))]
118            c::CLOCK_PROCESS_CPUTIME_ID => Ok(ClockId::ProcessCPUTime),
119            #[cfg(not(any(
120                solarish,
121                target_os = "horizon",
122                target_os = "netbsd",
123                target_os = "redox",
124                target_os = "vita"
125            )))]
126            c::CLOCK_THREAD_CPUTIME_ID => Ok(ClockId::ThreadCPUTime),
127            #[cfg(any(linux_kernel, target_os = "freebsd"))]
128            c::CLOCK_REALTIME_COARSE => Ok(ClockId::RealtimeCoarse),
129            #[cfg(any(linux_kernel, target_os = "freebsd"))]
130            c::CLOCK_MONOTONIC_COARSE => Ok(ClockId::MonotonicCoarse),
131            #[cfg(linux_kernel)]
132            c::CLOCK_MONOTONIC_RAW => Ok(ClockId::MonotonicRaw),
133            #[cfg(linux_kernel)]
134            c::CLOCK_REALTIME_ALARM => Ok(ClockId::RealtimeAlarm),
135            #[cfg(all(linux_kernel, feature = "linux_4_11"))]
136            c::CLOCK_TAI => Ok(ClockId::Tai),
137            #[cfg(any(linux_kernel, target_os = "fuchsia", target_os = "openbsd"))]
138            c::CLOCK_BOOTTIME => Ok(ClockId::Boottime),
139            #[cfg(any(linux_kernel, target_os = "fuchsia"))]
140            c::CLOCK_BOOTTIME_ALARM => Ok(ClockId::BoottimeAlarm),
141            _ => Err(io::Errno::RANGE),
142        }
143    }
144}
145
146/// `CLOCK_*` constants for use with [`clock_gettime`].
147///
148/// These constants are always supported at runtime, so `clock_gettime` never
149/// has to fail with `INVAL` due to an unsupported clock. See
150/// [`DynamicClockId`] for a greater set of clocks, with the caveat that not
151/// all of them are always supported.
152///
153/// [`clock_gettime`]: crate::time::clock_gettime
154#[cfg(apple)]
155#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
156#[repr(u32)]
157#[non_exhaustive]
158pub enum ClockId {
159    /// `CLOCK_REALTIME`
160    #[doc(alias = "CLOCK_REALTIME")]
161    Realtime = c::CLOCK_REALTIME,
162
163    /// `CLOCK_MONOTONIC`
164    #[doc(alias = "CLOCK_MONOTONIC")]
165    Monotonic = c::CLOCK_MONOTONIC,
166
167    /// `CLOCK_PROCESS_CPUTIME_ID`
168    #[doc(alias = "CLOCK_PROCESS_CPUTIME_ID")]
169    ProcessCPUTime = c::CLOCK_PROCESS_CPUTIME_ID,
170
171    /// `CLOCK_THREAD_CPUTIME_ID`
172    #[doc(alias = "CLOCK_THREAD_CPUTIME_ID")]
173    ThreadCPUTime = c::CLOCK_THREAD_CPUTIME_ID,
174}
175
176#[cfg(apple)]
177impl TryFrom<c::clockid_t> for ClockId {
178    type Error = io::Errno;
179
180    fn try_from(value: c::clockid_t) -> Result<Self, Self::Error> {
181        match value {
182            c::CLOCK_REALTIME => Ok(ClockId::Realtime),
183            c::CLOCK_MONOTONIC => Ok(ClockId::Monotonic),
184            c::CLOCK_PROCESS_CPUTIME_ID => Ok(ClockId::ProcessCPUTime),
185            c::CLOCK_THREAD_CPUTIME_ID => Ok(ClockId::ThreadCPUTime),
186            _ => Err(io::Errno::RANGE),
187        }
188    }
189}
190
191/// `CLOCK_*` constants for use with [`clock_gettime_dynamic`].
192///
193/// These constants may be unsupported at runtime, depending on the OS version,
194/// and `clock_gettime_dynamic` may fail with `INVAL`. See [`ClockId`] for
195/// clocks which are always supported at runtime.
196///
197/// [`clock_gettime_dynamic`]: crate::time::clock_gettime_dynamic
198#[cfg(not(target_os = "wasi"))]
199#[derive(Debug, Copy, Clone)]
200#[non_exhaustive]
201pub enum DynamicClockId<'a> {
202    /// `ClockId` values that are always supported at runtime.
203    Known(ClockId),
204
205    /// Linux dynamic clocks.
206    Dynamic(BorrowedFd<'a>),
207
208    /// `CLOCK_REALTIME_ALARM`
209    #[cfg(any(linux_kernel, target_os = "fuchsia"))]
210    #[doc(alias = "CLOCK_REALTIME_ALARM")]
211    RealtimeAlarm,
212
213    /// `CLOCK_TAI`, available on Linux ≥ 3.10
214    #[cfg(linux_kernel)]
215    #[doc(alias = "CLOCK_TAI")]
216    Tai,
217
218    /// `CLOCK_BOOTTIME`
219    #[cfg(any(
220        linux_kernel,
221        target_os = "freebsd",
222        target_os = "fuchsia",
223        target_os = "openbsd"
224    ))]
225    #[doc(alias = "CLOCK_BOOTTIME")]
226    Boottime,
227
228    /// `CLOCK_BOOTTIME_ALARM`
229    #[cfg(any(linux_kernel, target_os = "fuchsia"))]
230    #[doc(alias = "CLOCK_BOOTTIME_ALARM")]
231    BoottimeAlarm,
232}