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