Allow user to override pthread mutex and cond

This commit is contained in:
Justine Tunney 2024-12-23 21:57:52 -08:00
parent 4705705548
commit 55b7aa1632
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
54 changed files with 216 additions and 102 deletions

View file

@ -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();
}

View file

@ -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;

View file

@ -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) {

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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);
}

30
libc/intrin/dlopen.c Normal file
View file

@ -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);
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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;

View file

@ -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);

View file

@ -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 @@ StartOver:
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) {

View file

@ -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);
}
/**

View file

@ -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) {

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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) {

View file

@ -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;

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);
}

View file

@ -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}

View file

@ -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];

View file

@ -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) {
}

View file

@ -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);
}