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