summaryrefslogtreecommitdiff
path: root/kit/atomic.h
diff options
context:
space:
mode:
Diffstat (limited to 'kit/atomic.h')
-rw-r--r--kit/atomic.h219
1 files changed, 219 insertions, 0 deletions
diff --git a/kit/atomic.h b/kit/atomic.h
new file mode 100644
index 0000000..8ec7bad
--- /dev/null
+++ b/kit/atomic.h
@@ -0,0 +1,219 @@
+#ifndef KIT_ATOMIC_H
+#define KIT_ATOMIC_H
+
+#include "types.h"
+
+#ifndef _MSC_VER
+# include <stdatomic.h>
+#else
+# include <assert.h>
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+# define _Atomic volatile
+
+enum {
+ memory_order_relaxed,
+ memory_order_consume,
+ memory_order_acquire,
+ memory_order_release,
+ memory_order_acq_rel,
+ memory_order_seq_cst
+};
+
+void kit_atomic_store_explicit_8(u8 volatile *var, u8 value,
+ i32 memory_order);
+
+void kit_atomic_store_explicit_16(u16 volatile *var, u16 value,
+ i32 memory_order);
+
+void kit_atomic_store_explicit_32(u32 volatile *var, u32 value,
+ i32 memory_order);
+
+void kit_atomic_store_explicit_64(u64 volatile *var, u64 value,
+ i32 memory_order);
+
+u8 kit_atomic_load_explicit_8(u8 volatile *var, i32 memory_order);
+
+u16 kit_atomic_load_explicit_16(u16 volatile *var, i32 memory_order);
+
+u32 kit_atomic_load_explicit_32(u32 volatile *var, i32 memory_order);
+
+u64 kit_atomic_load_explicit_64(u64 volatile *var, i32 memory_order);
+
+u8 kit_atomic_exchange_explicit_8(u8 volatile *var, u8 value,
+ i32 memory_order);
+
+u16 kit_atomic_exchange_explicit_16(u16 volatile *var, u16 value,
+ i32 memory_order);
+
+u32 kit_atomic_exchange_explicit_32(u32 volatile *var, u32 value,
+ i32 memory_order);
+
+u64 kit_atomic_exchange_explicit_64(u64 volatile *var, u64 value,
+ i32 memory_order);
+
+i32 kit_atomic_compare_exchange_explicit_8(u8 volatile *var,
+ u8 *expected, u8 value,
+ i32 memory_order_succ_,
+ i32 memory_order_fail_);
+
+i32 kit_atomic_compare_exchange_explicit_16(u16 volatile *var,
+ u16 *expected, u16 value,
+ i32 memory_order_succ_,
+ i32 memory_order_fail_);
+
+i32 kit_atomic_compare_exchange_explicit_32(u32 volatile *var,
+ u32 *expected, u32 value,
+ i32 memory_order_succ_,
+ i32 memory_order_fail_);
+
+i32 kit_atomic_compare_exchange_explicit_64(u64 volatile *var,
+ u64 *expected, u64 value,
+ i32 memory_order_succ_,
+ i32 memory_order_fail_);
+
+u8 kit_atomic_fetch_add_explicit_8(u8 volatile *var, u8 value,
+ i32 memory_order);
+
+u16 kit_atomic_fetch_add_explicit_16(u16 volatile *var, u16 value,
+ i32 memory_order);
+
+u32 kit_atomic_fetch_add_explicit_32(u32 volatile *var, u32 value,
+ i32 memory_order);
+
+u64 kit_atomic_fetch_add_explicit_64(u64 volatile *var, u64 value,
+ i32 memory_order);
+
+# define atomic_store_explicit(var_, value_, memory_order_) \
+ do { \
+ assert(sizeof *(var_) == 1 || sizeof *(var_) == 2 || \
+ sizeof *(var_) == 4 || sizeof *(var_) == 8); \
+ if (sizeof *(var_) == 1) \
+ kit_atomic_store_explicit_8((u8 volatile *) (var_), \
+ (u8) (value_), (memory_order_)); \
+ if (sizeof *(var_) == 2) \
+ kit_atomic_store_explicit_16((u16 volatile *) (var_), \
+ (u16) (value_), \
+ (memory_order_)); \
+ if (sizeof *(var_) == 4) \
+ kit_atomic_store_explicit_32((u32 volatile *) (var_), \
+ (u32) (value_), \
+ (memory_order_)); \
+ if (sizeof *(var_) == 8) \
+ kit_atomic_store_explicit_64((u64 volatile *) (var_), \
+ (u64) (value_), \
+ (memory_order_)); \
+ } while (0)
+
+# define atomic_load_explicit(var_, memory_order_) \
+ (assert(sizeof *(var_) == 1 || sizeof *(var_) == 2 || \
+ sizeof *(var_) == 4 || sizeof *(var_) == 8), \
+ (sizeof *(var_) == 1 \
+ ? kit_atomic_load_explicit_8((u8 volatile *) (var_), \
+ (memory_order_)) \
+ : sizeof *(var_) == 2 \
+ ? kit_atomic_load_explicit_16((u16 volatile *) (var_), \
+ (memory_order_)) \
+ : sizeof *(var_) == 4 \
+ ? kit_atomic_load_explicit_32((u32 volatile *) (var_), \
+ (memory_order_)) \
+ : kit_atomic_load_explicit_64((u64 volatile *) (var_), \
+ (memory_order_))))
+
+# define atomic_exchange_explicit(var_, value_, memory_order_) \
+ (assert(sizeof *(var_) == 1 || sizeof *(var_) == 2 || \
+ sizeof *(var_) == 4 || sizeof *(var_) == 8), \
+ (sizeof *(var_) == 1 ? kit_atomic_exchange_explicit_8( \
+ (u8 volatile *) (var_), \
+ (u8) (value_), (memory_order_)) \
+ : sizeof *(var_) == 2 ? kit_atomic_exchange_explicit_16( \
+ (u16 volatile *) (var_), \
+ (u16) (value_), (memory_order_)) \
+ : sizeof *(var_) == 4 \
+ ? kit_atomic_exchange_explicit_32((u32 volatile *) (var_), \
+ (u32) (value_), \
+ (memory_order_)) \
+ : kit_atomic_exchange_explicit_64((u64 volatile *) (var_), \
+ (u64) (value_), \
+ (memory_order_))))
+
+# define atomic_compare_exchange_strong_explicit( \
+ var_, expected_, value_, memory_order_succ_, \
+ memory_order_fail_) \
+ (assert(sizeof *(var_) == 1 || sizeof *(var_) == 2 || \
+ sizeof *(var_) == 4 || sizeof *(var_) == 8), \
+ (sizeof *(var_) == 1 \
+ ? kit_atomic_compare_exchange_explicit_8( \
+ (u8 volatile *) (var_), (u8 *) (expected_), \
+ (u8) (value_), (memory_order_succ_), \
+ (memory_order_fail_)) \
+ : sizeof *(var_) == 2 \
+ ? kit_atomic_compare_exchange_explicit_16( \
+ (u16 volatile *) (var_), (u16 *) (expected_), \
+ (u16) (value_), (memory_order_succ_), \
+ (memory_order_fail_)) \
+ : sizeof *(var_) == 4 \
+ ? kit_atomic_compare_exchange_explicit_32( \
+ (u32 volatile *) (var_), (u32 *) (expected_), \
+ (u32) (value_), (memory_order_succ_), \
+ (memory_order_fail_)) \
+ : kit_atomic_compare_exchange_explicit_64( \
+ (u64 volatile *) (var_), (u64 *) (expected_), \
+ (u64) (value_), (memory_order_succ_), \
+ (memory_order_fail_))))
+
+# define atomic_compare_exchange_weak_explicit( \
+ var_, expected_, value_, memory_order_succ_, \
+ memory_order_fail_) \
+ atomic_compare_exchange_strong_explicit(var_, expected_, value_, \
+ memory_order_succ_, \
+ memory_order_fail_)
+
+# define atomic_fetch_add_explicit(var_, value_, memory_order_) \
+ (assert(sizeof *(var_) == 1 || sizeof *(var_) == 2 || \
+ sizeof *(var_) == 4 || sizeof *(var_) == 8), \
+ (sizeof *(var_) == 1 ? kit_atomic_fetch_add_explicit_8( \
+ (u8 volatile *) (var_), \
+ (u8) (value_), (memory_order_)) \
+ : sizeof *(var_) == 2 ? kit_atomic_fetch_add_explicit_16( \
+ (u16 volatile *) (var_), \
+ (u16) (value_), (memory_order_)) \
+ : sizeof *(var_) == 4 ? kit_atomic_fetch_add_explicit_32( \
+ (u32 volatile *) (var_), \
+ (u32) (value_), (memory_order_)) \
+ : kit_atomic_fetch_add_explicit_64( \
+ (u64 volatile *) (var_), \
+ (u64) (value_), (memory_order_))))
+
+# define atomic_store(var_, value_) \
+ atomic_store(var_, value_, memory_order_seq_cst)
+
+# define atomic_load(var_) atomic_load(var_, memory_order_seq_cst)
+
+# define atomic_exchange(var_, value_) \
+ atomic_exchange(var_, value_, memory_order_seq_cst)
+
+# define atomic_compare_exchange_strong(var_, expected_, value_) \
+ atomic_compare_exchange_strong_explicit(var_, expected_, value_, \
+ memory_order_seq_cst, \
+ memory_order_seq_cst)
+
+# define atomic_compare_exchange_weak(var_, expected_, value_) \
+ atomic_compare_exchange_weak_explicit(var_, expected_, value_, \
+ memory_order_seq_cst, \
+ memory_order_seq_cst)
+
+# define atomic_fetch_add(var_, value_) \
+ atomic_fetch_add(var_, value_, memory_order_seq_cst)
+
+# ifdef __cplusplus
+}
+# endif
+#endif
+
+#define ATOMIC KIT_ATOMIC
+
+#endif