Skip to content
Open
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
12 changes: 4 additions & 8 deletions system/lib/libc/musl/src/thread/__timedwait.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,20 +59,16 @@ int __timedwait_cp(volatile int *addr, int val,

#ifdef __EMSCRIPTEN__
double msecsToSleep = top ? (top->tv_sec * 1000 + 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
// 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_t self = pthread_self();
if (!self->canceldisable) {
double max_ms_slice_to_sleep = 100;
double sleepUntilTime = emscripten_get_now() + msecsToSleep;
do {
if (pthread_self()->cancel) {
if (self->cancel) {
// The thread was canceled by pthread_cancel().
// In the case of cancelasync or PTHREAD_CANCEL_ENABLE we can just call
// __pthread_testcancel(), which won't return at all.
Expand Down
10 changes: 6 additions & 4 deletions system/lib/pthread/emscripten_futex_wait.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ static int futex_wait_main_browser_thread(volatile void* addr,

while (1) {
#ifdef __EMSCRIPTEN_PTHREADS__
if (cancelable && pthread_self()->cancel) {
if (cancelable) {
__pthread_testcancel();
return -ETIMEDOUT;
}
#endif
Expand Down Expand Up @@ -130,7 +131,8 @@ int emscripten_futex_wait(volatile void *addr, uint32_t val, double max_wait_ms)
emscripten_conditional_set_current_thread_status(EM_THREAD_STATUS_RUNNING, EM_THREAD_STATUS_WAITFUTEX);

#ifdef __EMSCRIPTEN_PTHREADS__
bool cancelable = pthread_self()->cancelasync == PTHREAD_CANCEL_ASYNCHRONOUS;
pthread_t self = pthread_self();
bool cancelable = self->cancelasync;
#else
bool cancelable = false;
#endif
Expand Down Expand Up @@ -211,8 +213,8 @@ int emscripten_futex_wait(volatile void *addr, uint32_t val, double max_wait_ms)
}
#endif
#ifdef __EMSCRIPTEN_PTHREADS__
if (cancelable && ret == ATOMICS_WAIT_TIMED_OUT && pthread_self()->cancel) {
// Break out of the loop early if we were cancelled
if (cancelable && ret == ATOMICS_WAIT_TIMED_OUT) {
__pthread_testcancel();
break;
}
// If remainder_ns is negative it means we want wait forever, and we don't
Expand Down
8 changes: 4 additions & 4 deletions test/codesize/test_codesize_minimal_pthreads.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"a.out.js": 7364,
"a.out.js.gz": 3607,
"a.out.nodebug.wasm": 19265,
"a.out.nodebug.wasm.gz": 8934,
"total": 26629,
"total_gz": 12541,
"a.out.nodebug.wasm": 19231,
"a.out.nodebug.wasm.gz": 8905,
"total": 26595,
"total_gz": 12512,
"sent": [
"a (memory)",
"b (emscripten_get_now)",
Expand Down
8 changes: 4 additions & 4 deletions test/codesize/test_codesize_minimal_pthreads_memgrowth.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"a.out.js": 7766,
"a.out.js.gz": 3812,
"a.out.nodebug.wasm": 19266,
"a.out.nodebug.wasm.gz": 8935,
"total": 27032,
"total_gz": 12747,
"a.out.nodebug.wasm": 19234,
"a.out.nodebug.wasm.gz": 8919,
"total": 27000,
"total_gz": 12731,
"sent": [
"a (memory)",
"b (emscripten_get_now)",
Expand Down
14 changes: 12 additions & 2 deletions test/pthread/test_pthread_cancel_async.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,24 @@
#include <assert.h>
#include <unistd.h>
#include <errno.h>

#ifdef __EMSCRIPTEN__
#include <emscripten/console.h>
#else
void emscripten_out(const char* msg) {
printf("%s\n", msg);
}

void emscripten_outf(const char* msg, ...) {
printf("%s\n", msg);
}
#endif

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
_Atomic long res = 43;
_Atomic int started = false;

static void cleanup_handler(void *arg)
{
static void cleanup_handler(void *arg) {
long a = (long)arg;
emscripten_outf("Called clean-up handler with arg %ld", a);
res -= a;
Expand Down
Loading