Add atomic_bool implementation to unix and win32 stdatomic.h shim headers
This commit is contained in:
@@ -17,6 +17,10 @@
|
||||
#include <stdint.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include <intrin.h>
|
||||
|
||||
#define InterlockedCompareExchange8 _InterlockedCompareExchange8
|
||||
|
||||
#include <isc/util.h>
|
||||
|
||||
#ifndef __ATOMIC_RELAXED
|
||||
@@ -49,6 +53,14 @@ enum memory_order {
|
||||
|
||||
typedef enum memory_order memory_order;
|
||||
|
||||
/*
|
||||
* If you add a type with different sizeof() length,
|
||||
* you need to implement atomic_<foo>_explicitNN macros.
|
||||
*/
|
||||
|
||||
typedef bool volatile atomic_bool;
|
||||
typedef int_fast8_t volatile atomic_int_fast8_t;
|
||||
typedef uint_fast8_t volatile atomic_uint_fast8_t;
|
||||
typedef int_fast32_t volatile atomic_int_fast32_t;
|
||||
typedef uint_fast32_t volatile atomic_uint_fast32_t;
|
||||
typedef int_fast64_t volatile atomic_int_fast64_t;
|
||||
@@ -57,6 +69,9 @@ typedef uint_fast64_t volatile atomic_uint_fast64_t;
|
||||
#define atomic_init(obj, desired) \
|
||||
(*(obj) = (desired))
|
||||
|
||||
#define atomic_store_explicit8(obj, desired, order) \
|
||||
(void)InterlockedExchange8((atomic_int_fast8_t *)obj, desired)
|
||||
|
||||
#define atomic_store_explicit32(obj, desired, order) \
|
||||
(order == memory_order_relaxed \
|
||||
? (void)InterlockedExchangeNoFence((atomic_int_fast32_t *)obj, desired) \
|
||||
@@ -88,31 +103,36 @@ atomic_store_abort() {
|
||||
? atomic_store_explicit64(obj, desired, order) \
|
||||
: (sizeof(*(obj)) == 4 \
|
||||
? atomic_store_explicit32(obj, desired, order) \
|
||||
: atomic_store_abort()))
|
||||
: (sizeof(*(obj)) == 1 \
|
||||
? atomic_store_explicit8(obj, desired, order) \
|
||||
: atomic_store_abort())))
|
||||
|
||||
#define atomic_store(obj, desired) \
|
||||
atomic_store_explicit(obj, desired, memory_order_seq_cst)
|
||||
|
||||
#define atomic_load_explicit32(obj, order) \
|
||||
(order == memory_order_relaxed \
|
||||
#define atomic_load_explicit8(obj, order) \
|
||||
(int8_t)InterlockedOr8((atomic_int_fast8_t *)obj, 0)
|
||||
|
||||
#define atomic_load_explicit32(obj, order) \
|
||||
(order == memory_order_relaxed \
|
||||
? (int32_t)InterlockedOrNoFence((atomic_int_fast32_t *)obj, 0) \
|
||||
: (order == memory_order_acquire \
|
||||
? (int32_t)InterlockedOrAcquire((atomic_int_fast32_t *)obj, 0) \
|
||||
: (order == memory_order_release \
|
||||
: (order == memory_order_acquire \
|
||||
? (int32_t)InterlockedOrAcquire((atomic_int_fast32_t *)obj, 0) \
|
||||
: (order == memory_order_release \
|
||||
? (int32_t)InterlockedOrRelease((atomic_int_fast32_t *)obj, 0) \
|
||||
: (int32_t)InterlockedOr((atomic_int_fast32_t *)obj, 0))))
|
||||
|
||||
#ifdef _WIN64
|
||||
#define atomic_load_explicit64(obj, order) \
|
||||
(order == memory_order_relaxed \
|
||||
#define atomic_load_explicit64(obj, order) \
|
||||
(order == memory_order_relaxed \
|
||||
? InterlockedOr64NoFence((atomic_int_fast64_t *)obj, 0) \
|
||||
: (order == memory_order_acquire \
|
||||
: (order == memory_order_acquire \
|
||||
? InterlockedOr64Acquire((atomic_int_fast64_t *)obj, 0) \
|
||||
: (order == memory_order_release \
|
||||
: (order == memory_order_release \
|
||||
? InterlockedOr64Release((atomic_int_fast64_t *)obj, 0) \
|
||||
: InterlockedOr64((atomic_int_fast64_t *)obj, 0))))
|
||||
#else
|
||||
#define atomic_load_explicit64(obj, order) \
|
||||
#define atomic_load_explicit64(obj, order) \
|
||||
InterlockedOr64((atomic_int_fast64_t *)obj, 0)
|
||||
#endif
|
||||
|
||||
@@ -126,13 +146,18 @@ atomic_load_abort() {
|
||||
#define atomic_load_explicit(obj, order) \
|
||||
(sizeof(*(obj)) == 8 \
|
||||
? atomic_load_explicit64(obj, order) \
|
||||
: (sizeof(*obj == 4) \
|
||||
: (sizeof(*(obj) == 4) \
|
||||
? atomic_load_explicit32(obj, order) \
|
||||
: atomic_load_abort()))
|
||||
: (sizeof(*(obj) == 1) \
|
||||
? atomic_load_explicit8(obj, order) \
|
||||
: atomic_load_abort())))
|
||||
|
||||
#define atomic_load(obj) \
|
||||
atomic_load_explicit(obj, memory_order_seq_cst)
|
||||
|
||||
#define atomic_fetch_add_explicit8(obj, arg, order) \
|
||||
InterlockedExchangeAdd8((atomic_int_fast8_t *)obj, arg)
|
||||
|
||||
#define atomic_fetch_add_explicit32(obj, arg, order) \
|
||||
(order == memory_order_relaxed \
|
||||
? InterlockedExchangeAddNoFence((atomic_int_fast32_t *)obj, arg) \
|
||||
@@ -168,7 +193,9 @@ atomic_add_abort() {
|
||||
? atomic_fetch_add_explicit64(obj, arg, order) \
|
||||
: (sizeof(*(obj)) == 4 \
|
||||
? atomic_fetch_add_explicit32(obj, arg, order) \
|
||||
: atomic_add_abort()))
|
||||
: (sizeof(*(obj)) == 1 \
|
||||
? atomic_fetch_add_explicit8(obj, arg, order) \
|
||||
: atomic_add_abort())))
|
||||
|
||||
#define atomic_fetch_add(obj, arg) \
|
||||
atomic_fetch_add_explicit(obj, arg, memory_order_seq_cst)
|
||||
@@ -179,6 +206,24 @@ atomic_add_abort() {
|
||||
#define atomic_fetch_sub(obj, arg) \
|
||||
atomic_fetch_sub_explicit(obj, arg, memory_order_seq_cst)
|
||||
|
||||
static inline bool
|
||||
atomic_compare_exchange_strong_explicit8(atomic_int_fast8_t *obj,
|
||||
int8_t *expected,
|
||||
int8_t desired,
|
||||
memory_order succ,
|
||||
memory_order fail)
|
||||
{
|
||||
bool __r;
|
||||
int8_t __v;
|
||||
REQUIRE(succ == fail);
|
||||
__v = InterlockedCompareExchange8((atomic_int_fast8_t *)obj, desired, *expected);
|
||||
__r = (*(expected) == __v);
|
||||
if (!__r) {
|
||||
*(expected) = __v;
|
||||
}
|
||||
return (__r);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
atomic_compare_exchange_strong_explicit32(atomic_int_fast32_t *obj,
|
||||
int32_t *expected,
|
||||
@@ -260,7 +305,11 @@ atomic_compare_exchange_abort() {
|
||||
? atomic_compare_exchange_strong_explicit32(obj, expected, \
|
||||
desired, \
|
||||
succ, fail) \
|
||||
: atomic_compare_exchange_abort()))
|
||||
: (sizeof(*(obj)) == 1 \
|
||||
? atomic_compare_exchange_strong_explicit8(obj, expected, \
|
||||
desired, \
|
||||
succ, fail) \
|
||||
: atomic_compare_exchange_abort())))
|
||||
|
||||
#define atomic_compare_exchange_strong(obj, expected, desired, \
|
||||
succ, fail) \
|
||||
|
||||
Reference in New Issue
Block a user