1 | use crate::{backend, io}; |
2 | use core::fmt; |
3 | |
4 | pub 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 | )))] |
16 | pub 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 ] |
43 | pub fn clock_nanosleep_relative(id: ClockId, request: &Timespec) -> NanosleepRelativeResult { |
44 | backend::thread::syscalls::clock_nanosleep_relative(id, req: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 ] |
72 | pub fn clock_nanosleep_absolute(id: ClockId, request: &Timespec) -> io::Result<()> { |
73 | backend::thread::syscalls::clock_nanosleep_absolute(id, req: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 ] |
87 | pub fn nanosleep(request: &Timespec) -> NanosleepRelativeResult { |
88 | backend::thread::syscalls::nanosleep(req:request) |
89 | } |
90 | |
91 | /// A return type for `nanosleep` and `clock_nanosleep_relative`. |
92 | #[derive (Clone)] |
93 | #[must_use ] |
94 | pub 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 | |
103 | impl fmt::Debug for NanosleepRelativeResult { |
104 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
105 | match self { |
106 | Self::Ok => f.write_str(data:"Ok" ), |
107 | Self::Interrupted(remaining: &__kernel_timespec) => write!( |
108 | f, |
109 | "Interrupted(Timespec {{ tv_sec: {:?}, tv_nsec: {:?} }})" , |
110 | remaining.tv_sec, remaining.tv_nsec |
111 | ), |
112 | Self::Err(err: &Errno) => write!(f, "Err( {:?})" , err), |
113 | } |
114 | } |
115 | } |
116 | |