Skip to content

Commit 93ec16e

Browse files
committed
Remove timeout slicing from __timedwait. NFC
This removes the timeout slicing from `__timedwait` and instead relies on the existing slicing in `emscripten_futex_wait.c`. This is a followup to #26511 and #26471 (which did the same for the slicing in `__wait`).
1 parent 5fae227 commit 93ec16e

File tree

2 files changed

+9
-37
lines changed

2 files changed

+9
-37
lines changed

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

Lines changed: 2 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -58,41 +58,8 @@ int __timedwait_cp(volatile int *addr, int val,
5858
}
5959

6060
#ifdef __EMSCRIPTEN__
61-
double msecsToSleep = top ? (top->tv_sec * 1000 + top->tv_nsec / 1000000.0) : INFINITY;
62-
63-
// cp suffix in the function name means "cancellation point", so this wait can be cancelled
64-
// by the user, unless current thread has cancelation disabled (which may be either done
65-
// directly, or indirectly, for example in the __timedwait() function).
66-
pthread_t self = pthread_self();
67-
68-
if (self->canceldisable != PTHREAD_CANCEL_DISABLE) {
69-
double max_ms_slice_to_sleep = 100;
70-
double sleepUntilTime = emscripten_get_now() + msecsToSleep;
71-
do {
72-
if (self->cancel) {
73-
// The thread was canceled by pthread_cancel().
74-
// In the case of cancelasync or PTHREAD_CANCEL_ENABLE we can just call
75-
// __pthread_testcancel(), which won't return at all.
76-
__pthread_testcancel();
77-
// If __pthread_testcancel does return here it means that canceldisable
78-
// must be set to PTHREAD_CANCEL_MASKED. In this case we emulate the
79-
// behaviour of the futex syscall and return ECANCELLED here.
80-
// See pthread_cond_timedwait.c for the only use of this flag.
81-
return ECANCELED;
82-
}
83-
msecsToSleep = sleepUntilTime - emscripten_get_now();
84-
if (msecsToSleep <= 0) {
85-
return ETIMEDOUT;
86-
}
87-
// Must wait in slices in case this thread is cancelled in between.
88-
if (msecsToSleep > max_ms_slice_to_sleep)
89-
msecsToSleep = max_ms_slice_to_sleep;
90-
r = -emscripten_futex_wait((void*)addr, val, msecsToSleep);
91-
} while (r == ETIMEDOUT);
92-
} else {
93-
// Can wait in one go.
94-
r = -emscripten_futex_wait((void*)addr, val, msecsToSleep);
95-
}
61+
double msecs_to_sleep = top ? (top->tv_sec * 1000 + top->tv_nsec / 1000000.0) : INFINITY;
62+
r = -emscripten_futex_wait((void*)addr, val, msecs_to_sleep);
9663
#else
9764
r = -__futex4_cp(addr, FUTEX_WAIT|priv, val, top);
9865
#endif

system/lib/pthread/emscripten_futex_wait.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ int emscripten_futex_wait(volatile void *addr, uint32_t val, double max_wait_ms)
132132

133133
#ifdef __EMSCRIPTEN_PTHREADS__
134134
pthread_t self = pthread_self();
135-
bool cancelable = !self->canceldisable && self->cancelasync;
135+
bool cancelable = self->canceldisable != PTHREAD_CANCEL_DISABLE;
136136
#else
137137
bool cancelable = false;
138138
#endif
@@ -215,7 +215,12 @@ int emscripten_futex_wait(volatile void *addr, uint32_t val, double max_wait_ms)
215215
#ifdef __EMSCRIPTEN_PTHREADS__
216216
if (cancelable && ret == ATOMICS_WAIT_TIMED_OUT && self->cancel) {
217217
__pthread_testcancel();
218-
break;
218+
// If __pthread_testcancel does return here it means that canceldisable
219+
// must be set to PTHREAD_CANCEL_MASKED. In this case we emulate the
220+
// behaviour of the futex syscall and return ECANCELLED here.
221+
// See pthread_cond_timedwait.c for the only use of this flag.
222+
emscripten_conditional_set_current_thread_status(EM_THREAD_STATUS_WAITFUTEX, EM_THREAD_STATUS_RUNNING);
223+
return -ECANCELED;
219224
}
220225
// If remainder_ns is negative it means we want wait forever, and we don't
221226
// need to decrement remainder_ns in that case.

0 commit comments

Comments
 (0)