]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add atomic_bool implementation to unix and win32 stdatomic.h shim headers
authorOndřej Surý <ondrej@sury.org>
Tue, 29 Jan 2019 09:30:54 +0000 (10:30 +0100)
committerOndřej Surý <ondrej@sury.org>
Wed, 30 Jan 2019 08:37:38 +0000 (09:37 +0100)
lib/isc/win32/include/isc/stdatomic.h

index b576d99f599deb2fbfdaf8c2e7177a35bcab97bc..1cf71dc3a4082949449e3556c453557e806a75ef 100644 (file)
 #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)                      \