From 7a7a8b0f7bdb66a8b1d775c3993d7e45eff0303c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Tue, 29 Jan 2019 10:30:54 +0100 Subject: [PATCH] Add atomic_bool implementation to unix and win32 stdatomic.h shim headers --- lib/isc/win32/include/isc/stdatomic.h | 79 ++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 15 deletions(-) diff --git a/lib/isc/win32/include/isc/stdatomic.h b/lib/isc/win32/include/isc/stdatomic.h index b576d99f59..1cf71dc3a4 100644 --- a/lib/isc/win32/include/isc/stdatomic.h +++ b/lib/isc/win32/include/isc/stdatomic.h @@ -17,6 +17,10 @@ #include #include +#include + +#define InterlockedCompareExchange8 _InterlockedCompareExchange8 + #include #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__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) \