1*38fd1498Szrj /* Copyright (C) 2013-2018 Free Software Foundation, Inc. 2*38fd1498Szrj 3*38fd1498Szrj This file is part of GCC. 4*38fd1498Szrj 5*38fd1498Szrj GCC is free software; you can redistribute it and/or modify 6*38fd1498Szrj it under the terms of the GNU General Public License as published by 7*38fd1498Szrj the Free Software Foundation; either version 3, or (at your option) 8*38fd1498Szrj any later version. 9*38fd1498Szrj 10*38fd1498Szrj GCC is distributed in the hope that it will be useful, 11*38fd1498Szrj but WITHOUT ANY WARRANTY; without even the implied warranty of 12*38fd1498Szrj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13*38fd1498Szrj GNU General Public License for more details. 14*38fd1498Szrj 15*38fd1498Szrj Under Section 7 of GPL version 3, you are granted additional 16*38fd1498Szrj permissions described in the GCC Runtime Library Exception, version 17*38fd1498Szrj 3.1, as published by the Free Software Foundation. 18*38fd1498Szrj 19*38fd1498Szrj You should have received a copy of the GNU General Public License and 20*38fd1498Szrj a copy of the GCC Runtime Library Exception along with this program; 21*38fd1498Szrj see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 22*38fd1498Szrj <http://www.gnu.org/licenses/>. */ 23*38fd1498Szrj 24*38fd1498Szrj /* ISO C11 Standard: 7.17 Atomics <stdatomic.h>. */ 25*38fd1498Szrj 26*38fd1498Szrj #ifndef _STDATOMIC_H 27*38fd1498Szrj #define _STDATOMIC_H 28*38fd1498Szrj 29*38fd1498Szrj typedef enum 30*38fd1498Szrj { 31*38fd1498Szrj memory_order_relaxed = __ATOMIC_RELAXED, 32*38fd1498Szrj memory_order_consume = __ATOMIC_CONSUME, 33*38fd1498Szrj memory_order_acquire = __ATOMIC_ACQUIRE, 34*38fd1498Szrj memory_order_release = __ATOMIC_RELEASE, 35*38fd1498Szrj memory_order_acq_rel = __ATOMIC_ACQ_REL, 36*38fd1498Szrj memory_order_seq_cst = __ATOMIC_SEQ_CST 37*38fd1498Szrj } memory_order; 38*38fd1498Szrj 39*38fd1498Szrj 40*38fd1498Szrj typedef _Atomic _Bool atomic_bool; 41*38fd1498Szrj typedef _Atomic char atomic_char; 42*38fd1498Szrj typedef _Atomic signed char atomic_schar; 43*38fd1498Szrj typedef _Atomic unsigned char atomic_uchar; 44*38fd1498Szrj typedef _Atomic short atomic_short; 45*38fd1498Szrj typedef _Atomic unsigned short atomic_ushort; 46*38fd1498Szrj typedef _Atomic int atomic_int; 47*38fd1498Szrj typedef _Atomic unsigned int atomic_uint; 48*38fd1498Szrj typedef _Atomic long atomic_long; 49*38fd1498Szrj typedef _Atomic unsigned long atomic_ulong; 50*38fd1498Szrj typedef _Atomic long long atomic_llong; 51*38fd1498Szrj typedef _Atomic unsigned long long atomic_ullong; 52*38fd1498Szrj typedef _Atomic __CHAR16_TYPE__ atomic_char16_t; 53*38fd1498Szrj typedef _Atomic __CHAR32_TYPE__ atomic_char32_t; 54*38fd1498Szrj typedef _Atomic __WCHAR_TYPE__ atomic_wchar_t; 55*38fd1498Szrj typedef _Atomic __INT_LEAST8_TYPE__ atomic_int_least8_t; 56*38fd1498Szrj typedef _Atomic __UINT_LEAST8_TYPE__ atomic_uint_least8_t; 57*38fd1498Szrj typedef _Atomic __INT_LEAST16_TYPE__ atomic_int_least16_t; 58*38fd1498Szrj typedef _Atomic __UINT_LEAST16_TYPE__ atomic_uint_least16_t; 59*38fd1498Szrj typedef _Atomic __INT_LEAST32_TYPE__ atomic_int_least32_t; 60*38fd1498Szrj typedef _Atomic __UINT_LEAST32_TYPE__ atomic_uint_least32_t; 61*38fd1498Szrj typedef _Atomic __INT_LEAST64_TYPE__ atomic_int_least64_t; 62*38fd1498Szrj typedef _Atomic __UINT_LEAST64_TYPE__ atomic_uint_least64_t; 63*38fd1498Szrj typedef _Atomic __INT_FAST8_TYPE__ atomic_int_fast8_t; 64*38fd1498Szrj typedef _Atomic __UINT_FAST8_TYPE__ atomic_uint_fast8_t; 65*38fd1498Szrj typedef _Atomic __INT_FAST16_TYPE__ atomic_int_fast16_t; 66*38fd1498Szrj typedef _Atomic __UINT_FAST16_TYPE__ atomic_uint_fast16_t; 67*38fd1498Szrj typedef _Atomic __INT_FAST32_TYPE__ atomic_int_fast32_t; 68*38fd1498Szrj typedef _Atomic __UINT_FAST32_TYPE__ atomic_uint_fast32_t; 69*38fd1498Szrj typedef _Atomic __INT_FAST64_TYPE__ atomic_int_fast64_t; 70*38fd1498Szrj typedef _Atomic __UINT_FAST64_TYPE__ atomic_uint_fast64_t; 71*38fd1498Szrj typedef _Atomic __INTPTR_TYPE__ atomic_intptr_t; 72*38fd1498Szrj typedef _Atomic __UINTPTR_TYPE__ atomic_uintptr_t; 73*38fd1498Szrj typedef _Atomic __SIZE_TYPE__ atomic_size_t; 74*38fd1498Szrj typedef _Atomic __PTRDIFF_TYPE__ atomic_ptrdiff_t; 75*38fd1498Szrj typedef _Atomic __INTMAX_TYPE__ atomic_intmax_t; 76*38fd1498Szrj typedef _Atomic __UINTMAX_TYPE__ atomic_uintmax_t; 77*38fd1498Szrj 78*38fd1498Szrj 79*38fd1498Szrj #define ATOMIC_VAR_INIT(VALUE) (VALUE) 80*38fd1498Szrj 81*38fd1498Szrj /* Initialize an atomic object pointed to by PTR with VAL. */ 82*38fd1498Szrj #define atomic_init(PTR, VAL) \ 83*38fd1498Szrj atomic_store_explicit (PTR, VAL, __ATOMIC_RELAXED) 84*38fd1498Szrj 85*38fd1498Szrj #define kill_dependency(Y) \ 86*38fd1498Szrj __extension__ \ 87*38fd1498Szrj ({ \ 88*38fd1498Szrj __auto_type __kill_dependency_tmp = (Y); \ 89*38fd1498Szrj __kill_dependency_tmp; \ 90*38fd1498Szrj }) 91*38fd1498Szrj 92*38fd1498Szrj extern void atomic_thread_fence (memory_order); 93*38fd1498Szrj #define atomic_thread_fence(MO) __atomic_thread_fence (MO) 94*38fd1498Szrj extern void atomic_signal_fence (memory_order); 95*38fd1498Szrj #define atomic_signal_fence(MO) __atomic_signal_fence (MO) 96*38fd1498Szrj #define atomic_is_lock_free(OBJ) __atomic_is_lock_free (sizeof (*(OBJ)), (OBJ)) 97*38fd1498Szrj 98*38fd1498Szrj #define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE 99*38fd1498Szrj #define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE 100*38fd1498Szrj #define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE 101*38fd1498Szrj #define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE 102*38fd1498Szrj #define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE 103*38fd1498Szrj #define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE 104*38fd1498Szrj #define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE 105*38fd1498Szrj #define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE 106*38fd1498Szrj #define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE 107*38fd1498Szrj #define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE 108*38fd1498Szrj 109*38fd1498Szrj 110*38fd1498Szrj /* Note that these macros require __typeof__ and __auto_type to remove 111*38fd1498Szrj _Atomic qualifiers (and const qualifiers, if those are valid on 112*38fd1498Szrj macro operands). 113*38fd1498Szrj 114*38fd1498Szrj Also note that the header file uses the generic form of __atomic 115*38fd1498Szrj builtins, which requires the address to be taken of the value 116*38fd1498Szrj parameter, and then we pass that value on. This allows the macros 117*38fd1498Szrj to work for any type, and the compiler is smart enough to convert 118*38fd1498Szrj these to lock-free _N variants if possible, and throw away the 119*38fd1498Szrj temps. */ 120*38fd1498Szrj 121*38fd1498Szrj #define atomic_store_explicit(PTR, VAL, MO) \ 122*38fd1498Szrj __extension__ \ 123*38fd1498Szrj ({ \ 124*38fd1498Szrj __auto_type __atomic_store_ptr = (PTR); \ 125*38fd1498Szrj __typeof__ (*__atomic_store_ptr) __atomic_store_tmp = (VAL); \ 126*38fd1498Szrj __atomic_store (__atomic_store_ptr, &__atomic_store_tmp, (MO)); \ 127*38fd1498Szrj }) 128*38fd1498Szrj 129*38fd1498Szrj #define atomic_store(PTR, VAL) \ 130*38fd1498Szrj atomic_store_explicit (PTR, VAL, __ATOMIC_SEQ_CST) 131*38fd1498Szrj 132*38fd1498Szrj 133*38fd1498Szrj #define atomic_load_explicit(PTR, MO) \ 134*38fd1498Szrj __extension__ \ 135*38fd1498Szrj ({ \ 136*38fd1498Szrj __auto_type __atomic_load_ptr = (PTR); \ 137*38fd1498Szrj __typeof__ (*__atomic_load_ptr) __atomic_load_tmp; \ 138*38fd1498Szrj __atomic_load (__atomic_load_ptr, &__atomic_load_tmp, (MO)); \ 139*38fd1498Szrj __atomic_load_tmp; \ 140*38fd1498Szrj }) 141*38fd1498Szrj 142*38fd1498Szrj #define atomic_load(PTR) atomic_load_explicit (PTR, __ATOMIC_SEQ_CST) 143*38fd1498Szrj 144*38fd1498Szrj 145*38fd1498Szrj #define atomic_exchange_explicit(PTR, VAL, MO) \ 146*38fd1498Szrj __extension__ \ 147*38fd1498Szrj ({ \ 148*38fd1498Szrj __auto_type __atomic_exchange_ptr = (PTR); \ 149*38fd1498Szrj __typeof__ (*__atomic_exchange_ptr) __atomic_exchange_val = (VAL); \ 150*38fd1498Szrj __typeof__ (*__atomic_exchange_ptr) __atomic_exchange_tmp; \ 151*38fd1498Szrj __atomic_exchange (__atomic_exchange_ptr, &__atomic_exchange_val, \ 152*38fd1498Szrj &__atomic_exchange_tmp, (MO)); \ 153*38fd1498Szrj __atomic_exchange_tmp; \ 154*38fd1498Szrj }) 155*38fd1498Szrj 156*38fd1498Szrj #define atomic_exchange(PTR, VAL) \ 157*38fd1498Szrj atomic_exchange_explicit (PTR, VAL, __ATOMIC_SEQ_CST) 158*38fd1498Szrj 159*38fd1498Szrj 160*38fd1498Szrj #define atomic_compare_exchange_strong_explicit(PTR, VAL, DES, SUC, FAIL) \ 161*38fd1498Szrj __extension__ \ 162*38fd1498Szrj ({ \ 163*38fd1498Szrj __auto_type __atomic_compare_exchange_ptr = (PTR); \ 164*38fd1498Szrj __typeof__ (*__atomic_compare_exchange_ptr) __atomic_compare_exchange_tmp \ 165*38fd1498Szrj = (DES); \ 166*38fd1498Szrj __atomic_compare_exchange (__atomic_compare_exchange_ptr, (VAL), \ 167*38fd1498Szrj &__atomic_compare_exchange_tmp, 0, \ 168*38fd1498Szrj (SUC), (FAIL)); \ 169*38fd1498Szrj }) 170*38fd1498Szrj 171*38fd1498Szrj #define atomic_compare_exchange_strong(PTR, VAL, DES) \ 172*38fd1498Szrj atomic_compare_exchange_strong_explicit (PTR, VAL, DES, __ATOMIC_SEQ_CST, \ 173*38fd1498Szrj __ATOMIC_SEQ_CST) 174*38fd1498Szrj 175*38fd1498Szrj #define atomic_compare_exchange_weak_explicit(PTR, VAL, DES, SUC, FAIL) \ 176*38fd1498Szrj __extension__ \ 177*38fd1498Szrj ({ \ 178*38fd1498Szrj __auto_type __atomic_compare_exchange_ptr = (PTR); \ 179*38fd1498Szrj __typeof__ (*__atomic_compare_exchange_ptr) __atomic_compare_exchange_tmp \ 180*38fd1498Szrj = (DES); \ 181*38fd1498Szrj __atomic_compare_exchange (__atomic_compare_exchange_ptr, (VAL), \ 182*38fd1498Szrj &__atomic_compare_exchange_tmp, 1, \ 183*38fd1498Szrj (SUC), (FAIL)); \ 184*38fd1498Szrj }) 185*38fd1498Szrj 186*38fd1498Szrj #define atomic_compare_exchange_weak(PTR, VAL, DES) \ 187*38fd1498Szrj atomic_compare_exchange_weak_explicit (PTR, VAL, DES, __ATOMIC_SEQ_CST, \ 188*38fd1498Szrj __ATOMIC_SEQ_CST) 189*38fd1498Szrj 190*38fd1498Szrj 191*38fd1498Szrj 192*38fd1498Szrj #define atomic_fetch_add(PTR, VAL) __atomic_fetch_add ((PTR), (VAL), \ 193*38fd1498Szrj __ATOMIC_SEQ_CST) 194*38fd1498Szrj #define atomic_fetch_add_explicit(PTR, VAL, MO) \ 195*38fd1498Szrj __atomic_fetch_add ((PTR), (VAL), (MO)) 196*38fd1498Szrj 197*38fd1498Szrj #define atomic_fetch_sub(PTR, VAL) __atomic_fetch_sub ((PTR), (VAL), \ 198*38fd1498Szrj __ATOMIC_SEQ_CST) 199*38fd1498Szrj #define atomic_fetch_sub_explicit(PTR, VAL, MO) \ 200*38fd1498Szrj __atomic_fetch_sub ((PTR), (VAL), (MO)) 201*38fd1498Szrj 202*38fd1498Szrj #define atomic_fetch_or(PTR, VAL) __atomic_fetch_or ((PTR), (VAL), \ 203*38fd1498Szrj __ATOMIC_SEQ_CST) 204*38fd1498Szrj #define atomic_fetch_or_explicit(PTR, VAL, MO) \ 205*38fd1498Szrj __atomic_fetch_or ((PTR), (VAL), (MO)) 206*38fd1498Szrj 207*38fd1498Szrj #define atomic_fetch_xor(PTR, VAL) __atomic_fetch_xor ((PTR), (VAL), \ 208*38fd1498Szrj __ATOMIC_SEQ_CST) 209*38fd1498Szrj #define atomic_fetch_xor_explicit(PTR, VAL, MO) \ 210*38fd1498Szrj __atomic_fetch_xor ((PTR), (VAL), (MO)) 211*38fd1498Szrj 212*38fd1498Szrj #define atomic_fetch_and(PTR, VAL) __atomic_fetch_and ((PTR), (VAL), \ 213*38fd1498Szrj __ATOMIC_SEQ_CST) 214*38fd1498Szrj #define atomic_fetch_and_explicit(PTR, VAL, MO) \ 215*38fd1498Szrj __atomic_fetch_and ((PTR), (VAL), (MO)) 216*38fd1498Szrj 217*38fd1498Szrj 218*38fd1498Szrj typedef _Atomic struct 219*38fd1498Szrj { 220*38fd1498Szrj #if __GCC_ATOMIC_TEST_AND_SET_TRUEVAL == 1 221*38fd1498Szrj _Bool __val; 222*38fd1498Szrj #else 223*38fd1498Szrj unsigned char __val; 224*38fd1498Szrj #endif 225*38fd1498Szrj } atomic_flag; 226*38fd1498Szrj 227*38fd1498Szrj #define ATOMIC_FLAG_INIT { 0 } 228*38fd1498Szrj 229*38fd1498Szrj 230*38fd1498Szrj extern _Bool atomic_flag_test_and_set (volatile atomic_flag *); 231*38fd1498Szrj #define atomic_flag_test_and_set(PTR) \ 232*38fd1498Szrj __atomic_test_and_set ((PTR), __ATOMIC_SEQ_CST) 233*38fd1498Szrj extern _Bool atomic_flag_test_and_set_explicit (volatile atomic_flag *, 234*38fd1498Szrj memory_order); 235*38fd1498Szrj #define atomic_flag_test_and_set_explicit(PTR, MO) \ 236*38fd1498Szrj __atomic_test_and_set ((PTR), (MO)) 237*38fd1498Szrj 238*38fd1498Szrj extern void atomic_flag_clear (volatile atomic_flag *); 239*38fd1498Szrj #define atomic_flag_clear(PTR) __atomic_clear ((PTR), __ATOMIC_SEQ_CST) 240*38fd1498Szrj extern void atomic_flag_clear_explicit (volatile atomic_flag *, memory_order); 241*38fd1498Szrj #define atomic_flag_clear_explicit(PTR, MO) __atomic_clear ((PTR), (MO)) 242*38fd1498Szrj 243*38fd1498Szrj #endif /* _STDATOMIC_H */ 244