mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-02 17:28:30 +00:00
Perform some code cleanup
This commit is contained in:
parent
0dd9629562
commit
a4601a24d3
63 changed files with 350 additions and 1643 deletions
12
libc/intrin/futex.internal.h
Normal file
12
libc/intrin/futex.internal.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_INTRIN_FUTEX_INTERNAL_H_
|
||||
#define COSMOPOLITAN_LIBC_INTRIN_FUTEX_INTERNAL_H_
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
int _futex_wait(void *, int, struct timespec *);
|
||||
int _futex_wake(void *, int);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_INTRIN_FUTEX_INTERNAL_H_ */
|
44
libc/intrin/futex_wait.c
Normal file
44
libc/intrin/futex_wait.c
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 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/bits/asmflag.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/intrin/futex.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/futex.h"
|
||||
#include "libc/sysv/consts/nr.h"
|
||||
|
||||
privileged int _futex_wait(void *addr, int expect, struct timespec *timeout) {
|
||||
int ax;
|
||||
bool cf;
|
||||
char buf[45];
|
||||
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;
|
||||
STRACE("futex(%p, FUTEX_WAIT, %d, %s) → %s", addr, expect,
|
||||
DescribeTimespec(buf, sizeof(buf), 0, timeout),
|
||||
ax ? strerrno(-ax) : "0");
|
||||
return ax;
|
||||
}
|
49
libc/intrin/futex_wake.c
Normal file
49
libc/intrin/futex_wake.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 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/bits/asmflag.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/intrin/futex.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/futex.h"
|
||||
#include "libc/sysv/consts/nr.h"
|
||||
|
||||
static const char *FormatFutexWakeResult(char buf[12], int ax) {
|
||||
if (ax >= 0) {
|
||||
FormatInt32(buf, ax);
|
||||
return buf;
|
||||
} else {
|
||||
return strerrno(-ax);
|
||||
}
|
||||
}
|
||||
|
||||
privileged int _futex_wake(void *addr, int count) {
|
||||
int ax;
|
||||
bool cf;
|
||||
char buf[12];
|
||||
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;
|
||||
STRACE("futex(%p, FUTEX_WAKE, %d) → %s", addr, count,
|
||||
FormatFutexWakeResult(buf, ax));
|
||||
return ax;
|
||||
}
|
|
@ -73,6 +73,8 @@ o/$(MODE)/libc/intrin/kprintf.greg.o: \
|
|||
-fno-stack-protector
|
||||
|
||||
# synchronization primitives are intended to be magic free
|
||||
o/$(MODE)/libc/intrin/futex_wait.o \
|
||||
o/$(MODE)/libc/intrin/futex_wake.o \
|
||||
o/$(MODE)/libc/intrin/gettid.greg.o \
|
||||
o/$(MODE)/libc/intrin/pthread_mutex_lock.o \
|
||||
o/$(MODE)/libc/intrin/pthread_mutex_unlock.o \
|
||||
|
|
|
@ -126,6 +126,7 @@ void *pthread_getspecific(pthread_key_t);
|
|||
!atomic_exchange(&(mutex)->lock, 1)) \
|
||||
? 0 \
|
||||
: pthread_mutex_lock(mutex))
|
||||
/*
|
||||
#define pthread_mutex_unlock(mutex) \
|
||||
((mutex)->attr == PTHREAD_MUTEX_NORMAL \
|
||||
? (atomic_store_explicit(&(mutex)->lock, 0, memory_order_relaxed), \
|
||||
|
@ -134,6 +135,7 @@ void *pthread_getspecific(pthread_key_t);
|
|||
_pthread_mutex_wake(mutex)), \
|
||||
0) \
|
||||
: pthread_mutex_unlock(mutex))
|
||||
*/
|
||||
#endif
|
||||
|
||||
int _pthread_mutex_wake(pthread_mutex_t *) hidden;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/pthread.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
|
@ -24,6 +25,12 @@
|
|||
* @return 0 on success, or error number on failure
|
||||
*/
|
||||
int pthread_mutex_destroy(pthread_mutex_t *mutex) {
|
||||
int rc;
|
||||
if (!mutex->lock && !mutex->waits) {
|
||||
rc = 0;
|
||||
} else {
|
||||
rc = EDEADLK;
|
||||
}
|
||||
bzero(mutex, sizeof(*mutex));
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/futex.internal.h"
|
||||
#include "libc/intrin/pthread.h"
|
||||
#include "libc/intrin/spinlock.h"
|
||||
#include "libc/linux/futex.h"
|
||||
|
@ -28,38 +29,15 @@
|
|||
#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) {
|
||||
volatile int i;
|
||||
struct timespec ts;
|
||||
if (tries < 7) {
|
||||
for (i = 0; i != 1 << tries; i++) {
|
||||
}
|
||||
tries++;
|
||||
} else if (IsLinux() || IsOpenbsd()) {
|
||||
atomic_fetch_add(&mutex->waits, 1);
|
||||
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);
|
||||
_futex_wait(&mutex->lock, 1, &(struct timespec){1});
|
||||
atomic_fetch_sub(&mutex->waits, 1);
|
||||
} else {
|
||||
sched_yield();
|
||||
|
|
|
@ -41,7 +41,7 @@ int(pthread_mutex_unlock)(pthread_mutex_t *mutex) {
|
|||
case PTHREAD_MUTEX_NORMAL:
|
||||
atomic_store_explicit(&mutex->lock, 0, memory_order_relaxed);
|
||||
if ((IsLinux() || IsOpenbsd()) &&
|
||||
atomic_load_explicit(&mutex->waits, memory_order_relaxed)) {
|
||||
atomic_load_explicit(&mutex->waits, memory_order_relaxed) > 0) {
|
||||
_pthread_mutex_wake(mutex);
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -16,23 +16,9 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/asmflag.h"
|
||||
#include "libc/intrin/futex.internal.h"
|
||||
#include "libc/intrin/pthread.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) {
|
||||
return FutexWake(&mutex->lock, 1);
|
||||
return _futex_wake(&mutex->lock, 1);
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ sched_yield:
|
|||
testb IsXnu()
|
||||
jz 1f
|
||||
pause
|
||||
xor %eax,%eax
|
||||
ret
|
||||
#endif
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/bits/atomic.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/futex.internal.h"
|
||||
#include "libc/intrin/wait0.internal.h"
|
||||
#include "libc/linux/futex.h"
|
||||
|
||||
|
@ -34,8 +35,8 @@ void _wait0(int *ptid) {
|
|||
for (;;) {
|
||||
if (!(x = atomic_load_explicit(ptid, memory_order_relaxed))) {
|
||||
break;
|
||||
} else if (IsLinux()) {
|
||||
LinuxFutexWait(ptid, x, 0);
|
||||
} else if (IsLinux() || IsOpenbsd()) {
|
||||
_futex_wait(ptid, x, &(struct timespec){2});
|
||||
} else {
|
||||
sched_yield();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue