mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-02 17:28:30 +00:00
Improve lock hierarchy
- NetBSD no longer needs a spin lock to create semaphores - Windows fork() now locks process manager in correct order
This commit is contained in:
parent
7ba9a73840
commit
d3a13e8d70
14 changed files with 73 additions and 71 deletions
2
third_party/nsync/common.c
vendored
2
third_party/nsync/common.c
vendored
|
@ -153,7 +153,7 @@ static void free_waiters_populate (void) {
|
|||
// tim cook wants us to use his lol central dispatch
|
||||
n = 1;
|
||||
} else {
|
||||
n = getpagesize() / sizeof(waiter);
|
||||
n = __pagesize / sizeof(waiter);
|
||||
}
|
||||
waiter *waiters = mmap (0, n * sizeof(waiter),
|
||||
PROT_READ | PROT_WRITE,
|
||||
|
|
2
third_party/nsync/common.internal.h
vendored
2
third_party/nsync/common.internal.h
vendored
|
@ -211,7 +211,7 @@ static const uint32_t NSYNC_WAITER_TAG = 0x726d2ba9;
|
|||
0x1 /* waiter reserved by a thread, even when not in use */
|
||||
#define WAITER_IN_USE 0x2 /* waiter in use by a thread */
|
||||
|
||||
#define ASSERT(x) npassert(x)
|
||||
#define ASSERT(x) unassert(x)
|
||||
|
||||
/* Return a pointer to the nsync_waiter_s containing struct Dll *e. */
|
||||
#define DLL_NSYNC_WAITER(e) \
|
||||
|
|
2
third_party/nsync/mu_semaphore_futex.c
vendored
2
third_party/nsync/mu_semaphore_futex.c
vendored
|
@ -28,7 +28,7 @@
|
|||
* @fileoverview Semaphores w/ Linux Futexes API.
|
||||
*/
|
||||
|
||||
#define ASSERT(x) npassert(x)
|
||||
#define ASSERT(x) unassert(x)
|
||||
|
||||
/* Check that atomic operations on nsync_atomic_uint32_ can be applied to int. */
|
||||
static const int assert_int_size = 1 /
|
||||
|
|
37
third_party/nsync/mu_semaphore_sem.c
vendored
37
third_party/nsync/mu_semaphore_sem.c
vendored
|
@ -31,29 +31,34 @@
|
|||
#include "libc/sysv/consts/fd.h"
|
||||
#include "libc/thread/thread.h"
|
||||
#include "third_party/nsync/mu_semaphore.h"
|
||||
#include "libc/intrin/atomic.h"
|
||||
#include "libc/atomic.h"
|
||||
#include "third_party/nsync/time.h"
|
||||
|
||||
/**
|
||||
* @fileoverview Semaphores w/ POSIX Semaphores API.
|
||||
*/
|
||||
|
||||
#define ASSERT(x) npassert(x)
|
||||
#define SEM_CONTAINER(e) DLL_CONTAINER(struct sem, list, e)
|
||||
#define ASSERT(x) unassert(x)
|
||||
|
||||
struct sem {
|
||||
int64_t id;
|
||||
struct Dll list;
|
||||
struct sem *next;
|
||||
};
|
||||
|
||||
static struct {
|
||||
atomic_uint once;
|
||||
pthread_spinlock_t lock;
|
||||
struct Dll *list;
|
||||
} g_sems;
|
||||
static _Atomic(struct sem *) g_sems;
|
||||
|
||||
static nsync_semaphore *sem_big_enough_for_sem = (nsync_semaphore *) (uintptr_t)(1 /
|
||||
(sizeof (struct sem) <= sizeof (*sem_big_enough_for_sem)));
|
||||
|
||||
static void sems_push (struct sem *f) {
|
||||
int backoff = 0;
|
||||
f->next = atomic_load_explicit (&g_sems, memory_order_relaxed);
|
||||
while (!atomic_compare_exchange_weak_explicit (&g_sems, &f->next, f,
|
||||
memory_order_acq_rel, memory_order_relaxed))
|
||||
backoff = pthread_delay_np (&g_sems, backoff);
|
||||
}
|
||||
|
||||
static bool nsync_mu_semaphore_sem_create (struct sem *f) {
|
||||
int rc;
|
||||
int lol;
|
||||
|
@ -73,18 +78,12 @@ static bool nsync_mu_semaphore_sem_create (struct sem *f) {
|
|||
}
|
||||
|
||||
static void nsync_mu_semaphore_sem_fork_child (void) {
|
||||
struct Dll *e;
|
||||
struct sem *f;
|
||||
for (e = dll_first (g_sems.list); e; e = dll_next (g_sems.list, e)) {
|
||||
f = SEM_CONTAINER (e);
|
||||
for (f = atomic_load_explicit (&g_sems, memory_order_relaxed); f; f = f->next) {
|
||||
int rc = sys_close (f->id);
|
||||
STRACE ("close(%ld) → %d", f->id, rc);
|
||||
}
|
||||
for (e = dll_first (g_sems.list); e; e = dll_next (g_sems.list, e)) {
|
||||
f = SEM_CONTAINER (e);
|
||||
ASSERT (nsync_mu_semaphore_sem_create (f));
|
||||
}
|
||||
(void) pthread_spin_init (&g_sems.lock, 0);
|
||||
}
|
||||
|
||||
static void nsync_mu_semaphore_sem_init (void) {
|
||||
|
@ -93,14 +92,12 @@ static void nsync_mu_semaphore_sem_init (void) {
|
|||
|
||||
/* Initialize *s; the initial value is 0. */
|
||||
bool nsync_mu_semaphore_init_sem (nsync_semaphore *s) {
|
||||
static atomic_uint once;
|
||||
struct sem *f = (struct sem *) s;
|
||||
if (!nsync_mu_semaphore_sem_create (f))
|
||||
return false;
|
||||
cosmo_once (&g_sems.once, nsync_mu_semaphore_sem_init);
|
||||
pthread_spin_lock (&g_sems.lock);
|
||||
dll_init (&f->list);
|
||||
dll_make_first (&g_sems.list, &f->list);
|
||||
pthread_spin_unlock (&g_sems.lock);
|
||||
cosmo_once (&once, nsync_mu_semaphore_sem_init);
|
||||
sems_push(f);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue