Skip to content

Commit

Permalink
Allow user to override pthread mutex and cond
Browse files Browse the repository at this point in the history
  • Loading branch information
jart committed Dec 24, 2024
1 parent 4705705 commit 55b7aa1
Show file tree
Hide file tree
Showing 54 changed files with 216 additions and 102 deletions.
13 changes: 8 additions & 5 deletions libc/calls/fcntl-nt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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) {
Expand Down Expand Up @@ -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();
}
Expand Down
1 change: 1 addition & 0 deletions libc/calls/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
13 changes: 9 additions & 4 deletions libc/calls/read-nt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down
8 changes: 5 additions & 3 deletions libc/dlopen/dlopen.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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];

Expand Down Expand Up @@ -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;
}

Expand Down
11 changes: 4 additions & 7 deletions libc/intrin/cursor.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
}
5 changes: 3 additions & 2 deletions libc/intrin/cxalock.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 30 additions & 0 deletions libc/intrin/dlopen.c
Original file line number Diff line number Diff line change
@@ -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);
}
5 changes: 3 additions & 2 deletions libc/intrin/fds_lock.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
9 changes: 5 additions & 4 deletions libc/intrin/itimer.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,26 @@
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/thread/itimer.h"
#include "libc/str/str.h"
#include "libc/thread/posixthread.internal.h"

struct IntervalTimer __itimer = {
.lock = PTHREAD_MUTEX_INITIALIZER,
.cond = PTHREAD_COND_INITIALIZER,
};

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;
}
5 changes: 3 additions & 2 deletions libc/intrin/localtime_lock.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
8 changes: 6 additions & 2 deletions libc/intrin/pthread_mutex_lock.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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));
Expand All @@ -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));
Expand All @@ -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);
5 changes: 4 additions & 1 deletion libc/intrin/pthread_mutex_unlock.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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));
Expand All @@ -176,3 +177,5 @@ errno_t pthread_mutex_unlock(pthread_mutex_t *mutex) {
return 0;
}
}

__weak_reference(_pthread_mutex_unlock, pthread_mutex_unlock);
5 changes: 4 additions & 1 deletion libc/intrin/pthread_mutex_wipe_np.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,19 @@
╚─────────────────────────────────────────────────────────────────────────────*/
#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));
mutex->_word = MUTEX_UNLOCK(word);
mutex->_edges = edges;
return 0;
}

__weak_reference(_pthread_mutex_wipe_np, pthread_mutex_wipe_np);
4 changes: 2 additions & 2 deletions libc/intrin/pthreadlock.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
5 changes: 3 additions & 2 deletions libc/intrin/rand64.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -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 {
Expand All @@ -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;
}
4 changes: 2 additions & 2 deletions libc/intrin/sig.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down
Loading

0 comments on commit 55b7aa1

Please sign in to comment.