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