mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 06:53:33 +00:00
Allow user to override pthread mutex and cond
This commit is contained in:
parent
4705705548
commit
55b7aa1632
54 changed files with 216 additions and 102 deletions
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
30
libc/intrin/dlopen.c
Normal 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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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}
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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) {
|
||||
}
|
||||
|
||||
|
|
9
third_party/gdtoa/lock.c
vendored
9
third_party/gdtoa/lock.c
vendored
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue