Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions system/lib/pthread/library_pthread.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand Down
31 changes: 15 additions & 16 deletions system/lib/pthread/proxying_legacy.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Comment thread
sbc100 marked this conversation as resolved.
}

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);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we want to remove this line.

IIUC that idea with the futex_wait API is that one should only call it once you know you need to block. i.e. its designed as the expensive syscall that you use once you know you need to block, and its common to place it after some amount of spinning (or at least an atomic check like this one).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. Added this back as an early return with commit ab6b2bf.

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(
Expand Down
Loading