1*0a6a1f1dSLionel Sambuc /*===---- stdatomic.h - Standard header for atomic types and operations -----=== 2*0a6a1f1dSLionel Sambuc * 3*0a6a1f1dSLionel Sambuc * Permission is hereby granted, free of charge, to any person obtaining a copy 4*0a6a1f1dSLionel Sambuc * of this software and associated documentation files (the "Software"), to deal 5*0a6a1f1dSLionel Sambuc * in the Software without restriction, including without limitation the rights 6*0a6a1f1dSLionel Sambuc * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7*0a6a1f1dSLionel Sambuc * copies of the Software, and to permit persons to whom the Software is 8*0a6a1f1dSLionel Sambuc * furnished to do so, subject to the following conditions: 9*0a6a1f1dSLionel Sambuc * 10*0a6a1f1dSLionel Sambuc * The above copyright notice and this permission notice shall be included in 11*0a6a1f1dSLionel Sambuc * all copies or substantial portions of the Software. 12*0a6a1f1dSLionel Sambuc * 13*0a6a1f1dSLionel Sambuc * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14*0a6a1f1dSLionel Sambuc * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15*0a6a1f1dSLionel Sambuc * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16*0a6a1f1dSLionel Sambuc * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17*0a6a1f1dSLionel Sambuc * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18*0a6a1f1dSLionel Sambuc * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19*0a6a1f1dSLionel Sambuc * THE SOFTWARE. 20*0a6a1f1dSLionel Sambuc * 21*0a6a1f1dSLionel Sambuc *===-----------------------------------------------------------------------=== 22*0a6a1f1dSLionel Sambuc */ 23*0a6a1f1dSLionel Sambuc 24*0a6a1f1dSLionel Sambuc #ifndef __CLANG_STDATOMIC_H 25*0a6a1f1dSLionel Sambuc #define __CLANG_STDATOMIC_H 26*0a6a1f1dSLionel Sambuc 27*0a6a1f1dSLionel Sambuc /* If we're hosted, fall back to the system's stdatomic.h. FreeBSD, for 28*0a6a1f1dSLionel Sambuc * example, already has a Clang-compatible stdatomic.h header. 29*0a6a1f1dSLionel Sambuc */ 30*0a6a1f1dSLionel Sambuc #if __STDC_HOSTED__ && __has_include_next(<stdatomic.h>) 31*0a6a1f1dSLionel Sambuc # include_next <stdatomic.h> 32*0a6a1f1dSLionel Sambuc #else 33*0a6a1f1dSLionel Sambuc 34*0a6a1f1dSLionel Sambuc #include <stddef.h> 35*0a6a1f1dSLionel Sambuc #include <stdint.h> 36*0a6a1f1dSLionel Sambuc 37*0a6a1f1dSLionel Sambuc #ifdef __cplusplus 38*0a6a1f1dSLionel Sambuc extern "C" { 39*0a6a1f1dSLionel Sambuc #endif 40*0a6a1f1dSLionel Sambuc 41*0a6a1f1dSLionel Sambuc /* 7.17.1 Introduction */ 42*0a6a1f1dSLionel Sambuc 43*0a6a1f1dSLionel Sambuc #define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE 44*0a6a1f1dSLionel Sambuc #define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE 45*0a6a1f1dSLionel Sambuc #define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE 46*0a6a1f1dSLionel Sambuc #define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE 47*0a6a1f1dSLionel Sambuc #define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE 48*0a6a1f1dSLionel Sambuc #define ATOMIC_SHORT_T_LOCK_FREE __GCC_ATOMIC_SHORT_T_LOCK_FREE 49*0a6a1f1dSLionel Sambuc #define ATOMIC_INT_T_LOCK_FREE __GCC_ATOMIC_INT_T_LOCK_FREE 50*0a6a1f1dSLionel Sambuc #define ATOMIC_LONG_T_LOCK_FREE __GCC_ATOMIC_LONG_T_LOCK_FREE 51*0a6a1f1dSLionel Sambuc #define ATOMIC_LLONG_T_LOCK_FREE __GCC_ATOMIC_LLONG_T_LOCK_FREE 52*0a6a1f1dSLionel Sambuc #define ATOMIC_POINTER_T_LOCK_FREE __GCC_ATOMIC_POINTER_T_LOCK_FREE 53*0a6a1f1dSLionel Sambuc 54*0a6a1f1dSLionel Sambuc /* 7.17.2 Initialization */ 55*0a6a1f1dSLionel Sambuc 56*0a6a1f1dSLionel Sambuc #define ATOMIC_VAR_INIT(value) (value) 57*0a6a1f1dSLionel Sambuc #define atomic_init __c11_atomic_init 58*0a6a1f1dSLionel Sambuc 59*0a6a1f1dSLionel Sambuc /* 7.17.3 Order and consistency */ 60*0a6a1f1dSLionel Sambuc 61*0a6a1f1dSLionel Sambuc typedef enum memory_order { 62*0a6a1f1dSLionel Sambuc memory_order_relaxed = __ATOMIC_RELAXED, 63*0a6a1f1dSLionel Sambuc memory_order_consume = __ATOMIC_CONSUME, 64*0a6a1f1dSLionel Sambuc memory_order_acquire = __ATOMIC_ACQUIRE, 65*0a6a1f1dSLionel Sambuc memory_order_release = __ATOMIC_RELEASE, 66*0a6a1f1dSLionel Sambuc memory_order_acq_rel = __ATOMIC_ACQ_REL, 67*0a6a1f1dSLionel Sambuc memory_order_seq_cst = __ATOMIC_SEQ_CST 68*0a6a1f1dSLionel Sambuc } memory_order; 69*0a6a1f1dSLionel Sambuc 70*0a6a1f1dSLionel Sambuc #define kill_dependency(y) (y) 71*0a6a1f1dSLionel Sambuc 72*0a6a1f1dSLionel Sambuc /* 7.17.4 Fences */ 73*0a6a1f1dSLionel Sambuc 74*0a6a1f1dSLionel Sambuc // These should be provided by the libc implementation. 75*0a6a1f1dSLionel Sambuc void atomic_thread_fence(memory_order); 76*0a6a1f1dSLionel Sambuc void atomic_signal_fence(memory_order); 77*0a6a1f1dSLionel Sambuc 78*0a6a1f1dSLionel Sambuc #define atomic_thread_fence(order) __c11_atomic_thread_fence(order) 79*0a6a1f1dSLionel Sambuc #define atomic_signal_fence(order) __c11_atomic_signal_fence(order) 80*0a6a1f1dSLionel Sambuc 81*0a6a1f1dSLionel Sambuc /* 7.17.5 Lock-free property */ 82*0a6a1f1dSLionel Sambuc 83*0a6a1f1dSLionel Sambuc #define atomic_is_lock_free(obj) __c11_atomic_is_lock_free(sizeof(*(obj))) 84*0a6a1f1dSLionel Sambuc 85*0a6a1f1dSLionel Sambuc /* 7.17.6 Atomic integer types */ 86*0a6a1f1dSLionel Sambuc 87*0a6a1f1dSLionel Sambuc #ifdef __cplusplus 88*0a6a1f1dSLionel Sambuc typedef _Atomic(bool) atomic_bool; 89*0a6a1f1dSLionel Sambuc #else 90*0a6a1f1dSLionel Sambuc typedef _Atomic(_Bool) atomic_bool; 91*0a6a1f1dSLionel Sambuc #endif 92*0a6a1f1dSLionel Sambuc typedef _Atomic(char) atomic_char; 93*0a6a1f1dSLionel Sambuc typedef _Atomic(signed char) atomic_schar; 94*0a6a1f1dSLionel Sambuc typedef _Atomic(unsigned char) atomic_uchar; 95*0a6a1f1dSLionel Sambuc typedef _Atomic(short) atomic_short; 96*0a6a1f1dSLionel Sambuc typedef _Atomic(unsigned short) atomic_ushort; 97*0a6a1f1dSLionel Sambuc typedef _Atomic(int) atomic_int; 98*0a6a1f1dSLionel Sambuc typedef _Atomic(unsigned int) atomic_uint; 99*0a6a1f1dSLionel Sambuc typedef _Atomic(long) atomic_long; 100*0a6a1f1dSLionel Sambuc typedef _Atomic(unsigned long) atomic_ulong; 101*0a6a1f1dSLionel Sambuc typedef _Atomic(long long) atomic_llong; 102*0a6a1f1dSLionel Sambuc typedef _Atomic(unsigned long long) atomic_ullong; 103*0a6a1f1dSLionel Sambuc typedef _Atomic(uint_least16_t) atomic_char16_t; 104*0a6a1f1dSLionel Sambuc typedef _Atomic(uint_least32_t) atomic_char32_t; 105*0a6a1f1dSLionel Sambuc typedef _Atomic(wchar_t) atomic_wchar_t; 106*0a6a1f1dSLionel Sambuc typedef _Atomic(int_least8_t) atomic_int_least8_t; 107*0a6a1f1dSLionel Sambuc typedef _Atomic(uint_least8_t) atomic_uint_least8_t; 108*0a6a1f1dSLionel Sambuc typedef _Atomic(int_least16_t) atomic_int_least16_t; 109*0a6a1f1dSLionel Sambuc typedef _Atomic(uint_least16_t) atomic_uint_least16_t; 110*0a6a1f1dSLionel Sambuc typedef _Atomic(int_least32_t) atomic_int_least32_t; 111*0a6a1f1dSLionel Sambuc typedef _Atomic(uint_least32_t) atomic_uint_least32_t; 112*0a6a1f1dSLionel Sambuc typedef _Atomic(int_least64_t) atomic_int_least64_t; 113*0a6a1f1dSLionel Sambuc typedef _Atomic(uint_least64_t) atomic_uint_least64_t; 114*0a6a1f1dSLionel Sambuc typedef _Atomic(int_fast8_t) atomic_int_fast8_t; 115*0a6a1f1dSLionel Sambuc typedef _Atomic(uint_fast8_t) atomic_uint_fast8_t; 116*0a6a1f1dSLionel Sambuc typedef _Atomic(int_fast16_t) atomic_int_fast16_t; 117*0a6a1f1dSLionel Sambuc typedef _Atomic(uint_fast16_t) atomic_uint_fast16_t; 118*0a6a1f1dSLionel Sambuc typedef _Atomic(int_fast32_t) atomic_int_fast32_t; 119*0a6a1f1dSLionel Sambuc typedef _Atomic(uint_fast32_t) atomic_uint_fast32_t; 120*0a6a1f1dSLionel Sambuc typedef _Atomic(int_fast64_t) atomic_int_fast64_t; 121*0a6a1f1dSLionel Sambuc typedef _Atomic(uint_fast64_t) atomic_uint_fast64_t; 122*0a6a1f1dSLionel Sambuc typedef _Atomic(intptr_t) atomic_intptr_t; 123*0a6a1f1dSLionel Sambuc typedef _Atomic(uintptr_t) atomic_uintptr_t; 124*0a6a1f1dSLionel Sambuc typedef _Atomic(size_t) atomic_size_t; 125*0a6a1f1dSLionel Sambuc typedef _Atomic(ptrdiff_t) atomic_ptrdiff_t; 126*0a6a1f1dSLionel Sambuc typedef _Atomic(intmax_t) atomic_intmax_t; 127*0a6a1f1dSLionel Sambuc typedef _Atomic(uintmax_t) atomic_uintmax_t; 128*0a6a1f1dSLionel Sambuc 129*0a6a1f1dSLionel Sambuc /* 7.17.7 Operations on atomic types */ 130*0a6a1f1dSLionel Sambuc 131*0a6a1f1dSLionel Sambuc #define atomic_store(object, desired) __c11_atomic_store(object, desired, __ATOMIC_SEQ_CST) 132*0a6a1f1dSLionel Sambuc #define atomic_store_explicit __c11_atomic_store 133*0a6a1f1dSLionel Sambuc 134*0a6a1f1dSLionel Sambuc #define atomic_load(object) __c11_atomic_load(object, __ATOMIC_SEQ_CST) 135*0a6a1f1dSLionel Sambuc #define atomic_load_explicit __c11_atomic_load 136*0a6a1f1dSLionel Sambuc 137*0a6a1f1dSLionel Sambuc #define atomic_exchange(object, desired) __c11_atomic_exchange(object, desired, __ATOMIC_SEQ_CST) 138*0a6a1f1dSLionel Sambuc #define atomic_exchange_explicit __c11_atomic_exchange 139*0a6a1f1dSLionel Sambuc 140*0a6a1f1dSLionel Sambuc #define atomic_compare_exchange_strong(object, expected, desired) __c11_atomic_compare_exchange_strong(object, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) 141*0a6a1f1dSLionel Sambuc #define atomic_compare_exchange_strong_explicit __c11_atomic_compare_exchange_strong 142*0a6a1f1dSLionel Sambuc 143*0a6a1f1dSLionel Sambuc #define atomic_compare_exchange_weak(object, expected, desired) __c11_atomic_compare_exchange_weak(object, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) 144*0a6a1f1dSLionel Sambuc #define atomic_compare_exchange_weak_explicit __c11_atomic_compare_exchange_weak 145*0a6a1f1dSLionel Sambuc 146*0a6a1f1dSLionel Sambuc #define atomic_fetch_add(object, operand) __c11_atomic_fetch_add(object, operand, __ATOMIC_SEQ_CST) 147*0a6a1f1dSLionel Sambuc #define atomic_fetch_add_explicit __c11_atomic_fetch_add 148*0a6a1f1dSLionel Sambuc 149*0a6a1f1dSLionel Sambuc #define atomic_fetch_sub(object, operand) __c11_atomic_fetch_sub(object, operand, __ATOMIC_SEQ_CST) 150*0a6a1f1dSLionel Sambuc #define atomic_fetch_sub_explicit __c11_atomic_fetch_sub 151*0a6a1f1dSLionel Sambuc 152*0a6a1f1dSLionel Sambuc #define atomic_fetch_or(object, operand) __c11_atomic_fetch_or(object, operand, __ATOMIC_SEQ_CST) 153*0a6a1f1dSLionel Sambuc #define atomic_fetch_or_explicit __c11_atomic_fetch_or 154*0a6a1f1dSLionel Sambuc 155*0a6a1f1dSLionel Sambuc #define atomic_fetch_xor(object, operand) __c11_atomic_fetch_xor(object, operand, __ATOMIC_SEQ_CST) 156*0a6a1f1dSLionel Sambuc #define atomic_fetch_xor_explicit __c11_atomic_fetch_xor 157*0a6a1f1dSLionel Sambuc 158*0a6a1f1dSLionel Sambuc #define atomic_fetch_and(object, operand) __c11_atomic_fetch_and(object, operand, __ATOMIC_SEQ_CST) 159*0a6a1f1dSLionel Sambuc #define atomic_fetch_and_explicit __c11_atomic_fetch_and 160*0a6a1f1dSLionel Sambuc 161*0a6a1f1dSLionel Sambuc /* 7.17.8 Atomic flag type and operations */ 162*0a6a1f1dSLionel Sambuc 163*0a6a1f1dSLionel Sambuc typedef struct atomic_flag { atomic_bool _Value; } atomic_flag; 164*0a6a1f1dSLionel Sambuc 165*0a6a1f1dSLionel Sambuc #define ATOMIC_FLAG_INIT { 0 } 166*0a6a1f1dSLionel Sambuc 167*0a6a1f1dSLionel Sambuc // These should be provided by the libc implementation. 168*0a6a1f1dSLionel Sambuc #ifdef __cplusplus 169*0a6a1f1dSLionel Sambuc bool atomic_flag_test_and_set(volatile atomic_flag *); 170*0a6a1f1dSLionel Sambuc bool atomic_flag_test_and_set_explicit(volatile atomic_flag *, memory_order); 171*0a6a1f1dSLionel Sambuc #else 172*0a6a1f1dSLionel Sambuc _Bool atomic_flag_test_and_set(volatile atomic_flag *); 173*0a6a1f1dSLionel Sambuc _Bool atomic_flag_test_and_set_explicit(volatile atomic_flag *, memory_order); 174*0a6a1f1dSLionel Sambuc #endif 175*0a6a1f1dSLionel Sambuc void atomic_flag_clear(volatile atomic_flag *); 176*0a6a1f1dSLionel Sambuc void atomic_flag_clear_explicit(volatile atomic_flag *, memory_order); 177*0a6a1f1dSLionel Sambuc 178*0a6a1f1dSLionel Sambuc #define atomic_flag_test_and_set(object) __c11_atomic_exchange(&(object)->_Value, 1, __ATOMIC_SEQ_CST) 179*0a6a1f1dSLionel Sambuc #define atomic_flag_test_and_set_explicit(object, order) __c11_atomic_exchange(&(object)->_Value, 1, order) 180*0a6a1f1dSLionel Sambuc 181*0a6a1f1dSLionel Sambuc #define atomic_flag_clear(object) __c11_atomic_store(&(object)->_Value, 0, __ATOMIC_SEQ_CST) 182*0a6a1f1dSLionel Sambuc #define atomic_flag_clear_explicit(object, order) __c11_atomic_store(&(object)->_Value, 0, order) 183*0a6a1f1dSLionel Sambuc 184*0a6a1f1dSLionel Sambuc #ifdef __cplusplus 185*0a6a1f1dSLionel Sambuc } 186*0a6a1f1dSLionel Sambuc #endif 187*0a6a1f1dSLionel Sambuc 188*0a6a1f1dSLionel Sambuc #endif /* __STDC_HOSTED__ */ 189*0a6a1f1dSLionel Sambuc #endif /* __CLANG_STDATOMIC_H */ 190*0a6a1f1dSLionel Sambuc 191