Skip to content

Commit

Permalink
Cherry-pick remainder of PR 15739
Browse files Browse the repository at this point in the history
  • Loading branch information
kleisauke committed Sep 2, 2022
1 parent 1cca5a2 commit 25a6cb2
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 24 deletions.
11 changes: 5 additions & 6 deletions system/lib/libc/musl/src/thread/__timedwait.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,20 @@ int __timedwait_cp(volatile int *addr, int val,
top = &to;
}
#ifdef __EMSCRIPTEN__
double msecsToSleep = top ? (top->tv_sec * 1000 + top->tv_nsec / 1000000.0) : INFINITY;
pthread_t self = __pthread_self();
double msecsToSleep = top ? (top->tv_sec * 1000.0 + top->tv_nsec / 1000000.0) : INFINITY;
int is_runtime_thread = emscripten_is_main_runtime_thread();

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

// 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
// by the users unless current threads cancellability is set to PTHREAD_CANCEL_DISABLE
// which may be either done by the user of __timedwait() function.
if (is_runtime_thread ||
pthread_self()->canceldisable != PTHREAD_CANCEL_DISABLE ||
pthread_self()->cancelasync == PTHREAD_CANCEL_ASYNCHRONOUS) {
if (is_runtime_thread || self->canceldisable != PTHREAD_CANCEL_DISABLE || self->cancelasync) {
double sleepUntilTime = emscripten_get_now() + msecsToSleep;
do {
if (pthread_self()->cancel) {
if (self->cancel) {
// Emscripten-specific return value: The wait was canceled by user calling
// pthread_cancel() for this thread, and the caller needs to cooperatively
// cancel execution.
Expand Down
5 changes: 3 additions & 2 deletions system/lib/libc/musl/src/thread/__wait.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,17 @@ void __wait(volatile int *addr, volatile int *waiters, int val, int priv)
}
if (waiters) a_inc(waiters);
#ifdef __EMSCRIPTEN__
pthread_t self = __pthread_self();
int is_runtime_thread = emscripten_is_main_runtime_thread();

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

while (*addr==val) {
if (is_runtime_thread || pthread_self()->cancelasync == PTHREAD_CANCEL_ASYNCHRONOUS) {
if (is_runtime_thread || self->cancelasync) {
int e;
do {
if (pthread_self()->cancel) {
if (self->cancel) {
if (waiters) a_dec(waiters);
return;
}
Expand Down
27 changes: 11 additions & 16 deletions system/lib/pthread/library_pthread.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,24 +322,19 @@ static void _do_call(void* arg) {
}

EMSCRIPTEN_RESULT emscripten_wait_for_call_v(em_queued_call* call, double timeoutMSecs) {
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 == ETIMEDOUT && 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

0 comments on commit 25a6cb2

Please sign in to comment.