Skip to content

Commit 0c07c15

Browse files
authored
Include implemenation of musl's __lock/__unlock functions. NFC (#16129)
The functions `__lock` and `__unlock` are never called directly within musl but always via the `LOCK()` and `UNLOCK()` macros. They are implemented internally using an atomic integer along with the `__wake` and `__futexwait` internal function which emscripten already supports. Not to be confused with `__lockfile/__unlockfile` which are used to implement the `FLOCK()/FUNLOCK()` macros (which we already support and have enabled). In theory this could help remove data races and crashed within musl. In practice many of the uses of `LOCK/UNLOCK` are in places not compiled into emscripten. However I noticed at least these 3 that we do depend on and they do look useful/valid: - stdio/ofl.c: Open file lock used in fclose.c/fflush.c/__stdio_exit.c (We don't use __stdio_exit.c under emscripten) - random/srandom: Used as a mutex for the prng generator - dirent/rewinddir/seekdir: Used a mutex on an open directory handle
1 parent 1adfc09 commit 0c07c15

File tree

5 files changed

+18
-16
lines changed

5 files changed

+18
-16
lines changed

system/lib/libc/extras.c

Lines changed: 0 additions & 12 deletions
This file was deleted.

system/lib/pthread/library_pthread_stub.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,10 @@ int sem_destroy(sem_t *sem) {
389389

390390
void __wait(volatile int *addr, volatile int *waiters, int val, int priv) {}
391391

392+
void __lock(void* ptr) {}
393+
394+
void __unlock(void* ptr) {}
395+
392396
// When pthreads is not enabled, we can't use the Atomics futex api to do
393397
// proper sleeps, so simulate a busy spin wait loop instead.
394398
void emscripten_thread_sleep(double msecs) {

system/lib/pthread/pthread_create.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,17 @@ int __pthread_create(pthread_t* restrict res,
144144
#endif
145145

146146
//printf("start __pthread_create: %p\n", self);
147+
148+
// Set libc.need_locks before calling __pthread_create_js since
149+
// by the time it returns the thread could be running and we
150+
// want libc.need_locks to be set from the moment it starts.
151+
if (!libc.threads_minus_1++) libc.need_locks = 1;
152+
147153
int rtn = __pthread_create_js(new, attrp, entry, arg);
148-
if (rtn != 0)
154+
if (rtn != 0) {
155+
if (!--libc.threads_minus_1) libc.need_locks = 0;
149156
return rtn;
157+
}
150158

151159
// TODO(sbc): Implement circular list of threads
152160
/*
@@ -209,6 +217,8 @@ void _emscripten_thread_exit(void* result) {
209217

210218
free_tls_data();
211219

220+
if (!--libc.threads_minus_1) libc.need_locks = 0;
221+
212222
// TODO(sbc): Implement circular list of threads
213223
/*
214224
__tl_lock();

tests/other/metadce/minimal_main_Oz_USE_PTHREADS_PROXY_TO_PTHREAD.funcs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ $_emscripten_thread_init
2121
$_main_thread
2222
$a_cas
2323
$a_dec
24-
$a_inc.1
24+
$a_fetch_add
25+
$a_inc
2526
$a_swap
2627
$add
2728
$dispose_chunk

tools/system_libs.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -817,7 +817,7 @@ def get_files(self):
817817

818818
if self.is_mt:
819819
ignore += [
820-
'clone.c', '__lock.c',
820+
'clone.c',
821821
'pthread_create.c',
822822
'pthread_kill.c', 'pthread_sigmask.c',
823823
'__set_thread_area.c', 'synccall.c',
@@ -961,7 +961,6 @@ def get_files(self):
961961
path='system/lib/libc',
962962
filenames=[
963963
'dynlink.c',
964-
'extras.c',
965964
'wasi-helpers.c',
966965
'emscripten_get_heap_size.c',
967966
'raise.c',

0 commit comments

Comments
 (0)