diff --git a/system/lib/pthread/library_pthread.c b/system/lib/pthread/library_pthread.c index a89425874b113..0a47e1a4dd863 100644 --- a/system/lib/pthread/library_pthread.c +++ b/system/lib/pthread/library_pthread.c @@ -85,18 +85,17 @@ void emscripten_thread_sleep(double msecs) { __pthread_testcancel(); if (msecs > 0) { uint32_t dummyZeroAddress = 0; - double start = emscripten_get_now(); - double elapsed = 0; - while (elapsed < msecs) { + double target = emscripten_get_now() + msecs; + do { emscripten_conditional_set_current_thread_status(EM_THREAD_STATUS_RUNNING, EM_THREAD_STATUS_SLEEPING); - emscripten_futex_wait(&dummyZeroAddress, 0, msecs - elapsed); + emscripten_futex_wait(&dummyZeroAddress, 0, msecs); emscripten_conditional_set_current_thread_status(EM_THREAD_STATUS_SLEEPING, EM_THREAD_STATUS_RUNNING); emscripten_current_thread_process_queued_calls(); __pthread_testcancel(); - elapsed = emscripten_get_now() - start; - } + msecs = target - emscripten_get_now(); + } while (msecs > 0); } } diff --git a/system/lib/pthread/proxying_legacy.c b/system/lib/pthread/proxying_legacy.c index b9c0e148ba8a9..f6dae33fef15f 100644 --- a/system/lib/pthread/proxying_legacy.c +++ b/system/lib/pthread/proxying_legacy.c @@ -530,24 +530,23 @@ em_queued_call* emscripten_async_waitable_run_in_main_runtime_thread_( } EMSCRIPTEN_RESULT emscripten_wait_for_call_v(em_queued_call* call, double timeoutMSecs) { + if (call->operationDone) { + return EMSCRIPTEN_RESULT_SUCCESS; + } + + emscripten_set_current_thread_status(EM_THREAD_STATUS_WAITPROXY); + int r; + double target = emscripten_get_now() + timeoutMSecs; + do { + r = -emscripten_futex_wait(&call->operationDone, 0, timeoutMSecs); - int done = atomic_load(&call->operationDone); - if (!done) { - double now = emscripten_get_now(); - double waitEndTime = now + timeoutMSecs; - emscripten_set_current_thread_status(EM_THREAD_STATUS_WAITPROXY); - while (!done && now < waitEndTime) { - r = emscripten_futex_wait(&call->operationDone, 0, waitEndTime - now); - done = atomic_load(&call->operationDone); - now = emscripten_get_now(); - } - emscripten_set_current_thread_status(EM_THREAD_STATUS_RUNNING); - } - if (done) - return EMSCRIPTEN_RESULT_SUCCESS; - else - return EMSCRIPTEN_RESULT_TIMED_OUT; + timeoutMSecs = target - emscripten_get_now(); + } while (r == EINTR && timeoutMSecs > 0); + + emscripten_set_current_thread_status(EM_THREAD_STATUS_RUNNING); + + return r == ETIMEDOUT ? EMSCRIPTEN_RESULT_TIMED_OUT : EMSCRIPTEN_RESULT_SUCCESS; } EMSCRIPTEN_RESULT emscripten_wait_for_call_i(