xref: /minix3/external/bsd/llvm/dist/clang/lib/Headers/stdatomic.h (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
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