Skip to content

Commit b27d542

Browse files
committed
Remove loop from emscripten_thread_sleep. NFC
We have code in the lower level emscrpeten_futex_wait that take care of splitting up the wait for the main runtime thread. For normal pthreads I don't see any need to run the message queue while the thread is sleeping like this. Instead, it can run from the event loop, or explicitly run. Followup to emscripten-core#26471
1 parent f8e6e4b commit b27d542

File tree

3 files changed

+26
-42
lines changed

3 files changed

+26
-42
lines changed

system/lib/pthread/library_pthread.c

Lines changed: 17 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -65,54 +65,33 @@ int sched_get_priority_min(int policy) {
6565
return 0;
6666
}
6767

68-
int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *restrict attr, int *restrict prioceiling)
69-
{
68+
int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *restrict attr, int *restrict prioceiling) {
7069
// Not supported either in Emscripten or musl, return a faked value.
7170
if (prioceiling) *prioceiling = 99;
7271
return 0;
7372
}
7473

75-
int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *attr, int prioceiling)
76-
{
74+
int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *attr, int prioceiling) {
7775
// Not supported either in Emscripten or musl, return an error.
7876
return EPERM;
7977
}
8078

81-
static uint32_t dummyZeroAddress = 0;
82-
8379
void emscripten_thread_sleep(double msecs) {
84-
double now = emscripten_get_now();
85-
double target = now + msecs;
86-
87-
// If we have less than this many msecs left to wait, busy spin that instead.
88-
double min_ms_slice_to_sleep = 0.1;
89-
90-
// Break up sleeping so that we process proxied work at regular intervals.
91-
// TODO(sbc): This should be removed and/or moved down into
92-
// `emscripten_futex_wait`.
93-
double max_ms_slice_to_sleep = 100;
94-
95-
emscripten_conditional_set_current_thread_status(
96-
EM_THREAD_STATUS_RUNNING, EM_THREAD_STATUS_SLEEPING);
97-
98-
do {
99-
// Keep processing the main loop of the calling thread.
100-
__pthread_testcancel(); // pthreads spec: sleep is a cancellation point, so must test if this
101-
// thread is cancelled during the sleep.
102-
emscripten_current_thread_process_queued_calls();
103-
104-
now = emscripten_get_now();
105-
double ms_to_sleep = target - now;
106-
if (ms_to_sleep < min_ms_slice_to_sleep)
107-
continue;
108-
if (ms_to_sleep > max_ms_slice_to_sleep)
109-
ms_to_sleep = max_ms_slice_to_sleep;
110-
emscripten_futex_wait(&dummyZeroAddress, 0, ms_to_sleep);
111-
now = emscripten_get_now();
112-
} while (now < target);
113-
114-
emscripten_conditional_set_current_thread_status(
115-
EM_THREAD_STATUS_SLEEPING, EM_THREAD_STATUS_RUNNING);
80+
// We include emscripten_current_thread_process_queued_calls before and
81+
// after sleeping since that is how we recieve "async" signals.
82+
// We include
83+
// We include __pthread_testcancel here becuase clock_nanosleep is
84+
// a pthread cancelation point.
85+
emscripten_current_thread_process_queued_calls();
86+
__pthread_testcancel();
87+
emscripten_conditional_set_current_thread_status(EM_THREAD_STATUS_RUNNING,
88+
EM_THREAD_STATUS_SLEEPING);
89+
uint32_t dummyZeroAddress = 0;
90+
emscripten_futex_wait(&dummyZeroAddress, 0, msecs);
91+
emscripten_conditional_set_current_thread_status(EM_THREAD_STATUS_SLEEPING,
92+
EM_THREAD_STATUS_RUNNING);
93+
emscripten_current_thread_process_queued_calls();
94+
__pthread_testcancel();
11695
}
11796

11897
static struct pthread __main_pthread;

system/lib/pthread/library_pthread_stub.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,9 @@ int pthread_cancel(pthread_t thread) {
231231
return 0;
232232
}
233233

234-
void pthread_testcancel() {}
234+
void __pthread_testcancel() {}
235+
236+
weak_alias(__pthread_testcancel, pthread_testcancel);
235237

236238
_Noreturn void __pthread_exit(void* status) {
237239
exit(0);

test/pthread/test_pthread_kill.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,26 @@
55

66
#include <pthread.h>
77
#include <sys/types.h>
8+
#include <stdbool.h>
89
#include <stdio.h>
910
#include <stdlib.h>
1011
#include <assert.h>
1112
#include <unistd.h>
1213
#include <errno.h>
1314
#include <signal.h>
1415

16+
#include <emscripten/console.h>
17+
1518
pthread_cond_t started_cond = PTHREAD_COND_INITIALIZER;
1619
pthread_mutex_t started_lock = PTHREAD_MUTEX_INITIALIZER;
17-
_Atomic int got_term_signal = 0;
20+
_Atomic bool got_term_signal = false;
1821

1922
pthread_t thr;
2023

2124
void signal_handler(int sig, siginfo_t * info, void * arg) {
2225
printf("signal: %d onthread=%d\n", sig, pthread_self() == thr);
2326
if (sig == SIGTERM) {
24-
got_term_signal = 1;
27+
got_term_signal = true;
2528
}
2629
}
2730

@@ -63,9 +66,9 @@ int main() {
6366
printf("thread has started, sending SIGTERM\n");
6467

6568
s = pthread_kill(thr, SIGTERM);
69+
assert(s == 0);
6670
printf("SIGTERM sent\n");
6771

68-
assert(s == 0);
6972

7073
pthread_join(thr, NULL);
7174
return 0;

0 commit comments

Comments
 (0)