Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion system/lib/libc/musl/src/time/clock_nanosleep.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,18 @@ int __clock_nanosleep(clockid_t clk, int flags, const struct timespec *req, stru
if (!req || req->tv_nsec < 0 || req->tv_nsec > 999999999L || req->tv_sec < 0) {
return EINVAL;
}
emscripten_thread_sleep(req->tv_sec * 1000.0 + req->tv_nsec / 1e6);
struct timespec sleep_for = *req;
if (flags & TIMER_ABSTIME) {
struct timespec now;
clock_gettime(clk, &now);
if (now.tv_sec > req->tv_sec || (now.tv_sec == req->tv_sec && now.tv_nsec >= req->tv_nsec)) {
// The requested time has already passed
return 0;
}
sleep_for.tv_sec = req->tv_sec - now.tv_sec;
sleep_for.tv_nsec = req->tv_nsec - now.tv_nsec;
}
emscripten_thread_sleep(sleep_for.tv_sec * 1000.0 + sleep_for.tv_nsec / 1e6);
return 0;
#else
#ifdef SYS_clock_nanosleep_time64
Expand Down
42 changes: 42 additions & 0 deletions tests/other/test_clock_nanosleep.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include <assert.h>
#include <stdio.h>
#include <time.h>

long long get_time_ms() {
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
return (now.tv_sec * 1000) + (now.tv_nsec / 1000 / 1000);
}

int main(void) {
// Sleep for 10ms relative to current time (i.e. without TIMER_ABSTIME).
struct timespec sleep_for;
sleep_for.tv_sec = 0;
sleep_for.tv_nsec = 10 * 1000 * 1000;
long long before = get_time_ms();
printf("before: %lli\n", before);
clock_nanosleep(CLOCK_MONOTONIC, 0, &sleep_for, NULL);
long long after = get_time_ms();
printf("after: %lli\n", after);

// Check we slept at least 10ms
assert(after > before);
assert(after - before >= 10);
assert(after - before < 10000);

before = get_time_ms();
printf("before: %lli\n", before);
struct timespec deadline;
clock_gettime(CLOCK_MONOTONIC, &deadline);
deadline.tv_nsec += 20 * 1000 * 1000;
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &deadline, NULL);
after = get_time_ms();
printf("after: %lli\n", after);

// Check we slept at least 20ms
assert(after > before);
assert(after - before >= 20);
assert(after - before < 10000);

return 0;
}
3 changes: 3 additions & 0 deletions tests/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -11806,3 +11806,6 @@ def test_wasm_worker_preprocessor_flags(self):
def test_debug_opt_warning(self):
err = self.expect_fail([EMCC, test_file('hello_world.c'), '-O2', '-g', '-Werror'])
self.assertContained('error: running limited binaryen optimizations because DWARF info requested (or indirectly required) [-Wlimited-postlink-optimizations]', err)

def test_clock_nanosleep(self):
self.do_runf(test_file('other/test_clock_nanosleep.c'))