Micro-optimize timed wait loops. NFC (#26849)
Split out from #13007.
diff --git a/system/lib/pthread/library_pthread.c b/system/lib/pthread/library_pthread.c
index a894258..0a47e1a 100644
--- a/system/lib/pthread/library_pthread.c
+++ b/system/lib/pthread/library_pthread.c
@@ -85,18 +85,17 @@
__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 b9c0e14..f6dae33 100644
--- a/system/lib/pthread/proxying_legacy.c
+++ b/system/lib/pthread/proxying_legacy.c
@@ -530,24 +530,23 @@
}
EMSCRIPTEN_RESULT emscripten_wait_for_call_v(em_queued_call* call, double timeoutMSecs) {
- int r;
-
- 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)
+ if (call->operationDone) {
return EMSCRIPTEN_RESULT_SUCCESS;
- else
- return EMSCRIPTEN_RESULT_TIMED_OUT;
+ }
+
+ 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);
+
+ 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(