diff --git a/libc-bottom-half/cloudlibc/src/libc/time/clock_nanosleep.c b/libc-bottom-half/cloudlibc/src/libc/time/clock_nanosleep.c index d155ac678..3fbb611f2 100644 --- a/libc-bottom-half/cloudlibc/src/libc/time/clock_nanosleep.c +++ b/libc-bottom-half/cloudlibc/src/libc/time/clock_nanosleep.c @@ -41,7 +41,7 @@ int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *rqtp, // Note: rmtp is ignored if (clock_id != CLOCK_MONOTONIC) { - // wasip2 only provides a pollable for monotonic clocks + // wasip{2,3} only provide a pollable for monotonic clocks return ENOTSUP; } diff --git a/libc-bottom-half/cloudlibc/src/libc/time/nanosleep.c b/libc-bottom-half/cloudlibc/src/libc/time/nanosleep.c index d3885520b..31ba4faa9 100644 --- a/libc-bottom-half/cloudlibc/src/libc/time/nanosleep.c +++ b/libc-bottom-half/cloudlibc/src/libc/time/nanosleep.c @@ -8,7 +8,7 @@ int nanosleep(const struct timespec *rqtp, struct timespec *rem) { #if defined(__wasip2__) || defined(__wasip3__) - // FIXME(WebAssembly/WASI#857): wasip2 only supports the monotonic clock for + // FIXME(WebAssembly/WASI#857): wasip2/p3 only supports the monotonic clock for // sleeping. clockid_t clock = CLOCK_MONOTONIC; #else diff --git a/libc-bottom-half/cloudlibc/src/libc/unistd/sleep.c b/libc-bottom-half/cloudlibc/src/libc/unistd/sleep.c index 970287b62..4f2926a2b 100644 --- a/libc-bottom-half/cloudlibc/src/libc/unistd/sleep.c +++ b/libc-bottom-half/cloudlibc/src/libc/unistd/sleep.c @@ -4,10 +4,20 @@ #include #include +#include unsigned int sleep(unsigned int seconds) { struct timespec ts = {.tv_sec = seconds, .tv_nsec = 0}; - if (clock_nanosleep(CLOCK_REALTIME, 0, &ts, NULL) != 0) + // FIXME(WebAssembly/WASI#857): wasip2/p3 only supports the monotonic clock for + // sleeping. + #if defined(__wasip1__) + clockid_t clock_id = CLOCK_REALTIME; + #elif defined(__wasip2__) || defined(__wasip3__) + clockid_t clock_id = CLOCK_MONOTONIC; + #else + #error "Unsupported WASI version" + #endif + if (clock_nanosleep(clock_id, 0, &ts, NULL) != 0) return seconds; return 0; } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index bb51b2c05..87d03c615 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -298,6 +298,7 @@ add_wasilibc_test(rewinddir.c FS FAILP3) add_wasilibc_test(seekdir.c FS FAILP3) add_wasilibc_test(usleep.c) add_wasilibc_test(nanosleep.c) +add_wasilibc_test(sleep.c) add_wasilibc_test(write.c FS FAILP3) add_wasilibc_test(wasi-defines.c) diff --git a/test/src/sleep.c b/test/src/sleep.c new file mode 100644 index 000000000..928675218 --- /dev/null +++ b/test/src/sleep.c @@ -0,0 +1,38 @@ +#include "test.h" +#include +#include +#include +#include +#include +#include + +#define TEST(c) \ + do { \ + errno = 0; \ + if (!(c)) \ + t_error("%s failed (errno = %d)\n", #c, errno); \ + } while (0) + +#ifdef __wasip1__ +#define CLOCK CLOCK_REALTIME +#else +#define CLOCK CLOCK_MONOTONIC +#endif + +int main(void) { + // Sleep for a total of 2 seconds + unsigned int seconds_to_sleep = 2; + + struct timespec start_time, end_time; + clock_gettime(CLOCK, &start_time); + TEST(sleep(seconds_to_sleep) == 0); + clock_gettime(CLOCK, &end_time); + TEST(end_time.tv_sec - start_time.tv_sec <= 3); + + long nanoseconds_elapsed = (end_time.tv_sec - start_time.tv_sec) * 1E9 - + start_time.tv_nsec + end_time.tv_nsec; + + TEST(nanoseconds_elapsed >= seconds_to_sleep * 1E9); + + return t_status; +}