Skip to content

Commit d50e5a6

Browse files
committed
Cherry-pick remainder of PR 15739
1 parent 83d4cc1 commit d50e5a6

File tree

4 files changed

+22
-26
lines changed

4 files changed

+22
-26
lines changed

system/lib/libc/musl/src/thread/__timedwait.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,21 +56,20 @@ int __timedwait_cp(volatile int *addr, int val,
5656
top = &to;
5757
}
5858
#ifdef __EMSCRIPTEN__
59-
double msecsToSleep = top ? (top->tv_sec * 1000 + top->tv_nsec / 1000000.0) : INFINITY;
59+
pthread_t self = __pthread_self();
60+
double msecsToSleep = top ? (top->tv_sec * 1000.0 + top->tv_nsec / 1000000.0) : INFINITY;
6061
int is_runtime_thread = emscripten_is_main_runtime_thread();
6162

6263
// Main runtime thread may need to run proxied calls, so sleep in very small slices to be responsive.
6364
double max_ms_slice_to_sleep = is_runtime_thread ? 1 : 100;
6465

6566
// cp suffix in the function name means "cancellation point", so this wait can be cancelled
66-
// by the users unless current threads cancelability is set to PTHREAD_CANCEL_DISABLE
67+
// by the users unless current threads cancellability is set to PTHREAD_CANCEL_DISABLE
6768
// which may be either done by the user of __timedwait() function.
68-
if (is_runtime_thread ||
69-
pthread_self()->canceldisable != PTHREAD_CANCEL_DISABLE ||
70-
pthread_self()->cancelasync == PTHREAD_CANCEL_ASYNCHRONOUS) {
69+
if (is_runtime_thread || self->canceldisable != PTHREAD_CANCEL_DISABLE || self->cancelasync) {
7170
double sleepUntilTime = emscripten_get_now() + msecsToSleep;
7271
do {
73-
if (pthread_self()->cancel) {
72+
if (self->cancel) {
7473
// Emscripten-specific return value: The wait was canceled by user calling
7574
// pthread_cancel() for this thread, and the caller needs to cooperatively
7675
// cancel execution.

system/lib/libc/musl/src/thread/__wait.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,17 @@ void __wait(volatile int *addr, volatile int *waiters, int val, int priv)
1515
}
1616
if (waiters) a_inc(waiters);
1717
#ifdef __EMSCRIPTEN__
18+
pthread_t self = __pthread_self();
1819
int is_runtime_thread = emscripten_is_main_runtime_thread();
1920

2021
// Main runtime thread may need to run proxied calls, so sleep in very small slices to be responsive.
2122
double max_ms_slice_to_sleep = is_runtime_thread ? 1 : 100;
2223

2324
while (*addr==val) {
24-
if (is_runtime_thread || pthread_self()->cancelasync == PTHREAD_CANCEL_ASYNCHRONOUS) {
25+
if (is_runtime_thread || self->cancelasync) {
2526
int e;
2627
do {
27-
if (pthread_self()->cancel) {
28+
if (self->cancel) {
2829
if (waiters) a_dec(waiters);
2930
return;
3031
}

system/lib/libc/musl/src/thread/pthread_barrier_wait.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,10 @@ int pthread_barrier_wait(pthread_barrier_t *b)
9393
if (is_runtime_thread) {
9494
int e;
9595
do {
96-
// Main runtime thread may need to run proxied calls, so sleep in very small slices to be responsive.
97-
e = emscripten_futex_wait(&inst->finished, 1, 1);
9896
// Assist other threads by executing proxied operations that are effectively singlethreaded.
9997
emscripten_main_thread_process_queued_calls();
98+
// Main runtime thread may need to run proxied calls, so sleep in very small slices to be responsive.
99+
e = emscripten_futex_wait(&inst->finished, 1, 1);
100100
} while (e == -ETIMEDOUT);
101101
} else {
102102
// Can wait in one go.

system/lib/pthread/library_pthread.c

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -382,25 +382,21 @@ static CallQueue* GetOrAllocateQueue(void* target) {
382382
return q;
383383
}
384384

385+
// TODO(kleisauke): All paths call this with timeoutMSecs == INFINITY, perhaps drop this param?
385386
EMSCRIPTEN_RESULT emscripten_wait_for_call_v(em_queued_call* call, double timeoutMSecs) {
387+
emscripten_set_current_thread_status(EM_THREAD_STATUS_WAITPROXY);
388+
386389
int r;
390+
double target = emscripten_get_now() + timeoutMSecs;
391+
do {
392+
r = -emscripten_futex_wait(&call->operationDone, 0, timeoutMSecs);
387393

388-
int done = atomic_load(&call->operationDone);
389-
if (!done) {
390-
double now = emscripten_get_now();
391-
double waitEndTime = now + timeoutMSecs;
392-
emscripten_set_current_thread_status(EM_THREAD_STATUS_WAITPROXY);
393-
while (!done && now < waitEndTime) {
394-
r = emscripten_futex_wait(&call->operationDone, 0, waitEndTime - now);
395-
done = atomic_load(&call->operationDone);
396-
now = emscripten_get_now();
397-
}
398-
emscripten_set_current_thread_status(EM_THREAD_STATUS_RUNNING);
399-
}
400-
if (done)
401-
return EMSCRIPTEN_RESULT_SUCCESS;
402-
else
403-
return EMSCRIPTEN_RESULT_TIMED_OUT;
394+
timeoutMSecs = target - emscripten_get_now();
395+
} while (r == ETIMEDOUT && timeoutMSecs > 0);
396+
397+
emscripten_set_current_thread_status(EM_THREAD_STATUS_RUNNING);
398+
399+
return r == ETIMEDOUT ? EMSCRIPTEN_RESULT_TIMED_OUT : EMSCRIPTEN_RESULT_SUCCESS;
404400
}
405401

406402
EMSCRIPTEN_RESULT emscripten_wait_for_call_i(

0 commit comments

Comments
 (0)