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 16namespace 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 45template <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 61template <class T> 62struct 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 112template <> 113struct 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 195template <class T> 196struct 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 265template<> 266struct atomic<floating-point-type> { // since C++20 267 using value_type = floating-point-type; 268 using difference_type = value_type; 269 270 static constexpr bool is_always_lock_free = implementation-defined; 271 bool is_lock_free() const volatile noexcept; 272 bool is_lock_free() const noexcept; 273 274 constexpr atomic() noexcept; 275 constexpr atomic(floating-point-type) noexcept; 276 atomic(const atomic&) = delete; 277 atomic& operator=(const atomic&) = delete; 278 atomic& operator=(const atomic&) volatile = delete; 279 280 void store(floating-point-type, memory_order = memory_order::seq_cst) volatile noexcept; 281 void store(floating-point-type, memory_order = memory_order::seq_cst) noexcept; 282 floating-point-type operator=(floating-point-type) volatile noexcept; 283 floating-point-type operator=(floating-point-type) noexcept; 284 floating-point-type load(memory_order = memory_order::seq_cst) volatile noexcept; 285 floating-point-type load(memory_order = memory_order::seq_cst) noexcept; 286 operator floating-point-type() volatile noexcept; 287 operator floating-point-type() noexcept; 288 289 floating-point-type exchange(floating-point-type, 290 memory_order = memory_order::seq_cst) volatile noexcept; 291 floating-point-type exchange(floating-point-type, 292 memory_order = memory_order::seq_cst) noexcept; 293 bool compare_exchange_weak(floating-point-type&, floating-point-type, 294 memory_order, memory_order) volatile noexcept; 295 bool compare_exchange_weak(floating-point-type&, floating-point-type, 296 memory_order, memory_order) noexcept; 297 bool compare_exchange_strong(floating-point-type&, floating-point-type, 298 memory_order, memory_order) volatile noexcept; 299 bool compare_exchange_strong(floating-point-type&, floating-point-type, 300 memory_order, memory_order) noexcept; 301 bool compare_exchange_weak(floating-point-type&, floating-point-type, 302 memory_order = memory_order::seq_cst) volatile noexcept; 303 bool compare_exchange_weak(floating-point-type&, floating-point-type, 304 memory_order = memory_order::seq_cst) noexcept; 305 bool compare_exchange_strong(floating-point-type&, floating-point-type, 306 memory_order = memory_order::seq_cst) volatile noexcept; 307 bool compare_exchange_strong(floating-point-type&, floating-point-type, 308 memory_order = memory_order::seq_cst) noexcept; 309 310 floating-point-type fetch_add(floating-point-type, 311 memory_order = memory_order::seq_cst) volatile noexcept; 312 floating-point-type fetch_add(floating-point-type, 313 memory_order = memory_order::seq_cst) noexcept; 314 floating-point-type fetch_sub(floating-point-type, 315 memory_order = memory_order::seq_cst) volatile noexcept; 316 floating-point-type fetch_sub(floating-point-type, 317 memory_order = memory_order::seq_cst) noexcept; 318 319 floating-point-type operator+=(floating-point-type) volatile noexcept; 320 floating-point-type operator+=(floating-point-type) noexcept; 321 floating-point-type operator-=(floating-point-type) volatile noexcept; 322 floating-point-type operator-=(floating-point-type) noexcept; 323 324 void wait(floating-point-type, memory_order = memory_order::seq_cst) const volatile noexcept; 325 void wait(floating-point-type, memory_order = memory_order::seq_cst) const noexcept; 326 void notify_one() volatile noexcept; 327 void notify_one() noexcept; 328 void notify_all() volatile noexcept; 329 void notify_all() noexcept; 330}; 331 332// [atomics.nonmembers], non-member functions 333template<class T> 334 bool atomic_is_lock_free(const volatile atomic<T>*) noexcept; 335template<class T> 336 bool atomic_is_lock_free(const atomic<T>*) noexcept; 337template<class T> 338 void atomic_store(volatile atomic<T>*, atomic<T>::value_type) noexcept; 339template<class T> 340 void atomic_store(atomic<T>*, atomic<T>::value_type) noexcept; 341template<class T> 342 void atomic_store_explicit(volatile atomic<T>*, atomic<T>::value_type, 343 memory_order) noexcept; 344template<class T> 345 void atomic_store_explicit(atomic<T>*, atomic<T>::value_type, 346 memory_order) noexcept; 347template<class T> 348 T atomic_load(const volatile atomic<T>*) noexcept; 349template<class T> 350 T atomic_load(const atomic<T>*) noexcept; 351template<class T> 352 T atomic_load_explicit(const volatile atomic<T>*, memory_order) noexcept; 353template<class T> 354 T atomic_load_explicit(const atomic<T>*, memory_order) noexcept; 355template<class T> 356 T atomic_exchange(volatile atomic<T>*, atomic<T>::value_type) noexcept; 357template<class T> 358 T atomic_exchange(atomic<T>*, atomic<T>::value_type) noexcept; 359template<class T> 360 T atomic_exchange_explicit(volatile atomic<T>*, atomic<T>::value_type, 361 memory_order) noexcept; 362template<class T> 363 T atomic_exchange_explicit(atomic<T>*, atomic<T>::value_type, 364 memory_order) noexcept; 365template<class T> 366 bool atomic_compare_exchange_weak(volatile atomic<T>*, atomic<T>::value_type*, 367 atomic<T>::value_type) noexcept; 368template<class T> 369 bool atomic_compare_exchange_weak(atomic<T>*, atomic<T>::value_type*, 370 atomic<T>::value_type) noexcept; 371template<class T> 372 bool atomic_compare_exchange_strong(volatile atomic<T>*, atomic<T>::value_type*, 373 atomic<T>::value_type) noexcept; 374template<class T> 375 bool atomic_compare_exchange_strong(atomic<T>*, atomic<T>::value_type*, 376 atomic<T>::value_type) noexcept; 377template<class T> 378 bool atomic_compare_exchange_weak_explicit(volatile atomic<T>*, atomic<T>::value_type*, 379 atomic<T>::value_type, 380 memory_order, memory_order) noexcept; 381template<class T> 382 bool atomic_compare_exchange_weak_explicit(atomic<T>*, atomic<T>::value_type*, 383 atomic<T>::value_type, 384 memory_order, memory_order) noexcept; 385template<class T> 386 bool atomic_compare_exchange_strong_explicit(volatile atomic<T>*, atomic<T>::value_type*, 387 atomic<T>::value_type, 388 memory_order, memory_order) noexcept; 389template<class T> 390 bool atomic_compare_exchange_strong_explicit(atomic<T>*, atomic<T>::value_type*, 391 atomic<T>::value_type, 392 memory_order, memory_order) noexcept; 393 394template<class T> 395 T atomic_fetch_add(volatile atomic<T>*, atomic<T>::difference_type) noexcept; 396template<class T> 397 T atomic_fetch_add(atomic<T>*, atomic<T>::difference_type) noexcept; 398template<class T> 399 T atomic_fetch_add_explicit(volatile atomic<T>*, atomic<T>::difference_type, 400 memory_order) noexcept; 401template<class T> 402 T atomic_fetch_add_explicit(atomic<T>*, atomic<T>::difference_type, 403 memory_order) noexcept; 404template<class T> 405 T atomic_fetch_sub(volatile atomic<T>*, atomic<T>::difference_type) noexcept; 406template<class T> 407 T atomic_fetch_sub(atomic<T>*, atomic<T>::difference_type) noexcept; 408template<class T> 409 T atomic_fetch_sub_explicit(volatile atomic<T>*, atomic<T>::difference_type, 410 memory_order) noexcept; 411template<class T> 412 T atomic_fetch_sub_explicit(atomic<T>*, atomic<T>::difference_type, 413 memory_order) noexcept; 414template<class T> 415 T atomic_fetch_and(volatile atomic<T>*, atomic<T>::value_type) noexcept; 416template<class T> 417 T atomic_fetch_and(atomic<T>*, atomic<T>::value_type) noexcept; 418template<class T> 419 T atomic_fetch_and_explicit(volatile atomic<T>*, atomic<T>::value_type, 420 memory_order) noexcept; 421template<class T> 422 T atomic_fetch_and_explicit(atomic<T>*, atomic<T>::value_type, 423 memory_order) noexcept; 424template<class T> 425 T atomic_fetch_or(volatile atomic<T>*, atomic<T>::value_type) noexcept; 426template<class T> 427 T atomic_fetch_or(atomic<T>*, atomic<T>::value_type) noexcept; 428template<class T> 429 T atomic_fetch_or_explicit(volatile atomic<T>*, atomic<T>::value_type, 430 memory_order) noexcept; 431template<class T> 432 T atomic_fetch_or_explicit(atomic<T>*, atomic<T>::value_type, 433 memory_order) noexcept; 434template<class T> 435 T atomic_fetch_xor(volatile atomic<T>*, atomic<T>::value_type) noexcept; 436template<class T> 437 T atomic_fetch_xor(atomic<T>*, atomic<T>::value_type) noexcept; 438template<class T> 439 T atomic_fetch_xor_explicit(volatile atomic<T>*, atomic<T>::value_type, 440 memory_order) noexcept; 441template<class T> 442 T atomic_fetch_xor_explicit(atomic<T>*, atomic<T>::value_type, 443 memory_order) noexcept; 444 445template<class T> 446 void atomic_wait(const volatile atomic<T>*, atomic<T>::value_type) noexcept; 447template<class T> 448 void atomic_wait(const atomic<T>*, atomic<T>::value_type) noexcept; 449template<class T> 450 void atomic_wait_explicit(const volatile atomic<T>*, atomic<T>::value_type, 451 memory_order) noexcept; 452template<class T> 453 void atomic_wait_explicit(const atomic<T>*, atomic<T>::value_type, 454 memory_order) noexcept; 455template<class T> 456 void atomic_notify_one(volatile atomic<T>*) noexcept; 457template<class T> 458 void atomic_notify_one(atomic<T>*) noexcept; 459template<class T> 460 void atomic_notify_all(volatile atomic<T>*) noexcept; 461template<class T> 462 void atomic_notify_all(atomic<T>*) noexcept; 463 464// Atomics for standard typedef types 465 466typedef atomic<bool> atomic_bool; 467typedef atomic<char> atomic_char; 468typedef atomic<signed char> atomic_schar; 469typedef atomic<unsigned char> atomic_uchar; 470typedef atomic<short> atomic_short; 471typedef atomic<unsigned short> atomic_ushort; 472typedef atomic<int> atomic_int; 473typedef atomic<unsigned int> atomic_uint; 474typedef atomic<long> atomic_long; 475typedef atomic<unsigned long> atomic_ulong; 476typedef atomic<long long> atomic_llong; 477typedef atomic<unsigned long long> atomic_ullong; 478typedef atomic<char8_t> atomic_char8_t; // C++20 479typedef atomic<char16_t> atomic_char16_t; 480typedef atomic<char32_t> atomic_char32_t; 481typedef atomic<wchar_t> atomic_wchar_t; 482 483typedef atomic<int_least8_t> atomic_int_least8_t; 484typedef atomic<uint_least8_t> atomic_uint_least8_t; 485typedef atomic<int_least16_t> atomic_int_least16_t; 486typedef atomic<uint_least16_t> atomic_uint_least16_t; 487typedef atomic<int_least32_t> atomic_int_least32_t; 488typedef atomic<uint_least32_t> atomic_uint_least32_t; 489typedef atomic<int_least64_t> atomic_int_least64_t; 490typedef atomic<uint_least64_t> atomic_uint_least64_t; 491 492typedef atomic<int_fast8_t> atomic_int_fast8_t; 493typedef atomic<uint_fast8_t> atomic_uint_fast8_t; 494typedef atomic<int_fast16_t> atomic_int_fast16_t; 495typedef atomic<uint_fast16_t> atomic_uint_fast16_t; 496typedef atomic<int_fast32_t> atomic_int_fast32_t; 497typedef atomic<uint_fast32_t> atomic_uint_fast32_t; 498typedef atomic<int_fast64_t> atomic_int_fast64_t; 499typedef atomic<uint_fast64_t> atomic_uint_fast64_t; 500 501typedef atomic<int8_t> atomic_int8_t; 502typedef atomic<uint8_t> atomic_uint8_t; 503typedef atomic<int16_t> atomic_int16_t; 504typedef atomic<uint16_t> atomic_uint16_t; 505typedef atomic<int32_t> atomic_int32_t; 506typedef atomic<uint32_t> atomic_uint32_t; 507typedef atomic<int64_t> atomic_int64_t; 508typedef atomic<uint64_t> atomic_uint64_t; 509 510typedef atomic<intptr_t> atomic_intptr_t; 511typedef atomic<uintptr_t> atomic_uintptr_t; 512typedef atomic<size_t> atomic_size_t; 513typedef atomic<ptrdiff_t> atomic_ptrdiff_t; 514typedef atomic<intmax_t> atomic_intmax_t; 515typedef atomic<uintmax_t> atomic_uintmax_t; 516 517typedef see-below atomic_signed_lock_free; // since C++20 518typedef see-below atomic_unsigned_lock_free; // since C++20 519 520// flag type and operations 521 522typedef struct atomic_flag 523{ 524 atomic_flag() noexcept = default; // until C++20 525 constexpr atomic_flag() noexcept; // since C++20 526 atomic_flag(const atomic_flag&) = delete; 527 atomic_flag& operator=(const atomic_flag&) = delete; 528 atomic_flag& operator=(const atomic_flag&) volatile = delete; 529 530 bool test(memory_order m = memory_order_seq_cst) volatile noexcept; 531 bool test(memory_order m = memory_order_seq_cst) noexcept; 532 bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept; 533 bool test_and_set(memory_order m = memory_order_seq_cst) noexcept; 534 void clear(memory_order m = memory_order_seq_cst) volatile noexcept; 535 void clear(memory_order m = memory_order_seq_cst) noexcept; 536 537 void wait(bool, memory_order = memory_order::seq_cst) const volatile noexcept; 538 void wait(bool, memory_order = memory_order::seq_cst) const noexcept; 539 void notify_one() volatile noexcept; 540 void notify_one() noexcept; 541 void notify_all() volatile noexcept; 542 void notify_all() noexcept; 543} atomic_flag; 544 545bool atomic_flag_test(volatile atomic_flag* obj) noexcept; 546bool atomic_flag_test(atomic_flag* obj) noexcept; 547bool atomic_flag_test_explicit(volatile atomic_flag* obj, 548 memory_order m) noexcept; 549bool atomic_flag_test_explicit(atomic_flag* obj, memory_order m) noexcept; 550bool atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept; 551bool atomic_flag_test_and_set(atomic_flag* obj) noexcept; 552bool atomic_flag_test_and_set_explicit(volatile atomic_flag* obj, 553 memory_order m) noexcept; 554bool atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept; 555void atomic_flag_clear(volatile atomic_flag* obj) noexcept; 556void atomic_flag_clear(atomic_flag* obj) noexcept; 557void atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept; 558void atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept; 559 560void atomic_wait(const volatile atomic_flag* obj, T old) noexcept; 561void atomic_wait(const atomic_flag* obj, T old) noexcept; 562void atomic_wait_explicit(const volatile atomic_flag* obj, T old, memory_order m) noexcept; 563void atomic_wait_explicit(const atomic_flag* obj, T old, memory_order m) noexcept; 564void atomic_one(volatile atomic_flag* obj) noexcept; 565void atomic_one(atomic_flag* obj) noexcept; 566void atomic_all(volatile atomic_flag* obj) noexcept; 567void atomic_all(atomic_flag* obj) noexcept; 568 569// fences 570 571void atomic_thread_fence(memory_order m) noexcept; 572void atomic_signal_fence(memory_order m) noexcept; 573 574// deprecated 575 576template <class T> 577 void atomic_init(volatile atomic<T>* obj, atomic<T>::value_type desr) noexcept; 578 579template <class T> 580 void atomic_init(atomic<T>* obj, atomic<T>::value_type desr) noexcept; 581 582#define ATOMIC_VAR_INIT(value) see below 583 584#define ATOMIC_FLAG_INIT see below 585 586} // std 587 588*/ 589 590#include <__assert> // all public C++ headers provide the assertion handler 591#include <__atomic/aliases.h> 592#include <__atomic/atomic.h> 593#include <__atomic/atomic_base.h> 594#include <__atomic/atomic_flag.h> 595#include <__atomic/atomic_init.h> 596#include <__atomic/atomic_lock_free.h> 597#include <__atomic/atomic_sync.h> 598#include <__atomic/check_memory_order.h> 599#include <__atomic/contention_t.h> 600#include <__atomic/cxx_atomic_impl.h> 601#include <__atomic/fence.h> 602#include <__atomic/is_always_lock_free.h> 603#include <__atomic/kill_dependency.h> 604#include <__atomic/memory_order.h> 605#include <__config> 606#include <version> 607 608#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 609# pragma GCC system_header 610#endif 611 612#ifdef _LIBCPP_HAS_NO_ATOMIC_HEADER 613# error <atomic> is not implemented 614#endif 615 616#ifdef kill_dependency 617# error <atomic> is incompatible with <stdatomic.h> before C++23. Please compile with -std=c++23. 618#endif 619 620#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 621# include <cmath> 622# include <compare> 623# include <cstring> 624# include <type_traits> 625#endif 626 627#endif // _LIBCPP_ATOMIC 628