mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-27 14:58:30 +00:00
Rewrite recursive mutex code
This commit is contained in:
parent
bae7367774
commit
cfcf5918bc
27 changed files with 164 additions and 257 deletions
|
@ -18,7 +18,6 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/atomic.h"
|
||||
#include "libc/intrin/futex.internal.h"
|
||||
|
@ -31,35 +30,34 @@
|
|||
* @raises EPERM if in error check mode and not owned by caller
|
||||
*/
|
||||
int pthread_mutex_unlock(pthread_mutex_t *mutex) {
|
||||
int c, me, owner;
|
||||
switch (mutex->type) {
|
||||
case PTHREAD_MUTEX_NORMAL:
|
||||
// From Futexes Are Tricky Version 1.1 § Mutex, Take 3;
|
||||
// Ulrich Drepper, Red Hat Incorporated, June 27, 2004.
|
||||
if ((c = atomic_fetch_sub_explicit(&mutex->lock, 1,
|
||||
memory_order_release)) != 1) {
|
||||
atomic_store_explicit(&mutex->lock, 0, memory_order_release);
|
||||
_futex_wake(&mutex->lock, 1, mutex->pshared);
|
||||
}
|
||||
return 0;
|
||||
case PTHREAD_MUTEX_ERRORCHECK:
|
||||
me = gettid();
|
||||
owner = atomic_load_explicit(&mutex->lock, memory_order_relaxed);
|
||||
if (owner != me) {
|
||||
assert(!"permlock");
|
||||
return EPERM;
|
||||
}
|
||||
// fallthrough
|
||||
case PTHREAD_MUTEX_RECURSIVE:
|
||||
if (--mutex->reent) return 0;
|
||||
atomic_store_explicit(&mutex->lock, 0, memory_order_relaxed);
|
||||
if ((IsLinux() || IsOpenbsd()) &&
|
||||
atomic_load_explicit(&mutex->waits, memory_order_relaxed) > 0) {
|
||||
return _futex_wake(&mutex->lock, 1, mutex->pshared);
|
||||
}
|
||||
return 0;
|
||||
default:
|
||||
assert(!"badlock");
|
||||
return EINVAL;
|
||||
int c, t;
|
||||
|
||||
if (mutex->type == PTHREAD_MUTEX_NORMAL) {
|
||||
// From Futexes Are Tricky Version 1.1 § Mutex, Take 3;
|
||||
// Ulrich Drepper, Red Hat Incorporated, June 27, 2004.
|
||||
if ((c = atomic_fetch_sub(&mutex->lock, 1)) != 1) {
|
||||
atomic_store_explicit(&mutex->lock, 0, memory_order_release);
|
||||
_futex_wake(&mutex->lock, 1, mutex->pshared);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
t = gettid();
|
||||
if (mutex->type == PTHREAD_MUTEX_ERRORCHECK) {
|
||||
c = atomic_load_explicit(&mutex->lock, memory_order_relaxed);
|
||||
if ((c & 0x000fffff) != t) {
|
||||
assert(!"permlock");
|
||||
return EPERM;
|
||||
}
|
||||
}
|
||||
|
||||
c = atomic_fetch_sub(&mutex->lock, 0x00100000);
|
||||
if ((c & 0x0ff00000) == 0x00100000) {
|
||||
atomic_store_explicit(&mutex->lock, 0, memory_order_release);
|
||||
if ((c & 0xf0000000) == 0x20000000) {
|
||||
_futex_wake(&mutex->lock, 1, mutex->pshared);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue