mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-27 14:58:30 +00:00
Add futexes for OpenBSD
This commit is contained in:
parent
1216b6e7c7
commit
b8e9f71d33
4 changed files with 46 additions and 8 deletions
|
@ -121,7 +121,7 @@ int pthread_rwlock_unlock(pthread_rwlock_t *);
|
||||||
#define pthread_mutex_unlock(mutex) \
|
#define pthread_mutex_unlock(mutex) \
|
||||||
((mutex)->attr == PTHREAD_MUTEX_NORMAL \
|
((mutex)->attr == PTHREAD_MUTEX_NORMAL \
|
||||||
? (atomic_store_explicit(&(mutex)->lock, 0, memory_order_relaxed), \
|
? (atomic_store_explicit(&(mutex)->lock, 0, memory_order_relaxed), \
|
||||||
(IsLinux() && \
|
((IsLinux() || IsOpenbsd()) && \
|
||||||
atomic_load_explicit(&(mutex)->waits, memory_order_relaxed) && \
|
atomic_load_explicit(&(mutex)->waits, memory_order_relaxed) && \
|
||||||
_pthread_mutex_wake(mutex)), \
|
_pthread_mutex_wake(mutex)), \
|
||||||
0) \
|
0) \
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/bits/asmflag.h"
|
||||||
#include "libc/bits/atomic.h"
|
#include "libc/bits/atomic.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
|
@ -24,16 +25,41 @@
|
||||||
#include "libc/intrin/spinlock.h"
|
#include "libc/intrin/spinlock.h"
|
||||||
#include "libc/linux/futex.h"
|
#include "libc/linux/futex.h"
|
||||||
#include "libc/nexgen32e/threaded.h"
|
#include "libc/nexgen32e/threaded.h"
|
||||||
|
#include "libc/sysv/consts/futex.h"
|
||||||
|
#include "libc/sysv/consts/nr.h"
|
||||||
|
|
||||||
|
static inline int FutexWait(void *addr, int expect, struct timespec *timeout) {
|
||||||
|
int ax;
|
||||||
|
bool cf;
|
||||||
|
asm volatile(CFLAG_ASM("mov\t%6,%%r10\n\t"
|
||||||
|
"clc\n\t"
|
||||||
|
"syscall")
|
||||||
|
: CFLAG_CONSTRAINT(cf), "=a"(ax)
|
||||||
|
: "1"(__NR_futex), "D"(addr), "S"(FUTEX_WAIT), "d"(expect),
|
||||||
|
"g"(timeout)
|
||||||
|
: "rcx", "r10", "r11", "memory");
|
||||||
|
if (cf) ax = -ax;
|
||||||
|
return ax;
|
||||||
|
}
|
||||||
|
|
||||||
static int pthread_mutex_lock_spin(pthread_mutex_t *mutex, int tries) {
|
static int pthread_mutex_lock_spin(pthread_mutex_t *mutex, int tries) {
|
||||||
volatile int i;
|
volatile int i;
|
||||||
|
struct timespec ts;
|
||||||
if (tries < 7) {
|
if (tries < 7) {
|
||||||
for (i = 0; i != 1 << tries; i++) {
|
for (i = 0; i != 1 << tries; i++) {
|
||||||
}
|
}
|
||||||
tries++;
|
tries++;
|
||||||
} else if (IsLinux()) {
|
} else if (IsLinux() || IsOpenbsd()) {
|
||||||
atomic_fetch_add(&mutex->waits, 1);
|
atomic_fetch_add(&mutex->waits, 1);
|
||||||
LinuxFutexWait(&mutex->lock, 1, 0);
|
if (tries < 28) {
|
||||||
|
ts.tv_sec = 0;
|
||||||
|
ts.tv_nsec = 4 << tries;
|
||||||
|
tries++;
|
||||||
|
} else {
|
||||||
|
ts.tv_sec = 1;
|
||||||
|
ts.tv_nsec = 0;
|
||||||
|
}
|
||||||
|
FutexWait(&mutex->lock, 1, &ts);
|
||||||
atomic_fetch_sub(&mutex->waits, 1);
|
atomic_fetch_sub(&mutex->waits, 1);
|
||||||
} else {
|
} else {
|
||||||
sched_yield();
|
sched_yield();
|
||||||
|
|
|
@ -40,7 +40,7 @@ int(pthread_mutex_unlock)(pthread_mutex_t *mutex) {
|
||||||
// fallthrough
|
// fallthrough
|
||||||
case PTHREAD_MUTEX_NORMAL:
|
case PTHREAD_MUTEX_NORMAL:
|
||||||
atomic_store_explicit(&mutex->lock, 0, memory_order_relaxed);
|
atomic_store_explicit(&mutex->lock, 0, memory_order_relaxed);
|
||||||
if (IsLinux() &&
|
if ((IsLinux() || IsOpenbsd()) &&
|
||||||
atomic_load_explicit(&mutex->waits, memory_order_relaxed)) {
|
atomic_load_explicit(&mutex->waits, memory_order_relaxed)) {
|
||||||
_pthread_mutex_wake(mutex);
|
_pthread_mutex_wake(mutex);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,11 +16,23 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/bits/atomic.h"
|
#include "libc/bits/asmflag.h"
|
||||||
#include "libc/dce.h"
|
|
||||||
#include "libc/intrin/pthread.h"
|
#include "libc/intrin/pthread.h"
|
||||||
#include "libc/linux/futex.h"
|
#include "libc/sysv/consts/futex.h"
|
||||||
|
#include "libc/sysv/consts/nr.h"
|
||||||
|
|
||||||
|
static inline int FutexWake(void *addr, int count) {
|
||||||
|
int ax;
|
||||||
|
bool cf;
|
||||||
|
asm volatile(CFLAG_ASM("clc\n\t"
|
||||||
|
"syscall")
|
||||||
|
: CFLAG_CONSTRAINT(cf), "=a"(ax)
|
||||||
|
: "1"(__NR_futex), "D"(addr), "S"(FUTEX_WAKE), "d"(count)
|
||||||
|
: "rcx", "r11", "memory");
|
||||||
|
if (cf) ax = -ax;
|
||||||
|
return ax;
|
||||||
|
}
|
||||||
|
|
||||||
int _pthread_mutex_wake(pthread_mutex_t *mutex) {
|
int _pthread_mutex_wake(pthread_mutex_t *mutex) {
|
||||||
return LinuxFutexWake(&mutex->lock, 1);
|
return FutexWake(&mutex->lock, 1);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue