From a85a65f96eba4ed12e69ca0f539b29713549feab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Witold=20Kr=C4=99cicki?= Date: Thu, 24 Oct 2019 10:55:54 +0200 Subject: [PATCH] add atomic_exchange operations to mutexatomic.h and win32 stdatomic.h --- lib/isc/include/isc/mutexatomic.h | 16 ++++++++++++++++ lib/isc/unix/include/isc/stdatomic.h | 11 +++++++++++ lib/isc/win32/include/isc/stdatomic.h | 23 +++++++++++++++++++++-- 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/lib/isc/include/isc/mutexatomic.h b/lib/isc/include/isc/mutexatomic.h index c111081ee9..94d8998822 100644 --- a/lib/isc/include/isc/mutexatomic.h +++ b/lib/isc/include/isc/mutexatomic.h @@ -93,6 +93,11 @@ typedef struct atomic_uint_fast64 { uint64_t v; } atomic_uint_fast64_t; +typedef struct atomic_uintptr { + isc_mutex_t m; + uintptr_t v; +} atomic_uintptr_t; + typedef struct atomic_bool_s { isc_mutex_t m; bool v; @@ -198,3 +203,14 @@ typedef struct atomic_bool_s { atomic_compare_exchange_weak_explicit(obj, expected, desired, \ memory_order_seq_cst, \ memory_order_seq_cst) +#define atomic_exchange_explicit(obj, desired, order) \ + ({ \ + typeof((obj)->v) ___v; \ + REQUIRE(isc_mutex_lock(&(obj)->m) == ISC_R_SUCCESS); \ + ___v = (obj)->v; \ + (obj)->v = desired; \ + REQUIRE(isc_mutex_unlock(&(obj)->m) == ISC_R_SUCCESS); \ + ___v; \ + }) +#define atomic_exchange(obj, desired) \ + atomic_exchange_explicit(obj, desired, memory_order_seq_cst) diff --git a/lib/isc/unix/include/isc/stdatomic.h b/lib/isc/unix/include/isc/stdatomic.h index f0909d232b..8e423a961b 100644 --- a/lib/isc/unix/include/isc/stdatomic.h +++ b/lib/isc/unix/include/isc/stdatomic.h @@ -80,6 +80,8 @@ typedef int_fast64_t atomic_int_fast64_t; typedef uint_fast64_t atomic_uint_fast64_t; typedef bool atomic_bool; +typedef uint_fast64_t atomic_uintptr_t; + #if defined(__CLANG_ATOMICS) /* __c11_atomic builtins */ #define atomic_init(obj, desired) \ __c11_atomic_init(obj, desired) @@ -99,6 +101,8 @@ typedef bool atomic_bool; __c11_atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, fail) #define atomic_compare_exchange_weak_explicit(obj, expected, desired, succ, fail) \ __c11_atomic_compare_exchange_weak_explicit(obj, expected, desired, succ, fail) +#define atomic_exchange_explicit(obj, desired, order) \ + __c11_atomic_exchange_explicit(obj, expected, order) #elif defined(__GNUC_ATOMICS) /* __atomic builtins */ #define atomic_init(obj, desired) \ (*obj = desired) @@ -118,6 +122,8 @@ typedef bool atomic_bool; __atomic_compare_exchange_n(obj, expected, desired, 0, succ, fail) #define atomic_compare_exchange_weak_explicit(obj, expected, desired, succ, fail) \ __atomic_compare_exchange_n(obj, expected, desired, 1, succ, fail) +#define atomic_exchange_explicit(obj, desired, order) \ + __atomic_exchange_n(obj, desired, order) #else /* __sync builtins */ #define atomic_init(obj, desired) \ (*obj = desired) @@ -150,6 +156,9 @@ typedef bool atomic_bool; }) #define atomic_compare_exchange_weak_explicit(obj, expected, desired, succ, fail) \ atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, fail) +#define atomic_exchange_explicit(obj, desired, order) \ + __sync_lock_test_and_set(obj, desired) + #endif #define atomic_load(obj) \ @@ -168,3 +177,5 @@ typedef bool atomic_bool; atomic_compare_exchange_strong_explicit(obj, expected, desired, memory_order_seq_cst, memory_order_seq_cst) #define atomic_compare_exchange_weak(obj, expected, desired) \ atomic_compare_exchange_weak_explicit(obj, expected, desired, memory_order_seq_cst, memory_order_seq_cst) +#define atomic_exchange(obj, desired) \ + atomic_exchange_explicit(obj, desired, memory_order_seq_cst) diff --git a/lib/isc/win32/include/isc/stdatomic.h b/lib/isc/win32/include/isc/stdatomic.h index 62c2de14be..60ac199af2 100644 --- a/lib/isc/win32/include/isc/stdatomic.h +++ b/lib/isc/win32/include/isc/stdatomic.h @@ -397,8 +397,7 @@ atomic_compare_exchange_strong_explicit64(atomic_int_fast64_t *obj, return (__r); } -static inline -bool +static inline bool atomic_compare_exchange_abort() { INSIST(0); ISC_UNREACHABLE(); @@ -434,3 +433,23 @@ atomic_compare_exchange_abort() { atomic_compare_exchange_weak_explicit(obj, expected, desired, \ memory_order_seq_cst, \ memory_order_seq_cst) + +static inline +bool +atomic_exchange_abort() { + INSIST(0); + ISC_UNREACHABLE(); +} + + +#define atomic_exchange_explicit(obj, desired, order) \ + (sizeof(*(obj)) == 8 \ + ? InterlockedExchange64(obj, desired) \ + : (sizeof(*(obj)) == 4 \ + ? InterlockedExchange(obj, desired) \ + : (sizeof(*(obj)) == 1 \ + ? InterlockedExchange8(obj, desired) \ + : atomic_exchange_abort()))) + +#define atomic_exchange(obj, desired) \ + atomic_exchange_explicit(obj, desired, memory_order_seq_cst) \