|
16 | 16 | │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
17 | 17 | │ PERFORMANCE OF THIS SOFTWARE. │
|
18 | 18 | ╚─────────────────────────────────────────────────────────────────────────────*/
|
19 |
| -#include "libc/assert.h" |
20 |
| -#include "libc/calls/cp.internal.h" |
21 |
| -#include "libc/calls/internal.h" |
22 | 19 | #include "libc/calls/struct/timespec.h"
|
23 |
| -#include "libc/calls/struct/timespec.internal.h" |
24 | 20 | #include "libc/dce.h"
|
25 | 21 | #include "libc/errno.h"
|
26 |
| -#include "libc/intrin/describeflags.internal.h" |
27 |
| -#include "libc/intrin/kprintf.h" |
28 |
| -#include "libc/intrin/strace.internal.h" |
29 |
| -#include "libc/intrin/weaken.h" |
30 |
| -#include "libc/runtime/clktck.h" |
31 |
| -#include "libc/runtime/runtime.h" |
32 |
| -#include "libc/sysv/consts/clock.h" |
33 | 22 | #include "libc/sysv/consts/timer.h"
|
34 |
| -#include "libc/sysv/errfuns.h" |
35 |
| -#include "libc/thread/thread.h" |
36 |
| - |
37 |
| -static int sys_clock_nanosleep(int clock, int flags, // |
38 |
| - const struct timespec *req, |
39 |
| - struct timespec *rem) { |
40 |
| - int rc; |
41 |
| - BEGIN_CANCELATION_POINT; |
42 |
| - if (IsLinux() || IsFreebsd() || IsNetbsd()) { |
43 |
| - rc = __sys_clock_nanosleep(clock, flags, req, rem); |
44 |
| - } else if (IsXnu()) { |
45 |
| - rc = sys_clock_nanosleep_xnu(clock, flags, req, rem); |
46 |
| - } else if (IsOpenbsd()) { |
47 |
| - rc = sys_clock_nanosleep_openbsd(clock, flags, req, rem); |
48 |
| - } else if (IsWindows()) { |
49 |
| - rc = sys_clock_nanosleep_nt(clock, flags, req, rem); |
50 |
| - } else { |
51 |
| - rc = enosys(); |
52 |
| - } |
53 |
| - if (rc > 0) { |
54 |
| - errno = rc; |
55 |
| - rc = -1; |
56 |
| - } |
57 |
| - // system call support might not detect cancelation on bsds |
58 |
| - if (rc == -1 && errno == EINTR && // |
59 |
| - _weaken(pthread_testcancel_np) && // |
60 |
| - _weaken(pthread_testcancel_np)()) { |
61 |
| - rc = ecanceled(); |
62 |
| - } |
63 |
| - END_CANCELATION_POINT; |
64 |
| - STRACE("sys_clock_nanosleep(%s, %s, %s, [%s]) → %d% m", |
65 |
| - DescribeClockName(clock), DescribeSleepFlags(flags), |
66 |
| - DescribeTimespec(0, req), DescribeTimespec(rc, rem), rc); |
67 |
| - return rc; |
68 |
| -} |
69 |
| - |
70 |
| -static int cosmo_clock_nanosleep(int clock, int flags, |
71 |
| - const struct timespec *req, |
72 |
| - struct timespec *rem) { |
73 |
| - |
74 |
| - // pick clocks |
75 |
| - int time_clock; |
76 |
| - int sleep_clock; |
77 |
| - if (clock == CLOCK_REALTIME || // |
78 |
| - clock == CLOCK_REALTIME_PRECISE) { |
79 |
| - time_clock = clock; |
80 |
| - sleep_clock = CLOCK_REALTIME; |
81 |
| - } else if (clock == CLOCK_MONOTONIC || // |
82 |
| - clock == CLOCK_MONOTONIC_PRECISE) { |
83 |
| - time_clock = clock; |
84 |
| - sleep_clock = CLOCK_MONOTONIC; |
85 |
| - } else if (clock == CLOCK_REALTIME_COARSE || // |
86 |
| - clock == CLOCK_REALTIME_FAST) { |
87 |
| - return sys_clock_nanosleep(CLOCK_REALTIME, flags, req, rem); |
88 |
| - } else if (clock == CLOCK_MONOTONIC_COARSE || // |
89 |
| - clock == CLOCK_MONOTONIC_FAST) { |
90 |
| - return sys_clock_nanosleep(CLOCK_MONOTONIC, flags, req, rem); |
91 |
| - } else { |
92 |
| - return sys_clock_nanosleep(clock, flags, req, rem); |
93 |
| - } |
94 |
| - |
95 |
| - // sleep bulk of time in kernel |
96 |
| - struct timespec start, deadline, remain, waitfor, now; |
97 |
| - struct timespec quantum = timespec_fromnanos(1000000000 / CLK_TCK); |
98 |
| - unassert(!clock_gettime(time_clock, &start)); |
99 |
| - deadline = flags & TIMER_ABSTIME ? *req : timespec_add(start, *req); |
100 |
| - if (timespec_cmp(start, deadline) >= 0) return 0; |
101 |
| - remain = timespec_sub(deadline, start); |
102 |
| - if (timespec_cmp(remain, quantum) > 0) { |
103 |
| - waitfor = timespec_sub(remain, quantum); |
104 |
| - if (sys_clock_nanosleep(sleep_clock, 0, &waitfor, rem) == -1) { |
105 |
| - if (!flags && rem && errno == EINTR) { |
106 |
| - *rem = timespec_add(*rem, quantum); |
107 |
| - } |
108 |
| - return -1; |
109 |
| - } |
110 |
| - } |
111 |
| - |
112 |
| - // spin through final scheduling quantum |
113 |
| - int rc = 0; |
114 |
| - ftrace_enabled(-1); |
115 |
| - do { |
116 |
| - if (_check_cancel()) { |
117 |
| - rc = -1; |
118 |
| - break; |
119 |
| - } |
120 |
| - unassert(!clock_gettime(time_clock, &now)); |
121 |
| - } while (timespec_cmp(now, deadline) < 0); |
122 |
| - ftrace_enabled(+1); |
123 |
| - return rc; |
124 |
| -} |
125 | 23 |
|
126 | 24 | /**
|
127 | 25 | * Sleeps for particular amount of time.
|
@@ -157,10 +55,8 @@ static int cosmo_clock_nanosleep(int clock, int flags,
|
157 | 55 | * on OpenBSD it's good; on XNU it's bad; and on Windows it's ugly.
|
158 | 56 | *
|
159 | 57 | * @param clock may be
|
160 |
| - * - `CLOCK_REALTIME` to have nanosecond-accurate wall time sleeps |
161 |
| - * - `CLOCK_REALTIME_COARSE` to not spin through scheduler quantum |
162 |
| - * - `CLOCK_MONOTONIC` to base the sleep off the monotinic clock |
163 |
| - * - `CLOCK_MONOTONIC_COARSE` to once again not do userspace spin |
| 58 | + * - `CLOCK_REALTIME` |
| 59 | + * - `CLOCK_MONOTONIC` |
164 | 60 | * @param flags can be 0 for relative and `TIMER_ABSTIME` for absolute
|
165 | 61 | * @param req can be a relative or absolute time, depending on `flags`
|
166 | 62 | * @param rem shall be updated with the remainder of unslept time when
|
@@ -193,7 +89,7 @@ errno_t clock_nanosleep(int clock, int flags, //
|
193 | 89 | return EINVAL;
|
194 | 90 | }
|
195 | 91 | errno_t old = errno;
|
196 |
| - int rc = cosmo_clock_nanosleep(clock, flags, req, rem); |
| 92 | + int rc = sys_clock_nanosleep(clock, flags, req, rem); |
197 | 93 | errno_t err = !rc ? 0 : errno;
|
198 | 94 | errno = old;
|
199 | 95 | return err;
|
|
0 commit comments