diff --git a/libc/calls/fcntl-nt.c b/libc/calls/fcntl-nt.c index a10b585f3e0..77b8331a16b 100644 --- a/libc/calls/fcntl-nt.c +++ b/libc/calls/fcntl-nt.c @@ -51,6 +51,7 @@ #include "libc/sysv/consts/fio.h" #include "libc/sysv/consts/o.h" #include "libc/sysv/errfuns.h" +#include "libc/thread/posixthread.internal.h" #include "libc/thread/thread.h" struct FileLock { @@ -67,7 +68,9 @@ struct FileLocks { struct FileLock *free; }; -static struct FileLocks g_locks; +static struct FileLocks g_locks = { + .mu = PTHREAD_MUTEX_INITIALIZER, +}; static textwindows struct FileLock *NewFileLock(void) { struct FileLock *fl; @@ -110,7 +113,7 @@ static textwindows bool EqualsFileLock(struct FileLock *fl, int64_t off, textwindows void sys_fcntl_nt_lock_cleanup(int fd) { struct FileLock *fl, *ft, **flp; - pthread_mutex_lock(&g_locks.mu); + _pthread_mutex_lock(&g_locks.mu); for (flp = &g_locks.list, fl = *flp; fl;) { if (fl->fd == fd) { *flp = fl->next; @@ -122,7 +125,7 @@ textwindows void sys_fcntl_nt_lock_cleanup(int fd) { fl = *flp; } } - pthread_mutex_unlock(&g_locks.mu); + _pthread_mutex_unlock(&g_locks.mu); } static textwindows int64_t GetfileSize(int64_t handle) { @@ -353,9 +356,9 @@ textwindows int sys_fcntl_nt(int fd, int cmd, uintptr_t arg) { } else if (cmd == F_SETLK || cmd == F_SETLKW || cmd == F_GETLK) { struct Fd *f = g_fds.p + fd; if (f->cursor) { - pthread_mutex_lock(&g_locks.mu); + _pthread_mutex_lock(&g_locks.mu); rc = sys_fcntl_nt_lock(f, fd, cmd, arg); - pthread_mutex_unlock(&g_locks.mu); + _pthread_mutex_unlock(&g_locks.mu); } else { rc = ebadf(); } diff --git a/libc/calls/internal.h b/libc/calls/internal.h index 3a3c8160c60..80ffd0c58fc 100644 --- a/libc/calls/internal.h +++ b/libc/calls/internal.h @@ -34,6 +34,7 @@ int64_t GetConsoleOutputHandle(void); void EchoConsoleNt(const char *, size_t, bool); int IsWindowsExecutable(int64_t, const char16_t *); void InterceptTerminalCommands(const char *, size_t); +void sys_read_nt_wipe_keystrokes(void); forceinline bool __isfdopen(int fd) { return 0 <= fd && fd < g_fds.n && g_fds.p[fd].kind != kFdEmpty; diff --git a/libc/calls/read-nt.c b/libc/calls/read-nt.c index 9ac353a63c6..6a223a63676 100644 --- a/libc/calls/read-nt.c +++ b/libc/calls/read-nt.c @@ -136,10 +136,15 @@ struct Keystrokes { struct Keystroke pool[512]; }; -static struct Keystrokes __keystroke; +static struct Keystrokes __keystroke = { + .lock = PTHREAD_MUTEX_INITIALIZER, +}; -textwindows void WipeKeystrokes(void) { +textwindows void sys_read_nt_wipe_keystrokes(void) { + pthread_mutex_t lock = __keystroke.lock; bzero(&__keystroke, sizeof(__keystroke)); + __keystroke.lock = lock; + _pthread_mutex_wipe_np(&__keystroke.lock); } textwindows static void FreeKeystrokeImpl(struct Dll *key) { @@ -191,11 +196,11 @@ textwindows static void InitConsole(void) { } textwindows static void LockKeystrokes(void) { - pthread_mutex_lock(&__keystroke.lock); + _pthread_mutex_lock(&__keystroke.lock); } textwindows static void UnlockKeystrokes(void) { - pthread_mutex_unlock(&__keystroke.lock); + _pthread_mutex_unlock(&__keystroke.lock); } textwindows int64_t GetConsoleInputHandle(void) { diff --git a/libc/dlopen/dlopen.c b/libc/dlopen/dlopen.c index 3f56cff8cc0..57767d7bb1d 100644 --- a/libc/dlopen/dlopen.c +++ b/libc/dlopen/dlopen.c @@ -57,6 +57,7 @@ #include "libc/sysv/consts/prot.h" #include "libc/sysv/errfuns.h" #include "libc/temp.h" +#include "libc/thread/posixthread.internal.h" #include "libc/thread/thread.h" #include "libc/thread/tls.h" @@ -131,6 +132,8 @@ struct { long __sysv2nt14(); long foreign_tramp(); +void __dlopen_lock(void); +void __dlopen_unlock(void); static _Thread_local char dlerror_buf[128]; @@ -435,14 +438,13 @@ static dontinline char *foreign_alloc_block(void) { static dontinline void *foreign_alloc(size_t n) { void *res; static char *block; - static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; - pthread_mutex_lock(&lock); + __dlopen_lock(); if (!block || READ32LE(block) + n > 65536) if (!(block = foreign_alloc_block())) return 0; res = block + READ32LE(block); WRITE32LE(block, READ32LE(block) + n); - pthread_mutex_unlock(&lock); + __dlopen_unlock(); return res; } diff --git a/libc/intrin/cursor.c b/libc/intrin/cursor.c index e0c686d4f53..b89b1be2773 100644 --- a/libc/intrin/cursor.c +++ b/libc/intrin/cursor.c @@ -20,16 +20,13 @@ #include "libc/intrin/atomic.h" #include "libc/intrin/fds.h" #include "libc/runtime/runtime.h" +#include "libc/thread/posixthread.internal.h" struct Cursor *__cursor_new(void) { struct Cursor *c; if ((c = _mapanon(sizeof(struct Cursor)))) { if ((c->shared = _mapshared(sizeof(struct CursorShared)))) { - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); - pthread_mutex_init(&c->shared->lock, &attr); - pthread_mutexattr_destroy(&attr); + c->shared->lock = (pthread_mutex_t)PTHREAD_SHARED_MUTEX_INITIALIZER_NP; } else { munmap(c, sizeof(struct Cursor)); c = 0; @@ -56,9 +53,9 @@ int __cursor_unref(struct Cursor *c) { } void __cursor_lock(struct Cursor *c) { - pthread_mutex_lock(&c->shared->lock); + _pthread_mutex_lock(&c->shared->lock); } void __cursor_unlock(struct Cursor *c) { - pthread_mutex_unlock(&c->shared->lock); + _pthread_mutex_unlock(&c->shared->lock); } diff --git a/libc/intrin/cxalock.c b/libc/intrin/cxalock.c index f7211d7d317..cb5256757ff 100644 --- a/libc/intrin/cxalock.c +++ b/libc/intrin/cxalock.c @@ -17,14 +17,15 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/intrin/cxaatexit.h" +#include "libc/thread/posixthread.internal.h" #include "libc/thread/thread.h" pthread_mutex_t __cxa_lock_obj = PTHREAD_MUTEX_INITIALIZER; void __cxa_lock(void) { - pthread_mutex_lock(&__cxa_lock_obj); + _pthread_mutex_lock(&__cxa_lock_obj); } void __cxa_unlock(void) { - pthread_mutex_unlock(&__cxa_lock_obj); + _pthread_mutex_unlock(&__cxa_lock_obj); } diff --git a/libc/intrin/dlopen.c b/libc/intrin/dlopen.c new file mode 100644 index 00000000000..7191d0ffb7d --- /dev/null +++ b/libc/intrin/dlopen.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi │ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2024 Justine Alexandra Roberts Tunney │ +│ │ +│ Permission to use, copy, modify, and/or distribute this software for │ +│ any purpose with or without fee is hereby granted, provided that the │ +│ above copyright notice and this permission notice appear in all copies. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ +│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ +│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ +│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ +│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ +│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ +│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ +│ PERFORMANCE OF THIS SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/thread/posixthread.internal.h" +#include "libc/thread/thread.h" + +pthread_mutex_t __dlopen_lock_obj = PTHREAD_MUTEX_INITIALIZER; + +void __dlopen_lock(void) { + _pthread_mutex_lock(&__dlopen_lock_obj); +} + +void __dlopen_unlock(void) { + _pthread_mutex_unlock(&__dlopen_lock_obj); +} diff --git a/libc/intrin/fds_lock.c b/libc/intrin/fds_lock.c index c32367d8544..1e1ddcc3273 100644 --- a/libc/intrin/fds_lock.c +++ b/libc/intrin/fds_lock.c @@ -17,12 +17,13 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/state.internal.h" +#include "libc/thread/posixthread.internal.h" #include "libc/thread/thread.h" void __fds_lock(void) { - pthread_mutex_lock(&__fds_lock_obj); + _pthread_mutex_lock(&__fds_lock_obj); } void __fds_unlock(void) { - pthread_mutex_unlock(&__fds_lock_obj); + _pthread_mutex_unlock(&__fds_lock_obj); } diff --git a/libc/intrin/itimer.c b/libc/intrin/itimer.c index 595fc0a0080..4d18253960b 100644 --- a/libc/intrin/itimer.c +++ b/libc/intrin/itimer.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/thread/itimer.h" #include "libc/str/str.h" +#include "libc/thread/posixthread.internal.h" struct IntervalTimer __itimer = { .lock = PTHREAD_MUTEX_INITIALIZER, @@ -25,18 +26,18 @@ struct IntervalTimer __itimer = { }; textwindows void __itimer_lock(void) { - pthread_mutex_lock(&__itimer.lock); + _pthread_mutex_lock(&__itimer.lock); } textwindows void __itimer_unlock(void) { - pthread_mutex_unlock(&__itimer.lock); + _pthread_mutex_unlock(&__itimer.lock); } textwindows void __itimer_wipe_and_reset(void) { // timers aren't inherited by forked subprocesses bzero(&__itimer.it, sizeof(__itimer.it)); - pthread_mutex_wipe_np(&__itimer.lock); - pthread_cond_init(&__itimer.cond, 0); + _pthread_mutex_wipe_np(&__itimer.lock); + bzero(&__itimer.cond, sizeof(__itimer.cond)); __itimer.thread = 0; __itimer.once = 0; } diff --git a/libc/intrin/localtime_lock.c b/libc/intrin/localtime_lock.c index b8d2868607f..b7064c9a405 100644 --- a/libc/intrin/localtime_lock.c +++ b/libc/intrin/localtime_lock.c @@ -16,14 +16,15 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/thread/posixthread.internal.h" #include "third_party/tz/lock.h" pthread_mutex_t __localtime_lock_obj = PTHREAD_MUTEX_INITIALIZER; void __localtime_lock(void) { - pthread_mutex_lock(&__localtime_lock_obj); + _pthread_mutex_lock(&__localtime_lock_obj); } void __localtime_unlock(void) { - pthread_mutex_unlock(&__localtime_lock_obj); + _pthread_mutex_unlock(&__localtime_lock_obj); } diff --git a/libc/intrin/pthread_mutex_lock.c b/libc/intrin/pthread_mutex_lock.c index 9947bbc5ec1..e3dc8eca7e1 100644 --- a/libc/intrin/pthread_mutex_lock.c +++ b/libc/intrin/pthread_mutex_lock.c @@ -30,6 +30,7 @@ #include "libc/macros.h" #include "libc/runtime/internal.h" #include "libc/thread/lock.h" +#include "libc/thread/posixthread.internal.h" #include "libc/thread/thread.h" #include "libc/thread/tls.h" #include "third_party/nsync/mu.h" @@ -300,7 +301,7 @@ static errno_t pthread_mutex_lock_impl(pthread_mutex_t *mutex, * @see pthread_spin_lock() * @vforksafe */ -errno_t pthread_mutex_lock(pthread_mutex_t *mutex) { +errno_t _pthread_mutex_lock(pthread_mutex_t *mutex) { if (__tls_enabled && !__vforked) { errno_t err = pthread_mutex_lock_impl(mutex, false); LOCKTRACE("pthread_mutex_lock(%t) → %s", mutex, DescribeErrno(err)); @@ -323,7 +324,7 @@ errno_t pthread_mutex_lock(pthread_mutex_t *mutex) { * @raise EDEADLK if `mutex` is `PTHREAD_MUTEX_ERRORCHECK` and the * current thread already holds this mutex */ -errno_t pthread_mutex_trylock(pthread_mutex_t *mutex) { +errno_t _pthread_mutex_trylock(pthread_mutex_t *mutex) { if (__tls_enabled && !__vforked) { errno_t err = pthread_mutex_lock_impl(mutex, true); LOCKTRACE("pthread_mutex_trylock(%t) → %s", mutex, DescribeErrno(err)); @@ -333,3 +334,6 @@ errno_t pthread_mutex_trylock(pthread_mutex_t *mutex) { return 0; } } + +__weak_reference(_pthread_mutex_lock, pthread_mutex_lock); +__weak_reference(_pthread_mutex_trylock, pthread_mutex_trylock); diff --git a/libc/intrin/pthread_mutex_unlock.c b/libc/intrin/pthread_mutex_unlock.c index 2a088beba5a..782699ec7b8 100644 --- a/libc/intrin/pthread_mutex_unlock.c +++ b/libc/intrin/pthread_mutex_unlock.c @@ -28,6 +28,7 @@ #include "libc/intrin/weaken.h" #include "libc/runtime/internal.h" #include "libc/thread/lock.h" +#include "libc/thread/posixthread.internal.h" #include "libc/thread/thread.h" #include "third_party/nsync/mu.h" @@ -166,7 +167,7 @@ static errno_t pthread_mutex_unlock_impl(pthread_mutex_t *mutex) { * @raises EPERM if mutex ownership isn't acceptable * @vforksafe */ -errno_t pthread_mutex_unlock(pthread_mutex_t *mutex) { +errno_t _pthread_mutex_unlock(pthread_mutex_t *mutex) { if (__tls_enabled && !__vforked) { errno_t err = pthread_mutex_unlock_impl(mutex); LOCKTRACE("pthread_mutex_unlock(%t) → %s", mutex, DescribeErrno(err)); @@ -176,3 +177,5 @@ errno_t pthread_mutex_unlock(pthread_mutex_t *mutex) { return 0; } } + +__weak_reference(_pthread_mutex_unlock, pthread_mutex_unlock); diff --git a/libc/intrin/pthread_mutex_wipe_np.c b/libc/intrin/pthread_mutex_wipe_np.c index 0f0b5cb2608..e49c3512fc2 100644 --- a/libc/intrin/pthread_mutex_wipe_np.c +++ b/libc/intrin/pthread_mutex_wipe_np.c @@ -18,12 +18,13 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/str/str.h" #include "libc/thread/lock.h" +#include "libc/thread/posixthread.internal.h" #include "libc/thread/thread.h" /** * Unlocks mutex from child process after fork. */ -int pthread_mutex_wipe_np(pthread_mutex_t *mutex) { +int _pthread_mutex_wipe_np(pthread_mutex_t *mutex) { void *edges = mutex->_edges; uint64_t word = mutex->_word; bzero(mutex, sizeof(*mutex)); @@ -31,3 +32,5 @@ int pthread_mutex_wipe_np(pthread_mutex_t *mutex) { mutex->_edges = edges; return 0; } + +__weak_reference(_pthread_mutex_wipe_np, pthread_mutex_wipe_np); diff --git a/libc/intrin/pthreadlock.c b/libc/intrin/pthreadlock.c index 7db5827603f..085f5bba0ef 100644 --- a/libc/intrin/pthreadlock.c +++ b/libc/intrin/pthreadlock.c @@ -22,9 +22,9 @@ alignas(64) pthread_mutex_t __pthread_lock_obj = PTHREAD_MUTEX_INITIALIZER; void _pthread_lock(void) { - pthread_mutex_lock(&__pthread_lock_obj); + _pthread_mutex_lock(&__pthread_lock_obj); } void _pthread_unlock(void) { - pthread_mutex_unlock(&__pthread_lock_obj); + _pthread_mutex_unlock(&__pthread_lock_obj); } diff --git a/libc/intrin/rand64.c b/libc/intrin/rand64.c index 97b687a2d32..e0da32f7d92 100644 --- a/libc/intrin/rand64.c +++ b/libc/intrin/rand64.c @@ -22,6 +22,7 @@ #include "libc/runtime/runtime.h" #include "libc/str/str.h" #include "libc/sysv/consts/auxv.h" +#include "libc/thread/posixthread.internal.h" #include "libc/thread/thread.h" #include "libc/thread/tls.h" @@ -42,7 +43,7 @@ pthread_mutex_t __rand64_lock_obj = PTHREAD_MUTEX_INITIALIZER; uint64_t _rand64(void) { void *p; uint128_t s; - pthread_mutex_lock(&__rand64_lock_obj); + _pthread_mutex_lock(&__rand64_lock_obj); if (__pid == _rand64_pid) { s = _rand64_pool; // normal path } else { @@ -63,6 +64,6 @@ uint64_t _rand64(void) { _rand64_pid = __pid; } _rand64_pool = (s *= 15750249268501108917ull); // lemur64 - pthread_mutex_unlock(&__rand64_lock_obj); + _pthread_mutex_unlock(&__rand64_lock_obj); return s >> 64; } diff --git a/libc/intrin/sig.c b/libc/intrin/sig.c index 56866464f7d..5a77cfe9bc1 100644 --- a/libc/intrin/sig.c +++ b/libc/intrin/sig.c @@ -682,7 +682,7 @@ textwindows dontinstrument static uint32_t __sig_worker(void *arg) { __maps_track((char *)(((uintptr_t)sp + __pagesize - 1) & -__pagesize) - STKSZ, STKSZ); for (;;) { - pthread_mutex_lock(&__sig_worker_lock); + _pthread_mutex_lock(&__sig_worker_lock); // dequeue all pending signals and fire them off. if there's no // thread that can handle them then __sig_generate will requeue @@ -732,7 +732,7 @@ textwindows dontinstrument static uint32_t __sig_worker(void *arg) { } // wait until next scheduler quantum - pthread_mutex_unlock(&__sig_worker_lock); + _pthread_mutex_unlock(&__sig_worker_lock); Sleep(POLL_INTERVAL_MS); } return 0; diff --git a/libc/intrin/stack.c b/libc/intrin/stack.c index c77e9a8d095..09ee635b5e2 100644 --- a/libc/intrin/stack.c +++ b/libc/intrin/stack.c @@ -28,6 +28,7 @@ #include "libc/runtime/runtime.h" #include "libc/sysv/consts/map.h" #include "libc/sysv/consts/prot.h" +#include "libc/thread/posixthread.internal.h" #include "libc/thread/thread.h" /** @@ -67,15 +68,15 @@ static struct CosmoStacksConfig cosmo_stacks_config = { }; void cosmo_stack_lock(void) { - pthread_mutex_lock(&cosmo_stacks.lock); + _pthread_mutex_lock(&cosmo_stacks.lock); } void cosmo_stack_unlock(void) { - pthread_mutex_unlock(&cosmo_stacks.lock); + _pthread_mutex_unlock(&cosmo_stacks.lock); } void cosmo_stack_wipe(void) { - pthread_mutex_wipe_np(&cosmo_stacks.lock); + _pthread_mutex_wipe_np(&cosmo_stacks.lock); } static errno_t cosmo_stack_munmap(void *addr, size_t size) { diff --git a/libc/intrin/stdio.c b/libc/intrin/stdio.c index 9a6b75f2c06..f487b08674e 100644 --- a/libc/intrin/stdio.c +++ b/libc/intrin/stdio.c @@ -22,6 +22,7 @@ #include "libc/intrin/weaken.h" #include "libc/mem/mem.h" #include "libc/stdio/internal.h" +#include "libc/thread/posixthread.internal.h" #define STDIO_FILE_USE_AFTER_FREE 1 #define CORRUPT_STDIO_FILE_OBJECT 1 @@ -31,11 +32,11 @@ struct Stdio __stdio = { }; void __stdio_lock(void) { - pthread_mutex_lock(&__stdio.lock); + _pthread_mutex_lock(&__stdio.lock); } void __stdio_unlock(void) { - pthread_mutex_unlock(&__stdio.lock); + _pthread_mutex_unlock(&__stdio.lock); } static int refchk(int refs) { diff --git a/libc/mem/leaks.c b/libc/mem/leaks.c index c23ff989aab..ec422cb3b6d 100644 --- a/libc/mem/leaks.c +++ b/libc/mem/leaks.c @@ -40,12 +40,12 @@ struct Leak { static int leak_count; static struct Dll *leaks; static struct Dll *freaks; -static pthread_mutex_t lock; +static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; void __may_leak(void *alloc) { if (!alloc) return; - pthread_mutex_lock(&lock); + _pthread_mutex_lock(&lock); if (dll_is_empty(freaks)) { int g = __gransize; struct Leak *p = _mapanon(g); @@ -59,7 +59,7 @@ void __may_leak(void *alloc) { LEAK_CONTAINER(e)->alloc = alloc; dll_remove(&freaks, e); dll_make_first(&leaks, e); - pthread_mutex_unlock(&lock); + _pthread_mutex_unlock(&lock); } static void visitor(void *start, void *end, size_t used_bytes, void *arg) { diff --git a/libc/proc/execve-nt.greg.c b/libc/proc/execve-nt.greg.c index bd514b4ff27..c099880188a 100644 --- a/libc/proc/execve-nt.greg.c +++ b/libc/proc/execve-nt.greg.c @@ -52,7 +52,7 @@ extern pthread_mutex_t __sig_worker_lock; static void sys_execve_nt_abort(sigset_t sigmask) { _pthread_unlock(); - pthread_mutex_unlock(&__sig_worker_lock); + _pthread_mutex_unlock(&__sig_worker_lock); __sig_unblock(sigmask); } @@ -61,8 +61,8 @@ textwindows int sys_execve_nt(const char *program, char *const argv[], // execve() needs to be @asyncsignalsafe sigset_t sigmask = __sig_block(); - pthread_mutex_lock(&__sig_worker_lock); // order matters - _pthread_lock(); // order matters + _pthread_mutex_lock(&__sig_worker_lock); // order matters + _pthread_lock(); // order matters // new process should be a child of our parent int64_t hParentProcess; diff --git a/libc/proc/fork-nt.c b/libc/proc/fork-nt.c index f35500c78f1..c42140517eb 100644 --- a/libc/proc/fork-nt.c +++ b/libc/proc/fork-nt.c @@ -68,7 +68,6 @@ #ifdef __x86_64__ extern long __klog_handle; -void WipeKeystrokes(void); __msabi extern typeof(GetCurrentProcessId) *const __imp_GetCurrentProcessId; static textwindows wontreturn void AbortFork(const char *func, void *addr) { @@ -466,8 +465,6 @@ textwindows int sys_fork_nt(uint32_t dwCreationFlags) { // re-apply code morphing for function tracing if (ftrace_stackdigs) _weaken(__hook)(_weaken(ftrace_hook), _weaken(GetSymbolTable)()); - // reset core runtime services - WipeKeystrokes(); // notify pthread join atomic_store_explicit(&_pthread_static.ptid, GetCurrentThreadId(), memory_order_release); diff --git a/libc/proc/fork.c b/libc/proc/fork.c index a836b0102ff..42c194d27f9 100644 --- a/libc/proc/fork.c +++ b/libc/proc/fork.c @@ -17,6 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" +#include "libc/calls/internal.h" #include "libc/calls/sig.internal.h" #include "libc/calls/state.internal.h" #include "libc/calls/struct/sigset.internal.h" @@ -50,11 +51,14 @@ __msabi extern typeof(GetCurrentProcessId) *const __imp_GetCurrentProcessId; -extern pthread_mutex_t __rand64_lock_obj; -extern pthread_mutex_t __pthread_lock_obj; extern pthread_mutex_t __cxa_lock_obj; +extern pthread_mutex_t __dlopen_lock_obj; +extern pthread_mutex_t __pthread_lock_obj; +extern pthread_mutex_t __rand64_lock_obj; extern pthread_mutex_t __sig_worker_lock; +void __dlopen_lock(void); +void __dlopen_unlock(void); void nsync_mu_semaphore_sem_fork_child(void); // first and last and always @@ -79,7 +83,7 @@ static void fork_prepare_stdio(void) { f->forking = 1; __stdio_ref(f); __stdio_unlock(); - pthread_mutex_lock(&f->lock); + _pthread_mutex_lock(&f->lock); __stdio_unref(f); goto StartOver; } @@ -89,7 +93,7 @@ static void fork_parent_stdio(void) { struct Dll *e; for (e = dll_first(__stdio.files); e; e = dll_next(__stdio.files, e)) { FILE_CONTAINER(e)->forking = 0; - pthread_mutex_unlock(&FILE_CONTAINER(e)->lock); + _pthread_mutex_unlock(&FILE_CONTAINER(e)->lock); } __stdio_unlock(); } @@ -97,25 +101,26 @@ static void fork_parent_stdio(void) { static void fork_child_stdio(void) { struct Dll *e; for (e = dll_first(__stdio.files); e; e = dll_next(__stdio.files, e)) { - pthread_mutex_wipe_np(&FILE_CONTAINER(e)->lock); + _pthread_mutex_wipe_np(&FILE_CONTAINER(e)->lock); FILE_CONTAINER(e)->forking = 0; } - pthread_mutex_wipe_np(&__stdio.lock); + _pthread_mutex_wipe_np(&__stdio.lock); } static void fork_prepare(void) { - pthread_mutex_lock(&supreme_lock); + _pthread_mutex_lock(&supreme_lock); if (_weaken(_pthread_onfork_prepare)) _weaken(_pthread_onfork_prepare)(); fork_prepare_stdio(); __localtime_lock(); + __dlopen_lock(); __cxa_lock(); __gdtoa_lock1(); __gdtoa_lock(); _pthread_lock(); dlmalloc_pre_fork(); __fds_lock(); - pthread_mutex_lock(&__rand64_lock_obj); + _pthread_mutex_lock(&__rand64_lock_obj); if (_weaken(cosmo_stack_lock)) _weaken(cosmo_stack_lock)(); __maps_lock(); @@ -126,45 +131,48 @@ static void fork_parent(void) { __maps_unlock(); if (_weaken(cosmo_stack_unlock)) _weaken(cosmo_stack_unlock)(); - pthread_mutex_unlock(&__rand64_lock_obj); + _pthread_mutex_unlock(&__rand64_lock_obj); __fds_unlock(); dlmalloc_post_fork_parent(); _pthread_unlock(); __gdtoa_unlock(); __gdtoa_unlock1(); __cxa_unlock(); + __dlopen_unlock(); __localtime_unlock(); fork_parent_stdio(); if (_weaken(_pthread_onfork_parent)) _weaken(_pthread_onfork_parent)(); - pthread_mutex_unlock(&supreme_lock); + _pthread_mutex_unlock(&supreme_lock); } static void fork_child(void) { nsync_mu_semaphore_sem_fork_child(); if (_weaken(cosmo_stack_wipe)) _weaken(cosmo_stack_wipe)(); - pthread_mutex_wipe_np(&__rand64_lock_obj); - pthread_mutex_wipe_np(&__fds_lock_obj); + _pthread_mutex_wipe_np(&__dlopen_lock_obj); + _pthread_mutex_wipe_np(&__rand64_lock_obj); + _pthread_mutex_wipe_np(&__fds_lock_obj); dlmalloc_post_fork_child(); - pthread_mutex_wipe_np(&__gdtoa_lock_obj); - pthread_mutex_wipe_np(&__gdtoa_lock1_obj); + _pthread_mutex_wipe_np(&__gdtoa_lock_obj); + _pthread_mutex_wipe_np(&__gdtoa_lock1_obj); fork_child_stdio(); - pthread_mutex_wipe_np(&__pthread_lock_obj); - pthread_mutex_wipe_np(&__cxa_lock_obj); - pthread_mutex_wipe_np(&__localtime_lock_obj); + _pthread_mutex_wipe_np(&__pthread_lock_obj); + _pthread_mutex_wipe_np(&__cxa_lock_obj); + _pthread_mutex_wipe_np(&__localtime_lock_obj); if (IsWindows()) { // we don't bother locking the proc/itimer/sig locks above since // their state is reset in the forked child. nothing to protect. + sys_read_nt_wipe_keystrokes(); __proc_wipe_and_reset(); __itimer_wipe_and_reset(); - pthread_mutex_wipe_np(&__sig_worker_lock); + _pthread_mutex_wipe_np(&__sig_worker_lock); if (_weaken(__sig_init)) _weaken(__sig_init)(); } if (_weaken(_pthread_onfork_child)) _weaken(_pthread_onfork_child)(); - pthread_mutex_wipe_np(&supreme_lock); + _pthread_mutex_wipe_np(&supreme_lock); } int _fork(uint32_t dwCreationFlags) { diff --git a/libc/proc/proc.c b/libc/proc/proc.c index 56a5ff0a5ae..325b7645704 100644 --- a/libc/proc/proc.c +++ b/libc/proc/proc.c @@ -255,14 +255,14 @@ static textwindows void __proc_setup(void) { */ textwindows void __proc_lock(void) { cosmo_once(&__proc.once, __proc_setup); - pthread_mutex_lock(&__proc.lock); + _pthread_mutex_lock(&__proc.lock); } /** * Unlocks process tracker. */ textwindows void __proc_unlock(void) { - pthread_mutex_unlock(&__proc.lock); + _pthread_mutex_unlock(&__proc.lock); } /** @@ -273,7 +273,7 @@ textwindows void __proc_wipe_and_reset(void) { pthread_mutex_t lock = __proc.lock; bzero(&__proc, sizeof(__proc)); __proc.lock = lock; - pthread_mutex_wipe_np(&__proc.lock); + _pthread_mutex_wipe_np(&__proc.lock); } /** diff --git a/libc/stdio/dirstream.c b/libc/stdio/dirstream.c index ef11b674b42..f77f4e06ce8 100644 --- a/libc/stdio/dirstream.c +++ b/libc/stdio/dirstream.c @@ -49,6 +49,7 @@ #include "libc/sysv/consts/o.h" #include "libc/sysv/consts/s.h" #include "libc/sysv/errfuns.h" +#include "libc/thread/posixthread.internal.h" #include "libc/thread/thread.h" #include "libc/thread/tls.h" #include "libc/zip.h" @@ -134,11 +135,11 @@ struct dirent_netbsd { }; static void lockdir(DIR *dir) { - pthread_mutex_lock(&dir->lock); + _pthread_mutex_lock(&dir->lock); } static void unlockdir(DIR *dir) { - pthread_mutex_unlock(&dir->lock); + _pthread_mutex_unlock(&dir->lock); } static textwindows dontinline int fdopendir_nt(DIR *res, int fd) { diff --git a/libc/stdio/flockfile.c b/libc/stdio/flockfile.c index 61bac167bda..4b16a0778d8 100644 --- a/libc/stdio/flockfile.c +++ b/libc/stdio/flockfile.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" #include "libc/stdio/internal.h" +#include "libc/thread/posixthread.internal.h" #include "libc/thread/thread.h" /** @@ -25,5 +26,5 @@ */ void flockfile(FILE *f) { unassert(f != NULL); - pthread_mutex_lock(&f->lock); + _pthread_mutex_lock(&f->lock); } diff --git a/libc/stdio/funlockfile.c b/libc/stdio/funlockfile.c index b47f8ab9d72..cfeb7f53491 100644 --- a/libc/stdio/funlockfile.c +++ b/libc/stdio/funlockfile.c @@ -18,11 +18,12 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/stdio/internal.h" #include "libc/stdio/stdio.h" +#include "libc/thread/posixthread.internal.h" #include "libc/thread/thread.h" /** * Releases lock on stdio object. */ void funlockfile(FILE *f) { - pthread_mutex_unlock(&f->lock); + _pthread_mutex_unlock(&f->lock); } diff --git a/libc/testlib/testrunner.c b/libc/testlib/testrunner.c index 27ef2a63959..b8498e1eb7b 100644 --- a/libc/testlib/testrunner.c +++ b/libc/testlib/testrunner.c @@ -34,6 +34,7 @@ #include "libc/str/str.h" #include "libc/testlib/aspect.internal.h" #include "libc/testlib/testlib.h" +#include "libc/thread/posixthread.internal.h" #include "libc/thread/thread.h" #include "libc/x/x.h" @@ -52,7 +53,7 @@ void testlib_finish(void) { void testlib_error_enter(const char *file, const char *func) { ftrace_enabled(-1); strace_enabled(-1); - pthread_mutex_lock(&testlib_error_lock); + _pthread_mutex_lock(&testlib_error_lock); if (!IsWindows()) sys_getpid(); /* make strace easier to read */ if (!IsWindows()) @@ -67,7 +68,7 @@ void testlib_error_enter(const char *file, const char *func) { void testlib_error_leave(void) { strace_enabled(+1); ftrace_enabled(+1); - pthread_mutex_unlock(&testlib_error_lock); + _pthread_mutex_unlock(&testlib_error_lock); } wontreturn void testlib_abort(void) { diff --git a/libc/thread/itimer.c b/libc/thread/itimer.c index 5f3ba03af45..6a7cf2b8afe 100644 --- a/libc/thread/itimer.c +++ b/libc/thread/itimer.c @@ -34,6 +34,7 @@ #include "libc/sysv/consts/sig.h" #include "libc/sysv/errfuns.h" #include "libc/thread/itimer.h" +#include "libc/thread/posixthread.internal.h" #include "libc/thread/thread2.h" #include "libc/thread/tls.h" #ifdef __x86_64__ @@ -76,7 +77,7 @@ static textwindows dontinstrument uint32_t __itimer_worker(void *arg) { __sig_generate(SIGALRM, SI_TIMER); __itimer_lock(); struct timespec deadline = timeval_totimespec(waituntil); - pthread_cond_timedwait(&__itimer.cond, &__itimer.lock, &deadline); + _pthread_cond_timedwait(&__itimer.cond, &__itimer.lock, &deadline); __itimer_unlock(); } return 0; @@ -108,7 +109,7 @@ textwindows int sys_setitimer_nt(int which, const struct itimerval *neu, if (!timeval_iszero(config.it_value)) config.it_value = timeval_add(config.it_value, timeval_real()); __itimer.it = config; - pthread_cond_signal(&__itimer.cond); + _pthread_cond_signal(&__itimer.cond); } __itimer_unlock(); ALLOW_SIGNALS; diff --git a/libc/thread/posixthread.internal.h b/libc/thread/posixthread.internal.h index fe94dc066de..09f1f9ae5e0 100644 --- a/libc/thread/posixthread.internal.h +++ b/libc/thread/posixthread.internal.h @@ -98,6 +98,11 @@ extern _Atomic(unsigned) _pthread_count; extern struct PosixThread _pthread_static; extern _Atomic(pthread_key_dtor) _pthread_key_dtor[PTHREAD_KEYS_MAX]; +int _pthread_cond_signal(pthread_cond_t *) libcesque paramsnonnull(); +int _pthread_mutex_lock(pthread_mutex_t *) libcesque paramsnonnull(); +int _pthread_mutex_trylock(pthread_mutex_t *) libcesque paramsnonnull(); +int _pthread_mutex_unlock(pthread_mutex_t *) libcesque paramsnonnull(); +int _pthread_mutex_wipe_np(pthread_mutex_t *) libcesque paramsnonnull(); int _pthread_reschedule(struct PosixThread *) libcesque; int _pthread_setschedparam_freebsd(int, int, const struct sched_param *); int _pthread_tid(struct PosixThread *) libcesque; @@ -111,6 +116,13 @@ void _pthread_onfork_prepare(void) libcesque; void _pthread_unlock(void) libcesque; void _pthread_zombify(struct PosixThread *) libcesque; +int _pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *) libcesque + paramsnonnull(); + +int _pthread_cond_timedwait(pthread_cond_t *, pthread_mutex_t *, + const struct timespec *) libcesque + paramsnonnull((1, 2)); + forceinline pureconst struct PosixThread *_pthread_self(void) { return (struct PosixThread *)__get_tls()->tib_pthread; } diff --git a/libc/thread/pthread_atfork.c b/libc/thread/pthread_atfork.c index c7e32ed2c7c..ec8cc05fc91 100644 --- a/libc/thread/pthread_atfork.c +++ b/libc/thread/pthread_atfork.c @@ -63,17 +63,17 @@ static void _pthread_onfork(int i, const char *op) { } void _pthread_onfork_prepare(void) { - pthread_mutex_lock(&_atforks.lock); + _pthread_mutex_lock(&_atforks.lock); _pthread_onfork(0, "prepare"); } void _pthread_onfork_parent(void) { _pthread_onfork(1, "parent"); - pthread_mutex_unlock(&_atforks.lock); + _pthread_mutex_unlock(&_atforks.lock); } void _pthread_onfork_child(void) { - pthread_mutex_wipe_np(&_atforks.lock); + _pthread_mutex_wipe_np(&_atforks.lock); _pthread_onfork(2, "child"); } @@ -171,12 +171,12 @@ int pthread_atfork(atfork_f prepare, atfork_f parent, atfork_f child) { a->f[0] = prepare; a->f[1] = parent; a->f[2] = child; - pthread_mutex_lock(&_atforks.lock); + _pthread_mutex_lock(&_atforks.lock); a->p[0] = 0; a->p[1] = _atforks.list; if (_atforks.list) _atforks.list->p[0] = a; _atforks.list = a; - pthread_mutex_unlock(&_atforks.lock); + _pthread_mutex_unlock(&_atforks.lock); return 0; } diff --git a/libc/intrin/pthread_cond_init.c b/libc/thread/pthread_cond_init.c similarity index 100% rename from libc/intrin/pthread_cond_init.c rename to libc/thread/pthread_cond_init.c diff --git a/libc/thread/pthread_cond_signal.c b/libc/thread/pthread_cond_signal.c index df0de5bb425..fe6244d1ec3 100644 --- a/libc/thread/pthread_cond_signal.c +++ b/libc/thread/pthread_cond_signal.c @@ -43,7 +43,7 @@ __static_yoink("nsync_mu_trylock"); * @see pthread_cond_broadcast * @see pthread_cond_wait */ -errno_t pthread_cond_signal(pthread_cond_t *cond) { +errno_t _pthread_cond_signal(pthread_cond_t *cond) { #if PTHREAD_USE_NSYNC // do nothing if pthread_cond_timedwait() hasn't been called yet @@ -65,3 +65,5 @@ errno_t pthread_cond_signal(pthread_cond_t *cond) { cosmo_futex_wake((atomic_int *)&cond->_sequence, 1, cond->_pshared); return 0; } + +__weak_reference(_pthread_cond_signal, pthread_cond_signal); diff --git a/libc/thread/pthread_cond_timedwait.c b/libc/thread/pthread_cond_timedwait.c index cc39e5f3fbf..9e4daff39f3 100644 --- a/libc/thread/pthread_cond_timedwait.c +++ b/libc/thread/pthread_cond_timedwait.c @@ -49,7 +49,7 @@ static bool can_use_nsync(uint64_t muword) { static void pthread_cond_leave(void *arg) { struct PthreadWait *wait = (struct PthreadWait *)arg; - if (pthread_mutex_lock(wait->mutex)) + if (_pthread_mutex_lock(wait->mutex)) __builtin_trap(); atomic_fetch_sub_explicit(&wait->cond->_waiters, 1, memory_order_acq_rel); } @@ -68,7 +68,7 @@ static errno_t pthread_cond_timedwait_impl(pthread_cond_t *cond, // start waiting on condition variable atomic_fetch_add_explicit(&cond->_waiters, 1, memory_order_acq_rel); - if (pthread_mutex_unlock(mutex)) + if (_pthread_mutex_unlock(mutex)) __builtin_trap(); // wait for sequence change, timeout, or cancelation @@ -110,8 +110,8 @@ static errno_t pthread_cond_timedwait_impl(pthread_cond_t *cond, * @see pthread_cond_signal() * @cancelationpoint */ -errno_t pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, - const struct timespec *abstime) { +errno_t _pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, + const struct timespec *abstime) { // validate arguments struct PosixThread *pt; @@ -165,3 +165,5 @@ errno_t pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, END_CANCELATION_POINT; return err; } + +__weak_reference(_pthread_cond_timedwait, pthread_cond_timedwait); diff --git a/libc/thread/pthread_cond_wait.c b/libc/thread/pthread_cond_wait.c index df7d42dd194..e6ffd619c8a 100644 --- a/libc/thread/pthread_cond_wait.c +++ b/libc/thread/pthread_cond_wait.c @@ -16,6 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/thread/posixthread.internal.h" #include "libc/thread/thread.h" #include "libc/thread/thread2.h" @@ -39,6 +40,8 @@ * @see pthread_cond_signal * @cancelationpoint */ -errno_t pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) { +errno_t _pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) { return pthread_cond_timedwait(cond, mutex, 0); } + +__weak_reference(_pthread_cond_wait, pthread_cond_wait); diff --git a/libc/intrin/pthread_mutex_consistent.c b/libc/thread/pthread_mutex_consistent.c similarity index 100% rename from libc/intrin/pthread_mutex_consistent.c rename to libc/thread/pthread_mutex_consistent.c diff --git a/libc/intrin/pthread_mutex_destroy.c b/libc/thread/pthread_mutex_destroy.c similarity index 100% rename from libc/intrin/pthread_mutex_destroy.c rename to libc/thread/pthread_mutex_destroy.c diff --git a/libc/intrin/pthread_mutex_init.c b/libc/thread/pthread_mutex_init.c similarity index 100% rename from libc/intrin/pthread_mutex_init.c rename to libc/thread/pthread_mutex_init.c diff --git a/libc/intrin/pthread_mutexattr_destroy.c b/libc/thread/pthread_mutexattr_destroy.c similarity index 100% rename from libc/intrin/pthread_mutexattr_destroy.c rename to libc/thread/pthread_mutexattr_destroy.c diff --git a/libc/intrin/pthread_mutexattr_getpshared.c b/libc/thread/pthread_mutexattr_getpshared.c similarity index 100% rename from libc/intrin/pthread_mutexattr_getpshared.c rename to libc/thread/pthread_mutexattr_getpshared.c diff --git a/libc/intrin/pthread_mutexattr_gettype.c b/libc/thread/pthread_mutexattr_gettype.c similarity index 100% rename from libc/intrin/pthread_mutexattr_gettype.c rename to libc/thread/pthread_mutexattr_gettype.c diff --git a/libc/intrin/pthread_mutexattr_init.c b/libc/thread/pthread_mutexattr_init.c similarity index 100% rename from libc/intrin/pthread_mutexattr_init.c rename to libc/thread/pthread_mutexattr_init.c diff --git a/libc/intrin/pthread_mutexattr_setpshared.c b/libc/thread/pthread_mutexattr_setpshared.c similarity index 100% rename from libc/intrin/pthread_mutexattr_setpshared.c rename to libc/thread/pthread_mutexattr_setpshared.c diff --git a/libc/intrin/pthread_mutexattr_settype.c b/libc/thread/pthread_mutexattr_settype.c similarity index 100% rename from libc/intrin/pthread_mutexattr_settype.c rename to libc/thread/pthread_mutexattr_settype.c diff --git a/libc/intrin/pthread_spin_destroy.c b/libc/thread/pthread_spin_destroy.c similarity index 100% rename from libc/intrin/pthread_spin_destroy.c rename to libc/thread/pthread_spin_destroy.c diff --git a/libc/intrin/pthread_spin_init.c b/libc/thread/pthread_spin_init.c similarity index 100% rename from libc/intrin/pthread_spin_init.c rename to libc/thread/pthread_spin_init.c diff --git a/libc/intrin/pthread_spin_lock.c b/libc/thread/pthread_spin_lock.c similarity index 100% rename from libc/intrin/pthread_spin_lock.c rename to libc/thread/pthread_spin_lock.c diff --git a/libc/intrin/pthread_spin_trylock.c b/libc/thread/pthread_spin_trylock.c similarity index 100% rename from libc/intrin/pthread_spin_trylock.c rename to libc/thread/pthread_spin_trylock.c diff --git a/libc/intrin/pthread_spin_unlock.c b/libc/thread/pthread_spin_unlock.c similarity index 100% rename from libc/intrin/pthread_spin_unlock.c rename to libc/thread/pthread_spin_unlock.c diff --git a/libc/thread/sem_open.c b/libc/thread/sem_open.c index 2fda4471785..156bbc868fc 100644 --- a/libc/thread/sem_open.c +++ b/libc/thread/sem_open.c @@ -37,6 +37,7 @@ #include "libc/sysv/consts/o.h" #include "libc/sysv/consts/prot.h" #include "libc/sysv/errfuns.h" +#include "libc/thread/posixthread.internal.h" #include "libc/thread/semaphore.h" #include "libc/thread/thread.h" #include "libc/thread/tls.h" @@ -56,19 +57,18 @@ static struct Semaphores { }; static void sem_open_lock(void) { - pthread_mutex_lock(&g_semaphores.lock); + _pthread_mutex_lock(&g_semaphores.lock); } static void sem_open_unlock(void) { - pthread_mutex_unlock(&g_semaphores.lock); + _pthread_mutex_unlock(&g_semaphores.lock); } static void sem_open_wipe(void) { - pthread_mutex_init(&g_semaphores.lock, 0); + _pthread_mutex_wipe_np(&g_semaphores.lock); } static void sem_open_setup(void) { - sem_open_wipe(); pthread_atfork(sem_open_lock, sem_open_unlock, sem_open_wipe); } diff --git a/libc/thread/thread.h b/libc/thread/thread.h index e2827b7d435..15952c2a76b 100644 --- a/libc/thread/thread.h +++ b/libc/thread/thread.h @@ -48,6 +48,7 @@ COSMOPOLITAN_C_START_ #define PTHREAD_MUTEX_INITIALIZER {0, PTHREAD_MUTEX_DEFAULT} #define PTHREAD_NORMAL_MUTEX_INITIALIZER_NP {0, PTHREAD_MUTEX_NORMAL} +#define PTHREAD_SHARED_MUTEX_INITIALIZER_NP {0, PTHREAD_PROCESS_SHARED} #define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP {0, PTHREAD_MUTEX_RECURSIVE} #define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP {0, PTHREAD_MUTEX_ERRORCHECK} diff --git a/test/libc/system/popen_test.c b/test/libc/system/popen_test.c index fb4e0d1db1b..b0099bdc706 100644 --- a/test/libc/system/popen_test.c +++ b/test/libc/system/popen_test.c @@ -38,6 +38,20 @@ #include "libc/thread/thread.h" #include "libc/time.h" +// test ability of user to override pthread mutex api +int pthread_mutex_lock(pthread_mutex_t *mutex) { + abort(); +} +int pthread_mutex_unlock(pthread_mutex_t *mutex) { + abort(); +} +int pthread_mutex_trylock(pthread_mutex_t *mutex) { + abort(); +} +int pthread_mutex_wipe_np(pthread_mutex_t *mutex) { + abort(); +} + FILE *f; char buf[32]; diff --git a/test/libc/thread/pthread_create_test.c b/test/libc/thread/pthread_create_test.c index dfaf03e2a3d..92b6c28db8e 100644 --- a/test/libc/thread/pthread_create_test.c +++ b/test/libc/thread/pthread_create_test.c @@ -51,6 +51,20 @@ #include "libc/thread/thread.h" #include "libc/thread/thread2.h" +// test ability of user to override pthread mutex api +int pthread_mutex_lock(pthread_mutex_t *mutex) { + abort(); +} +int pthread_mutex_unlock(pthread_mutex_t *mutex) { + abort(); +} +int pthread_mutex_trylock(pthread_mutex_t *mutex) { + abort(); +} +int pthread_mutex_wipe_np(pthread_mutex_t *mutex) { + abort(); +} + void OnUsr1(int sig, siginfo_t *si, void *vctx) { } diff --git a/test/libc/intrin/pthread_spin_lock_test.c b/test/libc/thread/pthread_spin_lock_test.c similarity index 100% rename from test/libc/intrin/pthread_spin_lock_test.c rename to test/libc/thread/pthread_spin_lock_test.c diff --git a/third_party/gdtoa/lock.c b/third_party/gdtoa/lock.c index 85b0f5c8a66..e30dcb7c796 100644 --- a/third_party/gdtoa/lock.c +++ b/third_party/gdtoa/lock.c @@ -29,6 +29,7 @@ │ THIS SOFTWARE. │ │ │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/thread/posixthread.internal.h" #include "third_party/gdtoa/lock.h" pthread_mutex_t __gdtoa_lock_obj = PTHREAD_MUTEX_INITIALIZER; @@ -37,23 +38,23 @@ pthread_mutex_t __gdtoa_lock1_obj = PTHREAD_MUTEX_INITIALIZER; void __gdtoa_lock(void) { - pthread_mutex_lock(&__gdtoa_lock_obj); + _pthread_mutex_lock(&__gdtoa_lock_obj); } void __gdtoa_unlock(void) { - pthread_mutex_unlock(&__gdtoa_lock_obj); + _pthread_mutex_unlock(&__gdtoa_lock_obj); } void __gdtoa_lock1(void) { - pthread_mutex_lock(&__gdtoa_lock1_obj); + _pthread_mutex_lock(&__gdtoa_lock1_obj); } void __gdtoa_unlock1(void) { - pthread_mutex_unlock(&__gdtoa_lock1_obj); + _pthread_mutex_unlock(&__gdtoa_lock1_obj); }