xref: /dflybsd-src/contrib/gcc-8.0/gcc/ginclude/stdatomic.h (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
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