stdatomic.h (8135B)
1 /* stdatomic.h -- C11 7.17 -- Atomics 2 * 3 * Atomic codegen, lock-free shape, and fence semantics are entirely 4 * target-defined, so this header is a thin C11 surface over kit's 5 * atomic builtins. The `__atomic_*` family operates transparently on 6 * `_Atomic`-qualified pointers; lock-free properties come from the 7 * `__ATOMIC_*_LOCK_FREE` macros. 8 */ 9 #ifndef KIT_STDATOMIC_H 10 #define KIT_STDATOMIC_H 11 12 #include <stddef.h> 13 #include <stdint.h> 14 15 /* ------------------------------------------------------------------ */ 16 /* 7.17.3 Order and consistency */ 17 /* ------------------------------------------------------------------ */ 18 typedef enum memory_order { 19 memory_order_relaxed = __ATOMIC_RELAXED, 20 memory_order_consume = __ATOMIC_CONSUME, 21 memory_order_acquire = __ATOMIC_ACQUIRE, 22 memory_order_release = __ATOMIC_RELEASE, 23 memory_order_acq_rel = __ATOMIC_ACQ_REL, 24 memory_order_seq_cst = __ATOMIC_SEQ_CST, 25 } memory_order; 26 27 #define kill_dependency(y) (y) 28 29 /* ------------------------------------------------------------------ */ 30 /* 7.17.1 Lock-free property macros */ 31 /* ------------------------------------------------------------------ */ 32 #define ATOMIC_BOOL_LOCK_FREE __ATOMIC_BOOL_LOCK_FREE 33 #define ATOMIC_CHAR_LOCK_FREE __ATOMIC_CHAR_LOCK_FREE 34 #define ATOMIC_CHAR16_T_LOCK_FREE __ATOMIC_CHAR16_T_LOCK_FREE 35 #define ATOMIC_CHAR32_T_LOCK_FREE __ATOMIC_CHAR32_T_LOCK_FREE 36 #define ATOMIC_WCHAR_T_LOCK_FREE __ATOMIC_WCHAR_T_LOCK_FREE 37 #define ATOMIC_SHORT_LOCK_FREE __ATOMIC_SHORT_LOCK_FREE 38 #define ATOMIC_INT_LOCK_FREE __ATOMIC_INT_LOCK_FREE 39 #define ATOMIC_LONG_LOCK_FREE __ATOMIC_LONG_LOCK_FREE 40 #define ATOMIC_LLONG_LOCK_FREE __ATOMIC_LLONG_LOCK_FREE 41 #define ATOMIC_POINTER_LOCK_FREE __ATOMIC_POINTER_LOCK_FREE 42 43 /* ------------------------------------------------------------------ */ 44 /* 7.17.2 Initialization */ 45 /* ------------------------------------------------------------------ */ 46 #define ATOMIC_VAR_INIT(value) (value) 47 #define atomic_init(obj, value) \ 48 __atomic_store_n((obj), (value), __ATOMIC_RELAXED) 49 50 /* ------------------------------------------------------------------ */ 51 /* 7.17.4 Fences */ 52 /* ------------------------------------------------------------------ */ 53 #define atomic_thread_fence(order) __atomic_thread_fence(order) 54 #define atomic_signal_fence(order) __atomic_signal_fence(order) 55 56 /* ------------------------------------------------------------------ */ 57 /* 7.17.5 Lock-free property query */ 58 /* ------------------------------------------------------------------ */ 59 #define atomic_is_lock_free(obj) __atomic_is_lock_free(sizeof(*(obj)), (obj)) 60 61 /* ------------------------------------------------------------------ */ 62 /* 7.17.6 Atomic integer types */ 63 /* ------------------------------------------------------------------ */ 64 typedef _Atomic _Bool atomic_bool; 65 typedef _Atomic char atomic_char; 66 typedef _Atomic signed char atomic_schar; 67 typedef _Atomic unsigned char atomic_uchar; 68 typedef _Atomic short atomic_short; 69 typedef _Atomic unsigned short atomic_ushort; 70 typedef _Atomic int atomic_int; 71 typedef _Atomic unsigned int atomic_uint; 72 typedef _Atomic long atomic_long; 73 typedef _Atomic unsigned long atomic_ulong; 74 typedef _Atomic long long atomic_llong; 75 typedef _Atomic unsigned long long atomic_ullong; 76 typedef _Atomic __CHAR16_TYPE__ atomic_char16_t; 77 typedef _Atomic __CHAR32_TYPE__ atomic_char32_t; 78 typedef _Atomic __WCHAR_TYPE__ atomic_wchar_t; 79 typedef _Atomic int_least8_t atomic_int_least8_t; 80 typedef _Atomic uint_least8_t atomic_uint_least8_t; 81 typedef _Atomic int_least16_t atomic_int_least16_t; 82 typedef _Atomic uint_least16_t atomic_uint_least16_t; 83 typedef _Atomic int_least32_t atomic_int_least32_t; 84 typedef _Atomic uint_least32_t atomic_uint_least32_t; 85 typedef _Atomic int_least64_t atomic_int_least64_t; 86 typedef _Atomic uint_least64_t atomic_uint_least64_t; 87 typedef _Atomic int_fast8_t atomic_int_fast8_t; 88 typedef _Atomic uint_fast8_t atomic_uint_fast8_t; 89 typedef _Atomic int_fast16_t atomic_int_fast16_t; 90 typedef _Atomic uint_fast16_t atomic_uint_fast16_t; 91 typedef _Atomic int_fast32_t atomic_int_fast32_t; 92 typedef _Atomic uint_fast32_t atomic_uint_fast32_t; 93 typedef _Atomic int_fast64_t atomic_int_fast64_t; 94 typedef _Atomic uint_fast64_t atomic_uint_fast64_t; 95 typedef _Atomic intptr_t atomic_intptr_t; 96 typedef _Atomic uintptr_t atomic_uintptr_t; 97 typedef _Atomic size_t atomic_size_t; 98 typedef _Atomic ptrdiff_t atomic_ptrdiff_t; 99 typedef _Atomic intmax_t atomic_intmax_t; 100 typedef _Atomic uintmax_t atomic_uintmax_t; 101 102 /* ------------------------------------------------------------------ */ 103 /* 7.17.7 Operations on atomic types */ 104 /* ------------------------------------------------------------------ */ 105 #define atomic_store(obj, desired) \ 106 __atomic_store_n((obj), (desired), __ATOMIC_SEQ_CST) 107 #define atomic_store_explicit(obj, desired, order) \ 108 __atomic_store_n((obj), (desired), (order)) 109 110 #define atomic_load(obj) __atomic_load_n((obj), __ATOMIC_SEQ_CST) 111 #define atomic_load_explicit(obj, order) __atomic_load_n((obj), (order)) 112 113 #define atomic_exchange(obj, desired) \ 114 __atomic_exchange_n((obj), (desired), __ATOMIC_SEQ_CST) 115 #define atomic_exchange_explicit(obj, desired, order) \ 116 __atomic_exchange_n((obj), (desired), (order)) 117 118 #define atomic_compare_exchange_strong(obj, expected, desired) \ 119 __atomic_compare_exchange_n((obj), (expected), (desired), 0, \ 120 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) 121 #define atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, \ 122 fail) \ 123 __atomic_compare_exchange_n((obj), (expected), (desired), 0, (succ), (fail)) 124 #define atomic_compare_exchange_weak(obj, expected, desired) \ 125 __atomic_compare_exchange_n((obj), (expected), (desired), 1, \ 126 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) 127 #define atomic_compare_exchange_weak_explicit(obj, expected, desired, succ, \ 128 fail) \ 129 __atomic_compare_exchange_n((obj), (expected), (desired), 1, (succ), (fail)) 130 131 #define atomic_fetch_add(obj, arg) \ 132 __atomic_fetch_add((obj), (arg), __ATOMIC_SEQ_CST) 133 #define atomic_fetch_add_explicit(obj, arg, order) \ 134 __atomic_fetch_add((obj), (arg), (order)) 135 #define atomic_fetch_sub(obj, arg) \ 136 __atomic_fetch_sub((obj), (arg), __ATOMIC_SEQ_CST) 137 #define atomic_fetch_sub_explicit(obj, arg, order) \ 138 __atomic_fetch_sub((obj), (arg), (order)) 139 #define atomic_fetch_or(obj, arg) \ 140 __atomic_fetch_or((obj), (arg), __ATOMIC_SEQ_CST) 141 #define atomic_fetch_or_explicit(obj, arg, order) \ 142 __atomic_fetch_or((obj), (arg), (order)) 143 #define atomic_fetch_xor(obj, arg) \ 144 __atomic_fetch_xor((obj), (arg), __ATOMIC_SEQ_CST) 145 #define atomic_fetch_xor_explicit(obj, arg, order) \ 146 __atomic_fetch_xor((obj), (arg), (order)) 147 #define atomic_fetch_and(obj, arg) \ 148 __atomic_fetch_and((obj), (arg), __ATOMIC_SEQ_CST) 149 #define atomic_fetch_and_explicit(obj, arg, order) \ 150 __atomic_fetch_and((obj), (arg), (order)) 151 152 /* ------------------------------------------------------------------ */ 153 /* 7.17.8 Atomic flag */ 154 /* ------------------------------------------------------------------ */ 155 typedef struct atomic_flag { 156 /* Opaque flag storage may be wider than _Bool; use a word-sized atomic so 157 every primary backend can implement test-and-set with native RMW width. */ 158 _Atomic unsigned int _Value; 159 } atomic_flag; 160 161 #define ATOMIC_FLAG_INIT {0} 162 163 #define atomic_flag_test_and_set(obj) \ 164 __atomic_exchange_n(&(obj)->_Value, 1, __ATOMIC_SEQ_CST) 165 #define atomic_flag_test_and_set_explicit(obj, order) \ 166 __atomic_exchange_n(&(obj)->_Value, 1, (order)) 167 #define atomic_flag_clear(obj) \ 168 __atomic_store_n(&(obj)->_Value, 0, __ATOMIC_SEQ_CST) 169 #define atomic_flag_clear_explicit(obj, order) \ 170 __atomic_store_n(&(obj)->_Value, 0, (order)) 171 172 #endif