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