rustix/thread/
clock.rs

1use crate::{backend, io};
2use core::fmt;
3
4pub use crate::timespec::{Nsecs, Secs, Timespec};
5
6#[cfg(not(any(
7    apple,
8    target_os = "dragonfly",
9    target_os = "espidf",
10    target_os = "freebsd", // FreeBSD 12 has clock_nanosleep, but libc targets FreeBSD 11.
11    target_os = "openbsd",
12    target_os = "redox",
13    target_os = "vita",
14    target_os = "wasi",
15)))]
16pub use crate::clockid::ClockId;
17
18/// `clock_nanosleep(id, 0, request, remain)`—Sleeps for a duration on a
19/// given clock.
20///
21/// This is `clock_nanosleep` specialized for the case of a relative sleep
22/// interval. See [`clock_nanosleep_absolute`] for absolute intervals.
23///
24/// # References
25///  - [POSIX]
26///  - [Linux]
27///
28/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/clock_nanosleep.html
29/// [Linux]: https://man7.org/linux/man-pages/man2/clock_nanosleep.2.html
30#[cfg(not(any(
31    apple,
32    target_os = "dragonfly",
33    target_os = "emscripten",
34    target_os = "espidf",
35    target_os = "freebsd", // FreeBSD 12 has clock_nanosleep, but libc targets FreeBSD 11.
36    target_os = "haiku",
37    target_os = "openbsd",
38    target_os = "redox",
39    target_os = "vita",
40    target_os = "wasi",
41)))]
42#[inline]
43pub fn clock_nanosleep_relative(id: ClockId, request: &Timespec) -> NanosleepRelativeResult {
44    backend::thread::syscalls::clock_nanosleep_relative(id, request)
45}
46
47/// `clock_nanosleep(id, TIMER_ABSTIME, request, NULL)`—Sleeps until an
48/// absolute time on a given clock.
49///
50/// This is `clock_nanosleep` specialized for the case of an absolute sleep
51/// interval. See [`clock_nanosleep_relative`] for relative intervals.
52///
53/// # References
54///  - [POSIX]
55///  - [Linux]
56///
57/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/clock_nanosleep.html
58/// [Linux]: https://man7.org/linux/man-pages/man2/clock_nanosleep.2.html
59#[cfg(not(any(
60    apple,
61    target_os = "dragonfly",
62    target_os = "emscripten",
63    target_os = "espidf",
64    target_os = "freebsd", // FreeBSD 12 has clock_nanosleep, but libc targets FreeBSD 11.
65    target_os = "haiku",
66    target_os = "openbsd",
67    target_os = "redox",
68    target_os = "vita",
69    target_os = "wasi",
70)))]
71#[inline]
72pub fn clock_nanosleep_absolute(id: ClockId, request: &Timespec) -> io::Result<()> {
73    backend::thread::syscalls::clock_nanosleep_absolute(id, request)
74}
75
76/// `nanosleep(request, remain)`—Sleeps for a duration.
77///
78/// This effectively uses the system monotonic clock.
79///
80/// # References
81///  - [POSIX]
82///  - [Linux]
83///
84/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/nanosleep.html
85/// [Linux]: https://man7.org/linux/man-pages/man2/nanosleep.2.html
86#[inline]
87pub fn nanosleep(request: &Timespec) -> NanosleepRelativeResult {
88    backend::thread::syscalls::nanosleep(request)
89}
90
91/// A return type for `nanosleep` and `clock_nanosleep_relative`.
92#[derive(Clone)]
93#[must_use]
94pub enum NanosleepRelativeResult {
95    /// The sleep completed normally.
96    Ok,
97    /// The sleep was interrupted, the remaining time is returned.
98    Interrupted(Timespec),
99    /// An invalid time value was provided.
100    Err(io::Errno),
101}
102
103impl fmt::Debug for NanosleepRelativeResult {
104    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
105        match self {
106            Self::Ok => f.write_str("Ok"),
107            Self::Interrupted(remaining) => write!(
108                f,
109                "Interrupted(Timespec {{ tv_sec: {:?}, tv_nsec: {:?} }})",
110                remaining.tv_sec, remaining.tv_nsec
111            ),
112            Self::Err(err) => write!(f, "Err({:?})", err),
113        }
114    }
115}