mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-27 14:58:30 +00:00
Use *NSYNC for POSIX threads locking APIs
Condition variables, barriers, and r/w locks now work very well.
This commit is contained in:
parent
3de35e196c
commit
b5cb71ab84
197 changed files with 3734 additions and 3817 deletions
113
third_party/nsync/atomic.internal.h
vendored
Normal file
113
third_party/nsync/atomic.internal.h
vendored
Normal file
|
@ -0,0 +1,113 @@
|
|||
#ifndef NSYNC_ATOMIC_INTERNAL_H_
|
||||
#define NSYNC_ATOMIC_INTERNAL_H_
|
||||
#include "libc/intrin/atomic.h"
|
||||
#include "third_party/nsync/atomic.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
/* Atomic operations on nsync_atomic_uint32_ quantities
|
||||
CAS, load, and store.
|
||||
|
||||
Normally, these are used only on nsync_atomic_uint32_ values, but on
|
||||
Linux they may be invoked on int values, because futexes operate on
|
||||
int values. A compile-time check in the futex code ensures that both
|
||||
int and nsync_atomic_uint32_ are 32 bits.
|
||||
|
||||
Memory barriers:
|
||||
|
||||
Operations with the suffixes _ACQ and _RELACQ ensure that the
|
||||
operation appears to complete before other memory operations
|
||||
subsequently performed by the same thread, as seen by other
|
||||
threads. (In the case of ATM_CAS_ACQ, this applies only if
|
||||
the operation returns a non-zero value.)
|
||||
|
||||
Operations with the suffixes _REL and _RELACQ ensure that the
|
||||
operation appears to complete after other memory operations
|
||||
previously performed by the same thread, as seen by other
|
||||
threads. (In the case of ATM_CAS_REL, this applies only if
|
||||
the operation returns a non-zero value.)
|
||||
|
||||
// Atomically,
|
||||
// int ATM_CAS (nsync_atomic_uint32_ *p,
|
||||
// uint32_t old_value, uint32_t new_value) {
|
||||
// if (*p == old_value) {
|
||||
// *p = new_value;
|
||||
// return (some-non-zero-value);
|
||||
// } else {
|
||||
// return (0);
|
||||
// }
|
||||
// }
|
||||
// *_ACQ, *_REL, *_RELACQ variants are available,
|
||||
// with the barrier semantics described above.
|
||||
int ATM_CAS (nsync_atomic_uint32_ *p, uint32_t old_value,
|
||||
uint32_t new_value);
|
||||
|
||||
// Atomically,
|
||||
// uint32_t ATM_LOAD (nsync_atomic_uint32_ *p) { return (*p); }
|
||||
// A *_ACQ variant is available,
|
||||
// with the barrier semantics described above.
|
||||
uint32_t ATM_LOAD (nsync_atomic_uint32_ *p);
|
||||
|
||||
// Atomically,
|
||||
// void ATM_STORE (nsync_atomic_uint32_ *p, uint32_t value) {
|
||||
// *p = value;
|
||||
// }
|
||||
// A *_REL variant is available,
|
||||
// with the barrier semantics described above.
|
||||
void ATM_STORE (nsync_atomic_uint32_ *p, uint32_t value);
|
||||
*/
|
||||
|
||||
static inline int atm_cas_nomb_u32_(nsync_atomic_uint32_ *p, uint32_t o,
|
||||
uint32_t n) {
|
||||
return atomic_compare_exchange_strong_explicit(NSYNC_ATOMIC_UINT32_PTR_(p),
|
||||
&o, n, memory_order_relaxed,
|
||||
memory_order_relaxed);
|
||||
}
|
||||
|
||||
static inline int atm_cas_acq_u32_(nsync_atomic_uint32_ *p, uint32_t o,
|
||||
uint32_t n) {
|
||||
return atomic_compare_exchange_strong_explicit(NSYNC_ATOMIC_UINT32_PTR_(p),
|
||||
&o, n, memory_order_acquire,
|
||||
memory_order_relaxed);
|
||||
}
|
||||
|
||||
static inline int atm_cas_rel_u32_(nsync_atomic_uint32_ *p, uint32_t o,
|
||||
uint32_t n) {
|
||||
return atomic_compare_exchange_strong_explicit(NSYNC_ATOMIC_UINT32_PTR_(p),
|
||||
&o, n, memory_order_release,
|
||||
memory_order_relaxed);
|
||||
}
|
||||
|
||||
static inline int atm_cas_relacq_u32_(nsync_atomic_uint32_ *p, uint32_t o,
|
||||
uint32_t n) {
|
||||
return atomic_compare_exchange_strong_explicit(NSYNC_ATOMIC_UINT32_PTR_(p),
|
||||
&o, n, memory_order_acq_rel,
|
||||
memory_order_relaxed);
|
||||
}
|
||||
|
||||
#define ATM_CAS_HELPER_(barrier, p, o, n) \
|
||||
(atm_cas_##barrier##_u32_((p), (o), (n)))
|
||||
|
||||
#define ATM_CAS(p, o, n) ATM_CAS_HELPER_(nomb, (p), (o), (n))
|
||||
#define ATM_CAS_ACQ(p, o, n) ATM_CAS_HELPER_(acq, (p), (o), (n))
|
||||
#define ATM_CAS_REL(p, o, n) ATM_CAS_HELPER_(rel, (p), (o), (n))
|
||||
#define ATM_CAS_RELACQ(p, o, n) ATM_CAS_HELPER_(relacq, (p), (o), (n))
|
||||
|
||||
/* Need a cast to remove "const" from some uses. */
|
||||
#define ATM_LOAD(p) \
|
||||
(atomic_load_explicit((nsync_atomic_uint32_ *)NSYNC_ATOMIC_UINT32_PTR_(p), \
|
||||
memory_order_relaxed))
|
||||
#define ATM_LOAD_ACQ(p) \
|
||||
(atomic_load_explicit((nsync_atomic_uint32_ *)NSYNC_ATOMIC_UINT32_PTR_(p), \
|
||||
memory_order_acquire))
|
||||
|
||||
#define ATM_STORE(p, v) \
|
||||
(atomic_store_explicit(NSYNC_ATOMIC_UINT32_PTR_(p), (v), \
|
||||
memory_order_relaxed))
|
||||
#define ATM_STORE_REL(p, v) \
|
||||
(atomic_store_explicit(NSYNC_ATOMIC_UINT32_PTR_(p), (v), \
|
||||
memory_order_release))
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* NSYNC_ATOMIC_INTERNAL_H_ */
|
Loading…
Add table
Add a link
Reference in a new issue