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