diff --git a/test/core/test_poll_blocking.c b/test/core/test_poll_blocking.c index bdbd6b1ee1571..2ddb669e98893 100644 --- a/test/core/test_poll_blocking.c +++ b/test/core/test_poll_blocking.c @@ -22,23 +22,32 @@ void sleep_ms(int ms) { usleep(ms * 1000); } -int64_t timeval_delta_ms(struct timeval* begin, struct timeval* end) { - int64_t delta_s = end->tv_sec - begin->tv_sec; - int64_t delta_us = end->tv_usec - begin->tv_usec; - assert(delta_s >= 0); - return (delta_s * 1000) + (delta_us / 1000); +int64_t timespec_delta_ms(struct timespec* begin, struct timespec* end) { + struct timespec diff = { + .tv_sec = end->tv_sec - begin->tv_sec, + .tv_nsec = end->tv_nsec - begin->tv_nsec + }; + + if (diff.tv_nsec < 0) { + diff.tv_nsec += 1000000000; + diff.tv_sec -= 1; + } + + assert(diff.tv_sec >= 0); + + return (diff.tv_sec * 1000) + (diff.tv_nsec / 1000000); } // Check if timeout works without fds void test_timeout_without_fds() { printf("test_timeout_without_fds\n"); - struct timeval begin, end; + struct timespec begin, end; - gettimeofday(&begin, NULL); + clock_gettime(CLOCK_MONOTONIC, &begin); assert(poll(NULL, 0, TIMEOUT_MS) == 0); - gettimeofday(&end, NULL); + clock_gettime(CLOCK_MONOTONIC, &end); - int64_t duration = timeval_delta_ms(&begin, &end); + int64_t duration = timespec_delta_ms(&begin, &end); printf(" -> duration: %lld ms\n", duration); assert(duration >= TIMEOUT_MS); } @@ -46,17 +55,17 @@ void test_timeout_without_fds() { // Check if timeout works with fds without events void test_timeout_with_fds_without_events() { printf("test_timeout_with_fds_without_events\n"); - struct timeval begin, end; + struct timespec begin, end; int pipe_a[2]; assert(pipe(pipe_a) == 0); - gettimeofday(&begin, NULL); + clock_gettime(CLOCK_MONOTONIC, &begin); struct pollfd fds = {pipe_a[0], 0, 0}; assert(poll(&fds, 1, TIMEOUT_MS) == 0); - gettimeofday(&end, NULL); + clock_gettime(CLOCK_MONOTONIC, &end); - int64_t duration = timeval_delta_ms(&begin, &end); + int64_t duration = timespec_delta_ms(&begin, &end); printf(" -> duration: %lld ms\n", duration); assert(duration >= TIMEOUT_MS); @@ -77,7 +86,7 @@ void *write_after_sleep(void * arg) { // Check if poll can unblock on an event void test_unblock_poll() { printf("test_unblock_poll\n"); - struct timeval begin, end; + struct timespec begin, end; pthread_t tid; int pipe_a[2]; @@ -88,13 +97,13 @@ void test_unblock_poll() { {pipe_a[0], POLLIN, 0}, {pipe_shared[0], POLLIN, 0}, }; - gettimeofday(&begin, NULL); + clock_gettime(CLOCK_MONOTONIC, &begin); assert(pthread_create(&tid, NULL, write_after_sleep, NULL) == 0); assert(poll(fds, 2, -1) == 1); - gettimeofday(&end, NULL); + clock_gettime(CLOCK_MONOTONIC, &end); assert(fds[1].revents & POLLIN); - int64_t duration = timeval_delta_ms(&begin, &end); + int64_t duration = timespec_delta_ms(&begin, &end); printf(" -> duration: %lld ms\n", duration); assert(duration >= TIMEOUT_MS); @@ -105,15 +114,15 @@ void test_unblock_poll() { } void *do_poll_in_thread(void * arg) { - struct timeval begin, end; + struct timespec begin, end; - gettimeofday(&begin, NULL); + clock_gettime(CLOCK_MONOTONIC, &begin); struct pollfd fds = {pipe_shared[0], POLLIN, 0}; assert(poll(&fds, 1, 4000) == 1); - gettimeofday(&end, NULL); + clock_gettime(CLOCK_MONOTONIC, &end); assert(fds.revents & POLLIN); - int64_t duration = timeval_delta_ms(&begin, &end); + int64_t duration = timespec_delta_ms(&begin, &end); printf(" -> duration: %lld ms\n", duration); assert((duration >= TIMEOUT_MS) && (duration < 4000)); diff --git a/test/core/test_poll_blocking_asyncify.c b/test/core/test_poll_blocking_asyncify.c index b4d9bf6c735a5..6de6ae54c13d6 100644 --- a/test/core/test_poll_blocking_asyncify.c +++ b/test/core/test_poll_blocking_asyncify.c @@ -19,23 +19,33 @@ #include -int64_t timeval_delta_ms(struct timeval* begin, struct timeval* end) { - int64_t delta_s = end->tv_sec - begin->tv_sec; - int64_t delta_us = end->tv_usec - begin->tv_usec; - assert(delta_s >= 0); - return (delta_s * 1000) + (delta_us / 1000); +int64_t timespec_delta_ms(struct timespec* begin, struct timespec* end) { + struct timespec diff = { + .tv_sec = end->tv_sec - begin->tv_sec, + .tv_nsec = end->tv_nsec - begin->tv_nsec + }; + + if (diff.tv_nsec < 0) { + diff.tv_nsec += 1000000000; + diff.tv_sec -= 1; + } + + assert(diff.tv_sec >= 0); + + return (diff.tv_sec * 1000) + (diff.tv_nsec / 1000000); } // Check if timeout works without fds void test_timeout_without_fds() { printf("test_timeout_without_fds\n"); - struct timeval begin, end; + struct timespec begin = {0}; + struct timespec end = {0}; - gettimeofday(&begin, NULL); + clock_gettime(CLOCK_MONOTONIC, &begin); assert(poll(NULL, 0, 1000) == 0); - gettimeofday(&end, NULL); + clock_gettime(CLOCK_MONOTONIC, &end); - int64_t duration = timeval_delta_ms(&begin, &end); + int64_t duration = timespec_delta_ms(&begin, &end); printf(" -> duration: %lld ms\n", duration); assert(duration >= 1000); } @@ -51,7 +61,8 @@ void write_to_pipe(void * arg) { // Check if poll can unblock on an event void test_unblock_poll() { printf("test_unblock_poll\n"); - struct timeval begin, end; + struct timespec begin = {0}; + struct timespec end = {0}; int pipe_a[2]; assert(pipe(pipe_a) == 0); @@ -62,12 +73,12 @@ void test_unblock_poll() { {pipe_shared[0], POLLIN, 0}, }; emscripten_set_timeout(write_to_pipe, 1000, NULL); - gettimeofday(&begin, NULL); + clock_gettime(CLOCK_MONOTONIC, &begin); assert(poll(fds, 2, -1) == 1); - gettimeofday(&end, NULL); + clock_gettime(CLOCK_MONOTONIC, &end); assert(fds[1].revents & POLLIN); - int64_t duration = timeval_delta_ms(&begin, &end); + int64_t duration = timespec_delta_ms(&begin, &end); printf(" -> duration: %lld ms\n", duration); assert(duration >= 1000); diff --git a/test/core/test_select_blocking.c b/test/core/test_select_blocking.c index ddedab1aee851..88ecf3c487b04 100644 --- a/test/core/test_select_blocking.c +++ b/test/core/test_select_blocking.c @@ -19,25 +19,35 @@ void sleep_ms(int ms) { usleep(ms * 1000); } -int64_t timeval_delta_ms(struct timeval* begin, struct timeval* end) { - int64_t delta_s = end->tv_sec - begin->tv_sec; - int64_t delta_us = end->tv_usec - begin->tv_usec; - assert(delta_s >= 0); - return (delta_s * 1000) + (delta_us / 1000); +int64_t timespec_delta_ms(struct timespec* begin, struct timespec* end) { + struct timespec diff = { + .tv_sec = end->tv_sec - begin->tv_sec, + .tv_nsec = end->tv_nsec - begin->tv_nsec + }; + + if (diff.tv_nsec < 0) { + diff.tv_nsec += 1000000000; + diff.tv_sec -= 1; + } + + assert(diff.tv_sec >= 0); + + return (diff.tv_sec * 1000) + (diff.tv_nsec / 1000000); } // Check if timeout works without fds void test_timeout_without_fds() { printf("test_timeout_without_fds\n"); - struct timeval tv, begin, end; + struct timespec begin, end; + struct timeval tv; tv.tv_sec = 0; tv.tv_usec = TIMEOUT_MS * 1000; - gettimeofday(&begin, NULL); + clock_gettime(CLOCK_MONOTONIC, &begin); assert(select(0, NULL, NULL, NULL, &tv) == 0); - gettimeofday(&end, NULL); + clock_gettime(CLOCK_MONOTONIC, &end); - int64_t duration = timeval_delta_ms(&begin, &end); + int64_t duration = timespec_delta_ms(&begin, &end); printf(" -> duration: %lld ms\n", duration); assert(duration >= TIMEOUT_MS); } @@ -45,7 +55,8 @@ void test_timeout_without_fds() { // Check if timeout works with fds without events void test_timeout_with_fds_without_events() { printf("test_timeout_with_fds_without_events\n"); - struct timeval tv, begin, end; + struct timespec begin, end; + struct timeval tv; fd_set readfds; int pipe_a[2]; @@ -55,11 +66,11 @@ void test_timeout_with_fds_without_events() { tv.tv_usec = TIMEOUT_MS * 1000; FD_ZERO(&readfds); FD_SET(pipe_a[0], &readfds); - gettimeofday(&begin, NULL); + clock_gettime(CLOCK_MONOTONIC, &begin); assert(select(pipe_a[0] + 1, &readfds, NULL, NULL, &tv) == 0); - gettimeofday(&end, NULL); + clock_gettime(CLOCK_MONOTONIC, &end); - int64_t duration = timeval_delta_ms(&begin, &end); + int64_t duration = timespec_delta_ms(&begin, &end); printf(" -> duration: %lld ms\n", duration); assert(duration >= TIMEOUT_MS); @@ -80,7 +91,7 @@ void *write_after_sleep(void * arg) { // Check if select can unblock on an event void test_unblock_select() { printf("test_unblock_select\n"); - struct timeval begin, end; + struct timespec begin, end; fd_set readfds; pthread_t tid; int pipe_a[2]; @@ -92,13 +103,13 @@ void test_unblock_select() { FD_SET(pipe_a[0], &readfds); FD_SET(pipe_shared[0], &readfds); int maxfd = (pipe_a[0] > pipe_shared[0] ? pipe_a[0] : pipe_shared[0]); - gettimeofday(&begin, NULL); + clock_gettime(CLOCK_MONOTONIC, &begin); assert(pthread_create(&tid, NULL, write_after_sleep, NULL) == 0); assert(select(maxfd + 1, &readfds, NULL, NULL, NULL) == 1); - gettimeofday(&end, NULL); + clock_gettime(CLOCK_MONOTONIC, &end); assert(FD_ISSET(pipe_shared[0], &readfds)); - int64_t duration = timeval_delta_ms(&begin, &end); + int64_t duration = timespec_delta_ms(&begin, &end); printf(" -> duration: %lld ms\n", duration); assert(duration >= TIMEOUT_MS); @@ -109,9 +120,9 @@ void test_unblock_select() { } void *do_select_in_thread(void * arg) { - struct timeval begin, end; - fd_set readfds; + struct timespec begin, end; struct timeval tv; + fd_set readfds; tv.tv_sec = 4; tv.tv_usec = 0; @@ -119,12 +130,12 @@ void *do_select_in_thread(void * arg) { FD_SET(pipe_shared[0], &readfds); int maxfd = pipe_shared[0]; - gettimeofday(&begin, NULL); + clock_gettime(CLOCK_MONOTONIC, &begin); assert(select(maxfd + 1, &readfds, NULL, NULL, &tv) == 1); - gettimeofday(&end, NULL); + clock_gettime(CLOCK_MONOTONIC, &end); assert(FD_ISSET(pipe_shared[0], &readfds)); - int64_t duration = timeval_delta_ms(&begin, &end); + int64_t duration = timespec_delta_ms(&begin, &end); printf(" -> duration: %lld ms\n", duration); assert((duration >= TIMEOUT_MS) && (duration < 4000)); diff --git a/test/test_core.py b/test/test_core.py index 13c9694105560..0e90c9cdd1cd9 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -9588,17 +9588,14 @@ def test_syscall_intercept(self): self.do_core_test('test_syscall_intercept.c') @requires_pthreads - @flaky('https://github.com/emscripten-core/emscripten/issues/26256') def test_select_blocking(self): self.do_runf('core/test_select_blocking.c', cflags=['-pthread', '-sPROXY_TO_PTHREAD=1', '-sEXIT_RUNTIME=1']) @requires_pthreads - @flaky('https://github.com/emscripten-core/emscripten/issues/26256') def test_poll_blocking(self): self.do_runf('core/test_poll_blocking.c', cflags=['-pthread', '-sPROXY_TO_PTHREAD=1', '-sEXIT_RUNTIME=1']) @with_asyncify_and_jspi - @flaky('https://github.com/emscripten-core/emscripten/issues/26256') def test_poll_blocking_asyncify(self): if self.get_setting('JSPI') and engine_is_v8(self.get_current_js_engine()): self.skipTest('test requires setTimeout which is not supported under v8')