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}