]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/libcxx/include/atomic
Merge llvm-project main llvmorg-17-init-19304-gd0b54bb50e51
[FreeBSD/FreeBSD.git] / contrib / llvm-project / libcxx / include / atomic
1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9
10 #ifndef _LIBCPP_ATOMIC
11 #define _LIBCPP_ATOMIC
12
13 /*
14     atomic synopsis
15
16 namespace std
17 {
18
19 // feature test macro [version.syn]
20
21 #define __cpp_lib_atomic_is_always_lock_free
22 #define __cpp_lib_atomic_flag_test
23 #define __cpp_lib_atomic_lock_free_type_aliases
24 #define __cpp_lib_atomic_wait
25
26  // order and consistency
27
28  enum memory_order: unspecified // enum class in C++20
29  {
30     relaxed,
31     consume, // load-consume
32     acquire, // load-acquire
33     release, // store-release
34     acq_rel, // store-release load-acquire
35     seq_cst // store-release load-acquire
36  };
37
38  inline constexpr auto memory_order_relaxed = memory_order::relaxed;
39  inline constexpr auto memory_order_consume = memory_order::consume;
40  inline constexpr auto memory_order_acquire = memory_order::acquire;
41  inline constexpr auto memory_order_release = memory_order::release;
42  inline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
43  inline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
44
45 template <class T> T kill_dependency(T y) noexcept;
46
47 // lock-free property
48
49 #define ATOMIC_BOOL_LOCK_FREE unspecified
50 #define ATOMIC_CHAR_LOCK_FREE unspecified
51 #define ATOMIC_CHAR8_T_LOCK_FREE unspecified // C++20
52 #define ATOMIC_CHAR16_T_LOCK_FREE unspecified
53 #define ATOMIC_CHAR32_T_LOCK_FREE unspecified
54 #define ATOMIC_WCHAR_T_LOCK_FREE unspecified
55 #define ATOMIC_SHORT_LOCK_FREE unspecified
56 #define ATOMIC_INT_LOCK_FREE unspecified
57 #define ATOMIC_LONG_LOCK_FREE unspecified
58 #define ATOMIC_LLONG_LOCK_FREE unspecified
59 #define ATOMIC_POINTER_LOCK_FREE unspecified
60
61 template <class T>
62 struct atomic
63 {
64     using value_type = T;
65
66     static constexpr bool is_always_lock_free;
67     bool is_lock_free() const volatile noexcept;
68     bool is_lock_free() const noexcept;
69
70     atomic() noexcept = default; // until C++20
71     constexpr atomic() noexcept(is_nothrow_default_constructible_v<T>); // since C++20
72     constexpr atomic(T desr) noexcept;
73     atomic(const atomic&) = delete;
74     atomic& operator=(const atomic&) = delete;
75     atomic& operator=(const atomic&) volatile = delete;
76
77     T load(memory_order m = memory_order_seq_cst) const volatile noexcept;
78     T load(memory_order m = memory_order_seq_cst) const noexcept;
79     operator T() const volatile noexcept;
80     operator T() const noexcept;
81     void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
82     void store(T desr, memory_order m = memory_order_seq_cst) noexcept;
83     T operator=(T) volatile noexcept;
84     T operator=(T) noexcept;
85
86     T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
87     T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept;
88     bool compare_exchange_weak(T& expc, T desr,
89                                memory_order s, memory_order f) volatile noexcept;
90     bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept;
91     bool compare_exchange_strong(T& expc, T desr,
92                                  memory_order s, memory_order f) volatile noexcept;
93     bool compare_exchange_strong(T& expc, T desr,
94                                  memory_order s, memory_order f) noexcept;
95     bool compare_exchange_weak(T& expc, T desr,
96                                memory_order m = memory_order_seq_cst) volatile noexcept;
97     bool compare_exchange_weak(T& expc, T desr,
98                                memory_order m = memory_order_seq_cst) noexcept;
99     bool compare_exchange_strong(T& expc, T desr,
100                                 memory_order m = memory_order_seq_cst) volatile noexcept;
101     bool compare_exchange_strong(T& expc, T desr,
102                                  memory_order m = memory_order_seq_cst) noexcept;
103
104     void wait(T, memory_order = memory_order::seq_cst) const volatile noexcept;
105     void wait(T, memory_order = memory_order::seq_cst) const noexcept;
106     void notify_one() volatile noexcept;
107     void notify_one() noexcept;
108     void notify_all() volatile noexcept;
109     void notify_all() noexcept;
110 };
111
112 template <>
113 struct atomic<integral>
114 {
115     using value_type = integral;
116     using difference_type = value_type;
117
118     static constexpr bool is_always_lock_free;
119     bool is_lock_free() const volatile noexcept;
120     bool is_lock_free() const noexcept;
121
122     atomic() noexcept = default;
123     constexpr atomic(integral desr) noexcept;
124     atomic(const atomic&) = delete;
125     atomic& operator=(const atomic&) = delete;
126     atomic& operator=(const atomic&) volatile = delete;
127
128     integral load(memory_order m = memory_order_seq_cst) const volatile noexcept;
129     integral load(memory_order m = memory_order_seq_cst) const noexcept;
130     operator integral() const volatile noexcept;
131     operator integral() const noexcept;
132     void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept;
133     void store(integral desr, memory_order m = memory_order_seq_cst) noexcept;
134     integral operator=(integral desr) volatile noexcept;
135     integral operator=(integral desr) noexcept;
136
137     integral exchange(integral desr,
138                       memory_order m = memory_order_seq_cst) volatile noexcept;
139     integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept;
140     bool compare_exchange_weak(integral& expc, integral desr,
141                                memory_order s, memory_order f) volatile noexcept;
142     bool compare_exchange_weak(integral& expc, integral desr,
143                                memory_order s, memory_order f) noexcept;
144     bool compare_exchange_strong(integral& expc, integral desr,
145                                  memory_order s, memory_order f) volatile noexcept;
146     bool compare_exchange_strong(integral& expc, integral desr,
147                                  memory_order s, memory_order f) noexcept;
148     bool compare_exchange_weak(integral& expc, integral desr,
149                                memory_order m = memory_order_seq_cst) volatile noexcept;
150     bool compare_exchange_weak(integral& expc, integral desr,
151                                memory_order m = memory_order_seq_cst) noexcept;
152     bool compare_exchange_strong(integral& expc, integral desr,
153                                 memory_order m = memory_order_seq_cst) volatile noexcept;
154     bool compare_exchange_strong(integral& expc, integral desr,
155                                  memory_order m = memory_order_seq_cst) noexcept;
156
157     integral fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
158     integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept;
159     integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
160     integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept;
161     integral fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
162     integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept;
163     integral fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
164     integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept;
165     integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
166     integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept;
167
168     integral operator++(int) volatile noexcept;
169     integral operator++(int) noexcept;
170     integral operator--(int) volatile noexcept;
171     integral operator--(int) noexcept;
172     integral operator++() volatile noexcept;
173     integral operator++() noexcept;
174     integral operator--() volatile noexcept;
175     integral operator--() noexcept;
176     integral operator+=(integral op) volatile noexcept;
177     integral operator+=(integral op) noexcept;
178     integral operator-=(integral op) volatile noexcept;
179     integral operator-=(integral op) noexcept;
180     integral operator&=(integral op) volatile noexcept;
181     integral operator&=(integral op) noexcept;
182     integral operator|=(integral op) volatile noexcept;
183     integral operator|=(integral op) noexcept;
184     integral operator^=(integral op) volatile noexcept;
185     integral operator^=(integral op) noexcept;
186
187     void wait(integral, memory_order = memory_order::seq_cst) const volatile noexcept;
188     void wait(integral, memory_order = memory_order::seq_cst) const noexcept;
189     void notify_one() volatile noexcept;
190     void notify_one() noexcept;
191     void notify_all() volatile noexcept;
192     void notify_all() noexcept;
193 };
194
195 template <class T>
196 struct atomic<T*>
197 {
198     using value_type = T*;
199     using difference_type = ptrdiff_t;
200
201     static constexpr bool is_always_lock_free;
202     bool is_lock_free() const volatile noexcept;
203     bool is_lock_free() const noexcept;
204
205     atomic() noexcept = default; // until C++20
206     constexpr atomic() noexcept; // since C++20
207     constexpr atomic(T* desr) noexcept;
208     atomic(const atomic&) = delete;
209     atomic& operator=(const atomic&) = delete;
210     atomic& operator=(const atomic&) volatile = delete;
211
212     T* load(memory_order m = memory_order_seq_cst) const volatile noexcept;
213     T* load(memory_order m = memory_order_seq_cst) const noexcept;
214     operator T*() const volatile noexcept;
215     operator T*() const noexcept;
216     void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
217     void store(T* desr, memory_order m = memory_order_seq_cst) noexcept;
218     T* operator=(T*) volatile noexcept;
219     T* operator=(T*) noexcept;
220
221     T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
222     T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept;
223     bool compare_exchange_weak(T*& expc, T* desr,
224                                memory_order s, memory_order f) volatile noexcept;
225     bool compare_exchange_weak(T*& expc, T* desr,
226                                memory_order s, memory_order f) noexcept;
227     bool compare_exchange_strong(T*& expc, T* desr,
228                                  memory_order s, memory_order f) volatile noexcept;
229     bool compare_exchange_strong(T*& expc, T* desr,
230                                  memory_order s, memory_order f) noexcept;
231     bool compare_exchange_weak(T*& expc, T* desr,
232                                memory_order m = memory_order_seq_cst) volatile noexcept;
233     bool compare_exchange_weak(T*& expc, T* desr,
234                                memory_order m = memory_order_seq_cst) noexcept;
235     bool compare_exchange_strong(T*& expc, T* desr,
236                                 memory_order m = memory_order_seq_cst) volatile noexcept;
237     bool compare_exchange_strong(T*& expc, T* desr,
238                                  memory_order m = memory_order_seq_cst) noexcept;
239     T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
240     T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
241     T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
242     T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
243
244     T* operator++(int) volatile noexcept;
245     T* operator++(int) noexcept;
246     T* operator--(int) volatile noexcept;
247     T* operator--(int) noexcept;
248     T* operator++() volatile noexcept;
249     T* operator++() noexcept;
250     T* operator--() volatile noexcept;
251     T* operator--() noexcept;
252     T* operator+=(ptrdiff_t op) volatile noexcept;
253     T* operator+=(ptrdiff_t op) noexcept;
254     T* operator-=(ptrdiff_t op) volatile noexcept;
255     T* operator-=(ptrdiff_t op) noexcept;
256
257     void wait(T*, memory_order = memory_order::seq_cst) const volatile noexcept;
258     void wait(T*, memory_order = memory_order::seq_cst) const noexcept;
259     void notify_one() volatile noexcept;
260     void notify_one() noexcept;
261     void notify_all() volatile noexcept;
262     void notify_all() noexcept;
263 };
264
265
266 // [atomics.nonmembers], non-member functions
267 template<class T>
268   bool atomic_is_lock_free(const volatile atomic<T>*) noexcept;
269 template<class T>
270   bool atomic_is_lock_free(const atomic<T>*) noexcept;
271 template<class T>
272   void atomic_store(volatile atomic<T>*, atomic<T>::value_type) noexcept;
273 template<class T>
274   void atomic_store(atomic<T>*, atomic<T>::value_type) noexcept;
275 template<class T>
276   void atomic_store_explicit(volatile atomic<T>*, atomic<T>::value_type,
277                              memory_order) noexcept;
278 template<class T>
279   void atomic_store_explicit(atomic<T>*, atomic<T>::value_type,
280                              memory_order) noexcept;
281 template<class T>
282   T atomic_load(const volatile atomic<T>*) noexcept;
283 template<class T>
284   T atomic_load(const atomic<T>*) noexcept;
285 template<class T>
286   T atomic_load_explicit(const volatile atomic<T>*, memory_order) noexcept;
287 template<class T>
288   T atomic_load_explicit(const atomic<T>*, memory_order) noexcept;
289 template<class T>
290   T atomic_exchange(volatile atomic<T>*, atomic<T>::value_type) noexcept;
291 template<class T>
292   T atomic_exchange(atomic<T>*, atomic<T>::value_type) noexcept;
293 template<class T>
294   T atomic_exchange_explicit(volatile atomic<T>*, atomic<T>::value_type,
295                              memory_order) noexcept;
296 template<class T>
297   T atomic_exchange_explicit(atomic<T>*, atomic<T>::value_type,
298                              memory_order) noexcept;
299 template<class T>
300   bool atomic_compare_exchange_weak(volatile atomic<T>*, atomic<T>::value_type*,
301                                     atomic<T>::value_type) noexcept;
302 template<class T>
303   bool atomic_compare_exchange_weak(atomic<T>*, atomic<T>::value_type*,
304                                     atomic<T>::value_type) noexcept;
305 template<class T>
306   bool atomic_compare_exchange_strong(volatile atomic<T>*, atomic<T>::value_type*,
307                                       atomic<T>::value_type) noexcept;
308 template<class T>
309   bool atomic_compare_exchange_strong(atomic<T>*, atomic<T>::value_type*,
310                                       atomic<T>::value_type) noexcept;
311 template<class T>
312   bool atomic_compare_exchange_weak_explicit(volatile atomic<T>*, atomic<T>::value_type*,
313                                              atomic<T>::value_type,
314                                              memory_order, memory_order) noexcept;
315 template<class T>
316   bool atomic_compare_exchange_weak_explicit(atomic<T>*, atomic<T>::value_type*,
317                                              atomic<T>::value_type,
318                                              memory_order, memory_order) noexcept;
319 template<class T>
320   bool atomic_compare_exchange_strong_explicit(volatile atomic<T>*, atomic<T>::value_type*,
321                                                atomic<T>::value_type,
322                                                memory_order, memory_order) noexcept;
323 template<class T>
324   bool atomic_compare_exchange_strong_explicit(atomic<T>*, atomic<T>::value_type*,
325                                                atomic<T>::value_type,
326                                                memory_order, memory_order) noexcept;
327
328 template<class T>
329   T atomic_fetch_add(volatile atomic<T>*, atomic<T>::difference_type) noexcept;
330 template<class T>
331   T atomic_fetch_add(atomic<T>*, atomic<T>::difference_type) noexcept;
332 template<class T>
333   T atomic_fetch_add_explicit(volatile atomic<T>*, atomic<T>::difference_type,
334                               memory_order) noexcept;
335 template<class T>
336   T atomic_fetch_add_explicit(atomic<T>*, atomic<T>::difference_type,
337                               memory_order) noexcept;
338 template<class T>
339   T atomic_fetch_sub(volatile atomic<T>*, atomic<T>::difference_type) noexcept;
340 template<class T>
341   T atomic_fetch_sub(atomic<T>*, atomic<T>::difference_type) noexcept;
342 template<class T>
343   T atomic_fetch_sub_explicit(volatile atomic<T>*, atomic<T>::difference_type,
344                               memory_order) noexcept;
345 template<class T>
346   T atomic_fetch_sub_explicit(atomic<T>*, atomic<T>::difference_type,
347                               memory_order) noexcept;
348 template<class T>
349   T atomic_fetch_and(volatile atomic<T>*, atomic<T>::value_type) noexcept;
350 template<class T>
351   T atomic_fetch_and(atomic<T>*, atomic<T>::value_type) noexcept;
352 template<class T>
353   T atomic_fetch_and_explicit(volatile atomic<T>*, atomic<T>::value_type,
354                               memory_order) noexcept;
355 template<class T>
356   T atomic_fetch_and_explicit(atomic<T>*, atomic<T>::value_type,
357                               memory_order) noexcept;
358 template<class T>
359   T atomic_fetch_or(volatile atomic<T>*, atomic<T>::value_type) noexcept;
360 template<class T>
361   T atomic_fetch_or(atomic<T>*, atomic<T>::value_type) noexcept;
362 template<class T>
363   T atomic_fetch_or_explicit(volatile atomic<T>*, atomic<T>::value_type,
364                              memory_order) noexcept;
365 template<class T>
366   T atomic_fetch_or_explicit(atomic<T>*, atomic<T>::value_type,
367                              memory_order) noexcept;
368 template<class T>
369   T atomic_fetch_xor(volatile atomic<T>*, atomic<T>::value_type) noexcept;
370 template<class T>
371   T atomic_fetch_xor(atomic<T>*, atomic<T>::value_type) noexcept;
372 template<class T>
373   T atomic_fetch_xor_explicit(volatile atomic<T>*, atomic<T>::value_type,
374                               memory_order) noexcept;
375 template<class T>
376   T atomic_fetch_xor_explicit(atomic<T>*, atomic<T>::value_type,
377                               memory_order) noexcept;
378
379 template<class T>
380   void atomic_wait(const volatile atomic<T>*, atomic<T>::value_type) noexcept;
381 template<class T>
382   void atomic_wait(const atomic<T>*, atomic<T>::value_type) noexcept;
383 template<class T>
384   void atomic_wait_explicit(const volatile atomic<T>*, atomic<T>::value_type,
385                             memory_order) noexcept;
386 template<class T>
387   void atomic_wait_explicit(const atomic<T>*, atomic<T>::value_type,
388                             memory_order) noexcept;
389 template<class T>
390   void atomic_notify_one(volatile atomic<T>*) noexcept;
391 template<class T>
392   void atomic_notify_one(atomic<T>*) noexcept;
393 template<class T>
394   void atomic_notify_all(volatile atomic<T>*) noexcept;
395 template<class T>
396   void atomic_notify_all(atomic<T>*) noexcept;
397
398 // Atomics for standard typedef types
399
400 typedef atomic<bool>               atomic_bool;
401 typedef atomic<char>               atomic_char;
402 typedef atomic<signed char>        atomic_schar;
403 typedef atomic<unsigned char>      atomic_uchar;
404 typedef atomic<short>              atomic_short;
405 typedef atomic<unsigned short>     atomic_ushort;
406 typedef atomic<int>                atomic_int;
407 typedef atomic<unsigned int>       atomic_uint;
408 typedef atomic<long>               atomic_long;
409 typedef atomic<unsigned long>      atomic_ulong;
410 typedef atomic<long long>          atomic_llong;
411 typedef atomic<unsigned long long> atomic_ullong;
412 typedef atomic<char8_t>            atomic_char8_t; // C++20
413 typedef atomic<char16_t>           atomic_char16_t;
414 typedef atomic<char32_t>           atomic_char32_t;
415 typedef atomic<wchar_t>            atomic_wchar_t;
416
417 typedef atomic<int_least8_t>   atomic_int_least8_t;
418 typedef atomic<uint_least8_t>  atomic_uint_least8_t;
419 typedef atomic<int_least16_t>  atomic_int_least16_t;
420 typedef atomic<uint_least16_t> atomic_uint_least16_t;
421 typedef atomic<int_least32_t>  atomic_int_least32_t;
422 typedef atomic<uint_least32_t> atomic_uint_least32_t;
423 typedef atomic<int_least64_t>  atomic_int_least64_t;
424 typedef atomic<uint_least64_t> atomic_uint_least64_t;
425
426 typedef atomic<int_fast8_t>   atomic_int_fast8_t;
427 typedef atomic<uint_fast8_t>  atomic_uint_fast8_t;
428 typedef atomic<int_fast16_t>  atomic_int_fast16_t;
429 typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
430 typedef atomic<int_fast32_t>  atomic_int_fast32_t;
431 typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
432 typedef atomic<int_fast64_t>  atomic_int_fast64_t;
433 typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
434
435 typedef atomic<int8_t>   atomic_int8_t;
436 typedef atomic<uint8_t>  atomic_uint8_t;
437 typedef atomic<int16_t>  atomic_int16_t;
438 typedef atomic<uint16_t> atomic_uint16_t;
439 typedef atomic<int32_t>  atomic_int32_t;
440 typedef atomic<uint32_t> atomic_uint32_t;
441 typedef atomic<int64_t>  atomic_int64_t;
442 typedef atomic<uint64_t> atomic_uint64_t;
443
444 typedef atomic<intptr_t>  atomic_intptr_t;
445 typedef atomic<uintptr_t> atomic_uintptr_t;
446 typedef atomic<size_t>    atomic_size_t;
447 typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
448 typedef atomic<intmax_t>  atomic_intmax_t;
449 typedef atomic<uintmax_t> atomic_uintmax_t;
450
451 // flag type and operations
452
453 typedef struct atomic_flag
454 {
455     atomic_flag() noexcept = default; // until C++20
456     constexpr atomic_flag() noexcept; // since C++20
457     atomic_flag(const atomic_flag&) = delete;
458     atomic_flag& operator=(const atomic_flag&) = delete;
459     atomic_flag& operator=(const atomic_flag&) volatile = delete;
460
461     bool test(memory_order m = memory_order_seq_cst) volatile noexcept;
462     bool test(memory_order m = memory_order_seq_cst) noexcept;
463     bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept;
464     bool test_and_set(memory_order m = memory_order_seq_cst) noexcept;
465     void clear(memory_order m = memory_order_seq_cst) volatile noexcept;
466     void clear(memory_order m = memory_order_seq_cst) noexcept;
467
468     void wait(bool, memory_order = memory_order::seq_cst) const volatile noexcept;
469     void wait(bool, memory_order = memory_order::seq_cst) const noexcept;
470     void notify_one() volatile noexcept;
471     void notify_one() noexcept;
472     void notify_all() volatile noexcept;
473     void notify_all() noexcept;
474 } atomic_flag;
475
476 bool atomic_flag_test(volatile atomic_flag* obj) noexcept;
477 bool atomic_flag_test(atomic_flag* obj) noexcept;
478 bool atomic_flag_test_explicit(volatile atomic_flag* obj,
479                                memory_order m) noexcept;
480 bool atomic_flag_test_explicit(atomic_flag* obj, memory_order m) noexcept;
481 bool atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept;
482 bool atomic_flag_test_and_set(atomic_flag* obj) noexcept;
483 bool atomic_flag_test_and_set_explicit(volatile atomic_flag* obj,
484                                        memory_order m) noexcept;
485 bool atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept;
486 void atomic_flag_clear(volatile atomic_flag* obj) noexcept;
487 void atomic_flag_clear(atomic_flag* obj) noexcept;
488 void atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept;
489 void atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept;
490
491 void atomic_wait(const volatile atomic_flag* obj, T old) noexcept;
492 void atomic_wait(const atomic_flag* obj, T old) noexcept;
493 void atomic_wait_explicit(const volatile atomic_flag* obj, T old, memory_order m) noexcept;
494 void atomic_wait_explicit(const atomic_flag* obj, T old, memory_order m) noexcept;
495 void atomic_one(volatile atomic_flag* obj) noexcept;
496 void atomic_one(atomic_flag* obj) noexcept;
497 void atomic_all(volatile atomic_flag* obj) noexcept;
498 void atomic_all(atomic_flag* obj) noexcept;
499
500 // fences
501
502 void atomic_thread_fence(memory_order m) noexcept;
503 void atomic_signal_fence(memory_order m) noexcept;
504
505 // deprecated
506
507 template <class T>
508   void atomic_init(volatile atomic<T>* obj, atomic<T>::value_type desr) noexcept;
509
510 template <class T>
511   void atomic_init(atomic<T>* obj, atomic<T>::value_type desr) noexcept;
512
513 #define ATOMIC_VAR_INIT(value) see below
514
515 #define ATOMIC_FLAG_INIT see below
516
517 }  // std
518
519 */
520
521 #include <__assert> // all public C++ headers provide the assertion handler
522 #include <__atomic/aliases.h>
523 #include <__atomic/atomic.h>
524 #include <__atomic/atomic_base.h>
525 #include <__atomic/atomic_flag.h>
526 #include <__atomic/atomic_init.h>
527 #include <__atomic/atomic_lock_free.h>
528 #include <__atomic/atomic_sync.h>
529 #include <__atomic/check_memory_order.h>
530 #include <__atomic/contention_t.h>
531 #include <__atomic/cxx_atomic_impl.h>
532 #include <__atomic/fence.h>
533 #include <__atomic/is_always_lock_free.h>
534 #include <__atomic/kill_dependency.h>
535 #include <__atomic/memory_order.h>
536 #include <__config>
537 #include <version>
538
539 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
540 #  pragma GCC system_header
541 #endif
542
543 #ifdef _LIBCPP_HAS_NO_ATOMIC_HEADER
544 #  error <atomic> is not implemented
545 #endif
546
547 #ifdef kill_dependency
548 #  error <atomic> is incompatible with <stdatomic.h> before C++23. Please compile with -std=c++23.
549 #endif
550
551 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
552 #  include <cmath>
553 #  include <compare>
554 #  include <cstring>
555 #  include <type_traits>
556 #endif
557
558 #endif // _LIBCPP_ATOMIC