From 8ef03ecf23059c36e381e3ebc9539e2419d5d0d2 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Fri, 20 Mar 2026 16:15:18 -0700 Subject: [PATCH] Remove some of the complexity from __timedwait.c. NFC This should have been part of #26471. The breaking up of the wait time for 2 of the 3 cases that are handled here is now handled one layer own in emscripten_futex_wait: 1. Breaking up the wait because we are the main runtime thread. 2. Breaking up the wait because we are async cancelable. The third cases here (breaking up the wait because we are cancelable in the non-async sense) still needs to be handled here at the higher level. --- system/lib/libc/musl/src/thread/__timedwait.c | 10 +++------- system/lib/pthread/emscripten_futex_wait.c | 3 ++- test/codesize/test_codesize_minimal_pthreads.json | 8 ++++---- .../test_codesize_minimal_pthreads_memgrowth.json | 8 ++++---- 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/system/lib/libc/musl/src/thread/__timedwait.c b/system/lib/libc/musl/src/thread/__timedwait.c index 5d37774c8555a..9539b0b90c1a3 100644 --- a/system/lib/libc/musl/src/thread/__timedwait.c +++ b/system/lib/libc/musl/src/thread/__timedwait.c @@ -59,18 +59,14 @@ int __timedwait_cp(volatile int *addr, int val, #ifdef __EMSCRIPTEN__ double msecsToSleep = top ? (top->tv_sec * 1000 + top->tv_nsec / 1000000.0) : INFINITY; - int is_runtime_thread = emscripten_is_main_runtime_thread(); // cp suffix in the function name means "cancellation point", so this wait can be cancelled // by the users unless current threads cancelability is set to PTHREAD_CANCEL_DISABLE // which may be either done by the user of __timedwait() function. pthread_t self = pthread_self(); - if (is_runtime_thread || - self->canceldisable != PTHREAD_CANCEL_DISABLE || - self->cancelasync) { - // Main runtime thread may need to run proxied calls, so sleep in very small slices to be responsive. - double max_ms_slice_to_sleep = is_runtime_thread ? 1 : 100; + if (self->canceldisable != PTHREAD_CANCEL_DISABLE) { + double max_ms_slice_to_sleep = 100; double sleepUntilTime = emscripten_get_now() + msecsToSleep; do { if (self->cancel) { @@ -79,7 +75,7 @@ int __timedwait_cp(volatile int *addr, int val, // __pthread_testcancel(), which won't return at all. __pthread_testcancel(); // If __pthread_testcancel does return here it means that canceldisable - // must be set to PTHREAD_CANCEL_MASKED. This appear to mean "return + // must be set to PTHREAD_CANCEL_MASKED. This appears to mean "return // ECANCELLED to the caller". See pthread_cond_timedwait.c for the only // use of this that I could find. return ECANCELED; diff --git a/system/lib/pthread/emscripten_futex_wait.c b/system/lib/pthread/emscripten_futex_wait.c index 963622492d5dc..7a37e9bc33fcc 100644 --- a/system/lib/pthread/emscripten_futex_wait.c +++ b/system/lib/pthread/emscripten_futex_wait.c @@ -49,6 +49,7 @@ static int futex_wait_main_browser_thread(volatile void* addr, while (1) { #ifdef __EMSCRIPTEN_PTHREADS__ if (cancelable && pthread_self()->cancel) { + __pthread_testcancel(); return -ETIMEDOUT; } #endif @@ -213,7 +214,7 @@ int emscripten_futex_wait(volatile void *addr, uint32_t val, double max_wait_ms) #endif #ifdef __EMSCRIPTEN_PTHREADS__ if (cancelable && ret == ATOMICS_WAIT_TIMED_OUT && self->cancel) { - // Break out of the loop early if we were cancelled + __pthread_testcancel(); break; } // If remainder_ns is negative it means we want wait forever, and we don't diff --git a/test/codesize/test_codesize_minimal_pthreads.json b/test/codesize/test_codesize_minimal_pthreads.json index ed8abbc889665..286657e60f5b4 100644 --- a/test/codesize/test_codesize_minimal_pthreads.json +++ b/test/codesize/test_codesize_minimal_pthreads.json @@ -1,10 +1,10 @@ { "a.out.js": 7363, "a.out.js.gz": 3604, - "a.out.nodebug.wasm": 19256, - "a.out.nodebug.wasm.gz": 8935, - "total": 26619, - "total_gz": 12539, + "a.out.nodebug.wasm": 19239, + "a.out.nodebug.wasm.gz": 8916, + "total": 26602, + "total_gz": 12520, "sent": [ "a (memory)", "b (emscripten_get_now)", diff --git a/test/codesize/test_codesize_minimal_pthreads_memgrowth.json b/test/codesize/test_codesize_minimal_pthreads_memgrowth.json index 50a3f3afc8a34..2136612149cb0 100644 --- a/test/codesize/test_codesize_minimal_pthreads_memgrowth.json +++ b/test/codesize/test_codesize_minimal_pthreads_memgrowth.json @@ -1,10 +1,10 @@ { "a.out.js": 7765, "a.out.js.gz": 3810, - "a.out.nodebug.wasm": 19257, - "a.out.nodebug.wasm.gz": 8936, - "total": 27022, - "total_gz": 12746, + "a.out.nodebug.wasm": 19240, + "a.out.nodebug.wasm.gz": 8917, + "total": 27005, + "total_gz": 12727, "sent": [ "a (memory)", "b (emscripten_get_now)",