Skip to content

Commit 62fa62a

Browse files
authored
Add support for TIMER_ABSTIME flag in clock_nanosleep (#16455)
Fixes: #16453
1 parent cdc1c05 commit 62fa62a

File tree

3 files changed

+57
-1
lines changed

3 files changed

+57
-1
lines changed

system/lib/libc/musl/src/time/clock_nanosleep.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,18 @@ int __clock_nanosleep(clockid_t clk, int flags, const struct timespec *req, stru
1616
if (!req || req->tv_nsec < 0 || req->tv_nsec > 999999999L || req->tv_sec < 0) {
1717
return EINVAL;
1818
}
19-
emscripten_thread_sleep(req->tv_sec * 1000.0 + req->tv_nsec / 1e6);
19+
struct timespec sleep_for = *req;
20+
if (flags & TIMER_ABSTIME) {
21+
struct timespec now;
22+
clock_gettime(clk, &now);
23+
if (now.tv_sec > req->tv_sec || (now.tv_sec == req->tv_sec && now.tv_nsec >= req->tv_nsec)) {
24+
// The requested time has already passed
25+
return 0;
26+
}
27+
sleep_for.tv_sec = req->tv_sec - now.tv_sec;
28+
sleep_for.tv_nsec = req->tv_nsec - now.tv_nsec;
29+
}
30+
emscripten_thread_sleep(sleep_for.tv_sec * 1000.0 + sleep_for.tv_nsec / 1e6);
2031
return 0;
2132
#else
2233
#ifdef SYS_clock_nanosleep_time64

tests/other/test_clock_nanosleep.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#include <assert.h>
2+
#include <stdio.h>
3+
#include <time.h>
4+
5+
long long get_time_ms() {
6+
struct timespec now;
7+
clock_gettime(CLOCK_MONOTONIC, &now);
8+
return (now.tv_sec * 1000) + (now.tv_nsec / 1000 / 1000);
9+
}
10+
11+
int main(void) {
12+
// Sleep for 10ms relative to current time (i.e. without TIMER_ABSTIME).
13+
struct timespec sleep_for;
14+
sleep_for.tv_sec = 0;
15+
sleep_for.tv_nsec = 10 * 1000 * 1000;
16+
long long before = get_time_ms();
17+
printf("before: %lli\n", before);
18+
clock_nanosleep(CLOCK_MONOTONIC, 0, &sleep_for, NULL);
19+
long long after = get_time_ms();
20+
printf("after: %lli\n", after);
21+
22+
// Check we slept at least 10ms
23+
assert(after > before);
24+
assert(after - before >= 10);
25+
assert(after - before < 10000);
26+
27+
before = get_time_ms();
28+
printf("before: %lli\n", before);
29+
struct timespec deadline;
30+
clock_gettime(CLOCK_MONOTONIC, &deadline);
31+
deadline.tv_nsec += 20 * 1000 * 1000;
32+
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &deadline, NULL);
33+
after = get_time_ms();
34+
printf("after: %lli\n", after);
35+
36+
// Check we slept at least 20ms
37+
assert(after > before);
38+
assert(after - before >= 20);
39+
assert(after - before < 10000);
40+
41+
return 0;
42+
}

tests/test_other.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11806,3 +11806,6 @@ def test_wasm_worker_preprocessor_flags(self):
1180611806
def test_debug_opt_warning(self):
1180711807
err = self.expect_fail([EMCC, test_file('hello_world.c'), '-O2', '-g', '-Werror'])
1180811808
self.assertContained('error: running limited binaryen optimizations because DWARF info requested (or indirectly required) [-Wlimited-postlink-optimizations]', err)
11809+
11810+
def test_clock_nanosleep(self):
11811+
self.do_runf(test_file('other/test_clock_nanosleep.c'))

0 commit comments

Comments
 (0)