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}