Skip to content

Commit ba84d40

Browse files
authored
Simplify wait in slices logic. NFC. (#15739)
1 parent 5217a0e commit ba84d40

File tree

4 files changed

+28
-28
lines changed

4 files changed

+28
-28
lines changed

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

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#include <math.h>
66
#include <emscripten/threading.h>
77
#include <emscripten/emscripten.h>
8-
#include "pthread_impl.h"
98
#else
109
#include "futex.h"
1110
#endif
@@ -61,6 +60,10 @@ int __timedwait_cp(volatile int *addr, int val,
6160
#ifdef __EMSCRIPTEN__
6261
double msecsToSleep = top ? (top->tv_sec * 1000 + top->tv_nsec / 1000000.0) : INFINITY;
6362
int is_runtime_thread = emscripten_is_main_runtime_thread();
63+
64+
// Main runtime thread may need to run proxied calls, so sleep in very small slices to be responsive.
65+
double max_ms_slice_to_sleep = is_runtime_thread ? 1 : 100;
66+
6467
// cp suffix in the function name means "cancellation point", so this wait can be cancelled
6568
// by the users unless current threads cancelability is set to PTHREAD_CANCEL_DISABLE
6669
// which may be either done by the user of __timedwait() function.
@@ -77,16 +80,17 @@ int __timedwait_cp(volatile int *addr, int val,
7780
}
7881
// Assist other threads by executing proxied operations that are effectively singlethreaded.
7982
if (is_runtime_thread) emscripten_main_thread_process_queued_calls();
80-
// Must wait in slices in case this thread is cancelled in between.
81-
double waitMsecs = sleepUntilTime - emscripten_get_now();
82-
if (waitMsecs <= 0) {
83+
84+
msecsToSleep = sleepUntilTime - emscripten_get_now();
85+
if (msecsToSleep <= 0) {
8386
r = ETIMEDOUT;
8487
break;
8588
}
86-
if (waitMsecs > 100) waitMsecs = 100; // non-main threads can sleep in longer slices.
87-
if (is_runtime_thread && waitMsecs > 1) waitMsecs = 1; // the runtime thread may need to run proxied calls, so sleep in very small slices to be responsive.
88-
r = -emscripten_futex_wait((void*)addr, val, waitMsecs);
89-
} while(r == ETIMEDOUT);
89+
// Must wait in slices in case this thread is cancelled in between.
90+
if (msecsToSleep > max_ms_slice_to_sleep)
91+
msecsToSleep = max_ms_slice_to_sleep;
92+
r = -emscripten_futex_wait((void*)addr, val, msecsToSleep);
93+
} while (r == ETIMEDOUT);
9094
} else {
9195
// Can wait in one go.
9296
r = -emscripten_futex_wait((void*)addr, val, msecsToSleep);

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

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,12 @@ void __wait(volatile int *addr, volatile int *waiters, int val, int priv)
1616
if (waiters) a_inc(waiters);
1717
#ifdef __EMSCRIPTEN__
1818
int is_runtime_thread = emscripten_is_main_runtime_thread();
19+
20+
// Main runtime thread may need to run proxied calls, so sleep in very small slices to be responsive.
21+
double max_ms_slice_to_sleep = is_runtime_thread ? 1 : 100;
22+
1923
while (*addr==val) {
2024
if (is_runtime_thread || pthread_self()->cancelasync == PTHREAD_CANCEL_ASYNCHRONOUS) {
21-
// Must wait in slices in case this thread is cancelled in between.
2225
int e;
2326
do {
2427
if (pthread_self()->cancel) {
@@ -27,10 +30,9 @@ void __wait(volatile int *addr, volatile int *waiters, int val, int priv)
2730
}
2831
// Assist other threads by executing proxied operations that are effectively singlethreaded.
2932
if (is_runtime_thread) emscripten_main_thread_process_queued_calls();
30-
// Main thread waits in _very_ small slices so that it stays responsive to assist proxied
31-
// pthread calls.
32-
e = emscripten_futex_wait((void*)addr, val, is_runtime_thread ? 1 : 100);
33-
} while(e == -ETIMEDOUT);
33+
// Must wait in slices in case this thread is cancelled in between.
34+
e = emscripten_futex_wait((void*)addr, val, max_ms_slice_to_sleep);
35+
} while (e == -ETIMEDOUT);
3436
} else {
3537
// Can wait in one go.
3638
emscripten_futex_wait((void*)addr, val, INFINITY);

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,11 @@ int pthread_barrier_wait(pthread_barrier_t *b)
9393
if (is_runtime_thread) {
9494
int e;
9595
do {
96-
// Main thread waits in _very_ small slices so that it stays responsive to assist proxied
97-
// pthread calls.
96+
// Main runtime thread may need to run proxied calls, so sleep in very small slices to be responsive.
9897
e = emscripten_futex_wait(&inst->finished, 1, 1);
9998
// Assist other threads by executing proxied operations that are effectively singlethreaded.
10099
emscripten_main_thread_process_queued_calls();
101-
} while(e == -ETIMEDOUT);
100+
} while (e == -ETIMEDOUT);
102101
} else {
103102
// Can wait in one go.
104103
emscripten_futex_wait(&inst->finished, 1, INFINITY);

system/lib/pthread/library_pthread.c

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,6 @@ void emscripten_thread_sleep(double msecs) {
8787
double now = emscripten_get_now();
8888
double target = now + msecs;
8989

90-
__pthread_testcancel(); // pthreads spec: sleep is a cancellation point, so must test if this
91-
// thread is cancelled during the sleep.
92-
emscripten_current_thread_process_queued_calls();
93-
9490
// If we have less than this many msecs left to wait, busy spin that instead.
9591
double min_ms_slice_to_sleep = 0.1;
9692

@@ -99,23 +95,22 @@ void emscripten_thread_sleep(double msecs) {
9995

10096
emscripten_conditional_set_current_thread_status(
10197
EM_THREAD_STATUS_RUNNING, EM_THREAD_STATUS_SLEEPING);
102-
now = emscripten_get_now();
103-
while (now < target) {
98+
99+
do {
104100
// Keep processing the main loop of the calling thread.
105101
__pthread_testcancel(); // pthreads spec: sleep is a cancellation point, so must test if this
106102
// thread is cancelled during the sleep.
107103
emscripten_current_thread_process_queued_calls();
108104

109105
now = emscripten_get_now();
110106
double ms_to_sleep = target - now;
111-
if (ms_to_sleep > max_ms_slice_to_sleep) {
107+
if (ms_to_sleep < min_ms_slice_to_sleep)
108+
continue;
109+
if (ms_to_sleep > max_ms_slice_to_sleep)
112110
ms_to_sleep = max_ms_slice_to_sleep;
113-
}
114-
if (ms_to_sleep >= min_ms_slice_to_sleep) {
115-
emscripten_futex_wait(&dummyZeroAddress, 0, ms_to_sleep);
116-
}
111+
emscripten_futex_wait(&dummyZeroAddress, 0, ms_to_sleep);
117112
now = emscripten_get_now();
118-
};
113+
} while (now < target);
119114

120115
emscripten_conditional_set_current_thread_status(
121116
EM_THREAD_STATUS_SLEEPING, EM_THREAD_STATUS_RUNNING);

0 commit comments

Comments
 (0)