1 // -*- C++ -*- 2 //===--------------------------- atomic -----------------------------------===// 3 // 4 // The LLVM Compiler Infrastructure 5 // 6 // This file is distributed under the University of Illinois Open Source 7 // License. See LICENSE.TXT for details. 8 // 9 //===----------------------------------------------------------------------===// 10 11 #ifndef _LIBCPP_ATOMIC 12 #define _LIBCPP_ATOMIC 13 14 /* 15 atomic synopsis 16 17 namespace std 18 { 19 20 // order and consistency 21 22 typedef enum memory_order 23 { 24 memory_order_relaxed, 25 memory_order_consume, // load-consume 26 memory_order_acquire, // load-acquire 27 memory_order_release, // store-release 28 memory_order_acq_rel, // store-release load-acquire 29 memory_order_seq_cst // store-release load-acquire 30 } memory_order; 31 32 template <class T> T kill_dependency(T y) noexcept; 33 34 // lock-free property 35 36 #define ATOMIC_CHAR_LOCK_FREE unspecified 37 #define ATOMIC_CHAR16_T_LOCK_FREE unspecified 38 #define ATOMIC_CHAR32_T_LOCK_FREE unspecified 39 #define ATOMIC_WCHAR_T_LOCK_FREE unspecified 40 #define ATOMIC_SHORT_LOCK_FREE unspecified 41 #define ATOMIC_INT_LOCK_FREE unspecified 42 #define ATOMIC_LONG_LOCK_FREE unspecified 43 #define ATOMIC_LLONG_LOCK_FREE unspecified 44 45 // flag type and operations 46 47 typedef struct atomic_flag 48 { 49 bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept; 50 bool test_and_set(memory_order m = memory_order_seq_cst) noexcept; 51 void clear(memory_order m = memory_order_seq_cst) volatile noexcept; 52 void clear(memory_order m = memory_order_seq_cst) noexcept; 53 atomic_flag() noexcept = default; 54 atomic_flag(const atomic_flag&) = delete; 55 atomic_flag& operator=(const atomic_flag&) = delete; 56 atomic_flag& operator=(const atomic_flag&) volatile = delete; 57 } atomic_flag; 58 59 bool 60 atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept; 61 62 bool 63 atomic_flag_test_and_set(atomic_flag* obj) noexcept; 64 65 bool 66 atomic_flag_test_and_set_explicit(volatile atomic_flag* obj, 67 memory_order m) noexcept; 68 69 bool 70 atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept; 71 72 void 73 atomic_flag_clear(volatile atomic_flag* obj) noexcept; 74 75 void 76 atomic_flag_clear(atomic_flag* obj) noexcept; 77 78 void 79 atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept; 80 81 void 82 atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept; 83 84 #define ATOMIC_FLAG_INIT see below 85 #define ATOMIC_VAR_INIT(value) see below 86 87 template <class T> 88 struct atomic 89 { 90 bool is_lock_free() const volatile noexcept; 91 bool is_lock_free() const noexcept; 92 void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept; 93 void store(T desr, memory_order m = memory_order_seq_cst) noexcept; 94 T load(memory_order m = memory_order_seq_cst) const volatile noexcept; 95 T load(memory_order m = memory_order_seq_cst) const noexcept; 96 operator T() const volatile noexcept; 97 operator T() const noexcept; 98 T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept; 99 T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept; 100 bool compare_exchange_weak(T& expc, T desr, 101 memory_order s, memory_order f) volatile noexcept; 102 bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept; 103 bool compare_exchange_strong(T& expc, T desr, 104 memory_order s, memory_order f) volatile noexcept; 105 bool compare_exchange_strong(T& expc, T desr, 106 memory_order s, memory_order f) noexcept; 107 bool compare_exchange_weak(T& expc, T desr, 108 memory_order m = memory_order_seq_cst) volatile noexcept; 109 bool compare_exchange_weak(T& expc, T desr, 110 memory_order m = memory_order_seq_cst) noexcept; 111 bool compare_exchange_strong(T& expc, T desr, 112 memory_order m = memory_order_seq_cst) volatile noexcept; 113 bool compare_exchange_strong(T& expc, T desr, 114 memory_order m = memory_order_seq_cst) noexcept; 115 116 atomic() noexcept = default; 117 constexpr atomic(T desr) noexcept; 118 atomic(const atomic&) = delete; 119 atomic& operator=(const atomic&) = delete; 120 atomic& operator=(const atomic&) volatile = delete; 121 T operator=(T) volatile noexcept; 122 T operator=(T) noexcept; 123 }; 124 125 template <> 126 struct atomic<integral> 127 { 128 bool is_lock_free() const volatile noexcept; 129 bool is_lock_free() const noexcept; 130 void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept; 131 void store(integral desr, memory_order m = memory_order_seq_cst) noexcept; 132 integral load(memory_order m = memory_order_seq_cst) const volatile noexcept; 133 integral load(memory_order m = memory_order_seq_cst) const noexcept; 134 operator integral() const volatile noexcept; 135 operator integral() const noexcept; 136 integral exchange(integral desr, 137 memory_order m = memory_order_seq_cst) volatile noexcept; 138 integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept; 139 bool compare_exchange_weak(integral& expc, integral desr, 140 memory_order s, memory_order f) volatile noexcept; 141 bool compare_exchange_weak(integral& expc, integral desr, 142 memory_order s, memory_order f) noexcept; 143 bool compare_exchange_strong(integral& expc, integral desr, 144 memory_order s, memory_order f) volatile noexcept; 145 bool compare_exchange_strong(integral& expc, integral desr, 146 memory_order s, memory_order f) noexcept; 147 bool compare_exchange_weak(integral& expc, integral desr, 148 memory_order m = memory_order_seq_cst) volatile noexcept; 149 bool compare_exchange_weak(integral& expc, integral desr, 150 memory_order m = memory_order_seq_cst) noexcept; 151 bool compare_exchange_strong(integral& expc, integral desr, 152 memory_order m = memory_order_seq_cst) volatile noexcept; 153 bool compare_exchange_strong(integral& expc, integral desr, 154 memory_order m = memory_order_seq_cst) noexcept; 155 156 integral 157 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 160 fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 161 integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept; 162 integral 163 fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 164 integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept; 165 integral 166 fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 167 integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept; 168 integral 169 fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 170 integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept; 171 172 atomic() noexcept = default; 173 constexpr atomic(integral desr) noexcept; 174 atomic(const atomic&) = delete; 175 atomic& operator=(const atomic&) = delete; 176 atomic& operator=(const atomic&) volatile = delete; 177 integral operator=(integral desr) volatile noexcept; 178 integral operator=(integral desr) noexcept; 179 180 integral operator++(int) volatile noexcept; 181 integral operator++(int) noexcept; 182 integral operator--(int) volatile noexcept; 183 integral operator--(int) noexcept; 184 integral operator++() volatile noexcept; 185 integral operator++() noexcept; 186 integral operator--() volatile noexcept; 187 integral operator--() noexcept; 188 integral operator+=(integral op) volatile noexcept; 189 integral operator+=(integral op) noexcept; 190 integral operator-=(integral op) volatile noexcept; 191 integral operator-=(integral op) noexcept; 192 integral operator&=(integral op) volatile noexcept; 193 integral operator&=(integral op) noexcept; 194 integral operator|=(integral op) volatile noexcept; 195 integral operator|=(integral op) noexcept; 196 integral operator^=(integral op) volatile noexcept; 197 integral operator^=(integral op) noexcept; 198 }; 199 200 template <class T> 201 struct atomic<T*> 202 { 203 bool is_lock_free() const volatile noexcept; 204 bool is_lock_free() const noexcept; 205 void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept; 206 void store(T* desr, memory_order m = memory_order_seq_cst) noexcept; 207 T* load(memory_order m = memory_order_seq_cst) const volatile noexcept; 208 T* load(memory_order m = memory_order_seq_cst) const noexcept; 209 operator T*() const volatile noexcept; 210 operator T*() const noexcept; 211 T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept; 212 T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept; 213 bool compare_exchange_weak(T*& expc, T* desr, 214 memory_order s, memory_order f) volatile noexcept; 215 bool compare_exchange_weak(T*& expc, T* desr, 216 memory_order s, memory_order f) noexcept; 217 bool compare_exchange_strong(T*& expc, T* desr, 218 memory_order s, memory_order f) volatile noexcept; 219 bool compare_exchange_strong(T*& expc, T* desr, 220 memory_order s, memory_order f) noexcept; 221 bool compare_exchange_weak(T*& expc, T* desr, 222 memory_order m = memory_order_seq_cst) volatile noexcept; 223 bool compare_exchange_weak(T*& expc, T* desr, 224 memory_order m = memory_order_seq_cst) noexcept; 225 bool compare_exchange_strong(T*& expc, T* desr, 226 memory_order m = memory_order_seq_cst) volatile noexcept; 227 bool compare_exchange_strong(T*& expc, T* desr, 228 memory_order m = memory_order_seq_cst) noexcept; 229 T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept; 230 T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept; 231 T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept; 232 T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept; 233 234 atomic() noexcept = default; 235 constexpr atomic(T* desr) noexcept; 236 atomic(const atomic&) = delete; 237 atomic& operator=(const atomic&) = delete; 238 atomic& operator=(const atomic&) volatile = delete; 239 240 T* operator=(T*) volatile noexcept; 241 T* operator=(T*) noexcept; 242 T* operator++(int) volatile noexcept; 243 T* operator++(int) noexcept; 244 T* operator--(int) volatile noexcept; 245 T* operator--(int) noexcept; 246 T* operator++() volatile noexcept; 247 T* operator++() noexcept; 248 T* operator--() volatile noexcept; 249 T* operator--() noexcept; 250 T* operator+=(ptrdiff_t op) volatile noexcept; 251 T* operator+=(ptrdiff_t op) noexcept; 252 T* operator-=(ptrdiff_t op) volatile noexcept; 253 T* operator-=(ptrdiff_t op) noexcept; 254 }; 255 256 257 template <class T> 258 bool 259 atomic_is_lock_free(const volatile atomic<T>* obj) noexcept; 260 261 template <class T> 262 bool 263 atomic_is_lock_free(const atomic<T>* obj) noexcept; 264 265 template <class T> 266 void 267 atomic_init(volatile atomic<T>* obj, T desr) noexcept; 268 269 template <class T> 270 void 271 atomic_init(atomic<T>* obj, T desr) noexcept; 272 273 template <class T> 274 void 275 atomic_store(volatile atomic<T>* obj, T desr) noexcept; 276 277 template <class T> 278 void 279 atomic_store(atomic<T>* obj, T desr) noexcept; 280 281 template <class T> 282 void 283 atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept; 284 285 template <class T> 286 void 287 atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept; 288 289 template <class T> 290 T 291 atomic_load(const volatile atomic<T>* obj) noexcept; 292 293 template <class T> 294 T 295 atomic_load(const atomic<T>* obj) noexcept; 296 297 template <class T> 298 T 299 atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept; 300 301 template <class T> 302 T 303 atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept; 304 305 template <class T> 306 T 307 atomic_exchange(volatile atomic<T>* obj, T desr) noexcept; 308 309 template <class T> 310 T 311 atomic_exchange(atomic<T>* obj, T desr) noexcept; 312 313 template <class T> 314 T 315 atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept; 316 317 template <class T> 318 T 319 atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept; 320 321 template <class T> 322 bool 323 atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept; 324 325 template <class T> 326 bool 327 atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept; 328 329 template <class T> 330 bool 331 atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept; 332 333 template <class T> 334 bool 335 atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept; 336 337 template <class T> 338 bool 339 atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc, 340 T desr, 341 memory_order s, memory_order f) noexcept; 342 343 template <class T> 344 bool 345 atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr, 346 memory_order s, memory_order f) noexcept; 347 348 template <class T> 349 bool 350 atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj, 351 T* expc, T desr, 352 memory_order s, memory_order f) noexcept; 353 354 template <class T> 355 bool 356 atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc, 357 T desr, 358 memory_order s, memory_order f) noexcept; 359 360 template <class Integral> 361 Integral 362 atomic_fetch_add(volatile atomic<Integral>* obj, Integral op) noexcept; 363 364 template <class Integral> 365 Integral 366 atomic_fetch_add(atomic<Integral>* obj, Integral op) noexcept; 367 368 template <class Integral> 369 Integral 370 atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op, 371 memory_order m) noexcept; 372 template <class Integral> 373 Integral 374 atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op, 375 memory_order m) noexcept; 376 template <class Integral> 377 Integral 378 atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op) noexcept; 379 380 template <class Integral> 381 Integral 382 atomic_fetch_sub(atomic<Integral>* obj, Integral op) noexcept; 383 384 template <class Integral> 385 Integral 386 atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op, 387 memory_order m) noexcept; 388 template <class Integral> 389 Integral 390 atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op, 391 memory_order m) noexcept; 392 template <class Integral> 393 Integral 394 atomic_fetch_and(volatile atomic<Integral>* obj, Integral op) noexcept; 395 396 template <class Integral> 397 Integral 398 atomic_fetch_and(atomic<Integral>* obj, Integral op) noexcept; 399 400 template <class Integral> 401 Integral 402 atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op, 403 memory_order m) noexcept; 404 template <class Integral> 405 Integral 406 atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op, 407 memory_order m) noexcept; 408 template <class Integral> 409 Integral 410 atomic_fetch_or(volatile atomic<Integral>* obj, Integral op) noexcept; 411 412 template <class Integral> 413 Integral 414 atomic_fetch_or(atomic<Integral>* obj, Integral op) noexcept; 415 416 template <class Integral> 417 Integral 418 atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op, 419 memory_order m) noexcept; 420 template <class Integral> 421 Integral 422 atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op, 423 memory_order m) noexcept; 424 template <class Integral> 425 Integral 426 atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op) noexcept; 427 428 template <class Integral> 429 Integral 430 atomic_fetch_xor(atomic<Integral>* obj, Integral op) noexcept; 431 432 template <class Integral> 433 Integral 434 atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op, 435 memory_order m) noexcept; 436 template <class Integral> 437 Integral 438 atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op, 439 memory_order m) noexcept; 440 441 template <class T> 442 T* 443 atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op) noexcept; 444 445 template <class T> 446 T* 447 atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op) noexcept; 448 449 template <class T> 450 T* 451 atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op, 452 memory_order m) noexcept; 453 template <class T> 454 T* 455 atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept; 456 457 template <class T> 458 T* 459 atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op) noexcept; 460 461 template <class T> 462 T* 463 atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op) noexcept; 464 465 template <class T> 466 T* 467 atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op, 468 memory_order m) noexcept; 469 template <class T> 470 T* 471 atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept; 472 473 // Atomics for standard typedef types 474 475 typedef atomic<bool> atomic_bool; 476 typedef atomic<char> atomic_char; 477 typedef atomic<signed char> atomic_schar; 478 typedef atomic<unsigned char> atomic_uchar; 479 typedef atomic<short> atomic_short; 480 typedef atomic<unsigned short> atomic_ushort; 481 typedef atomic<int> atomic_int; 482 typedef atomic<unsigned int> atomic_uint; 483 typedef atomic<long> atomic_long; 484 typedef atomic<unsigned long> atomic_ulong; 485 typedef atomic<long long> atomic_llong; 486 typedef atomic<unsigned long long> atomic_ullong; 487 typedef atomic<char16_t> atomic_char16_t; 488 typedef atomic<char32_t> atomic_char32_t; 489 typedef atomic<wchar_t> atomic_wchar_t; 490 491 typedef atomic<int_least8_t> atomic_int_least8_t; 492 typedef atomic<uint_least8_t> atomic_uint_least8_t; 493 typedef atomic<int_least16_t> atomic_int_least16_t; 494 typedef atomic<uint_least16_t> atomic_uint_least16_t; 495 typedef atomic<int_least32_t> atomic_int_least32_t; 496 typedef atomic<uint_least32_t> atomic_uint_least32_t; 497 typedef atomic<int_least64_t> atomic_int_least64_t; 498 typedef atomic<uint_least64_t> atomic_uint_least64_t; 499 500 typedef atomic<int_fast8_t> atomic_int_fast8_t; 501 typedef atomic<uint_fast8_t> atomic_uint_fast8_t; 502 typedef atomic<int_fast16_t> atomic_int_fast16_t; 503 typedef atomic<uint_fast16_t> atomic_uint_fast16_t; 504 typedef atomic<int_fast32_t> atomic_int_fast32_t; 505 typedef atomic<uint_fast32_t> atomic_uint_fast32_t; 506 typedef atomic<int_fast64_t> atomic_int_fast64_t; 507 typedef atomic<uint_fast64_t> atomic_uint_fast64_t; 508 509 typedef atomic<intptr_t> atomic_intptr_t; 510 typedef atomic<uintptr_t> atomic_uintptr_t; 511 typedef atomic<size_t> atomic_size_t; 512 typedef atomic<ptrdiff_t> atomic_ptrdiff_t; 513 typedef atomic<intmax_t> atomic_intmax_t; 514 typedef atomic<uintmax_t> atomic_uintmax_t; 515 516 // fences 517 518 void atomic_thread_fence(memory_order m) noexcept; 519 void atomic_signal_fence(memory_order m) noexcept; 520 521 } // std 522 523 */ 524 525 #include <__config> 526 #include <cstddef> 527 #include <cstdint> 528 #include <type_traits> 529 530 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 531 #pragma GCC system_header 532 #endif 533 534 _LIBCPP_BEGIN_NAMESPACE_STD 535 536 #if !__has_feature(cxx_atomic) 537 #error <atomic> is not implemented 538 #else 539 540 typedef enum memory_order 541 { 542 memory_order_relaxed, memory_order_consume, memory_order_acquire, 543 memory_order_release, memory_order_acq_rel, memory_order_seq_cst 544 } memory_order; 545 546 template <class _Tp> 547 inline _LIBCPP_INLINE_VISIBILITY 548 _Tp 549 kill_dependency(_Tp __y) _NOEXCEPT 550 { 551 return __y; 552 } 553 554 // general atomic<T> 555 556 template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value> 557 struct __atomic_base // false 558 { 559 mutable _Atomic(_Tp) __a_; 560 561 _LIBCPP_INLINE_VISIBILITY 562 bool is_lock_free() const volatile _NOEXCEPT 563 {return __c11_atomic_is_lock_free(sizeof(_Tp));} 564 _LIBCPP_INLINE_VISIBILITY 565 bool is_lock_free() const _NOEXCEPT 566 {return __c11_atomic_is_lock_free(sizeof(_Tp));} 567 _LIBCPP_INLINE_VISIBILITY 568 void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 569 {__c11_atomic_store(&__a_, __d, __m);} 570 _LIBCPP_INLINE_VISIBILITY 571 void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT 572 {__c11_atomic_store(&__a_, __d, __m);} 573 _LIBCPP_INLINE_VISIBILITY 574 _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT 575 {return __c11_atomic_load(&__a_, __m);} 576 _LIBCPP_INLINE_VISIBILITY 577 _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT 578 {return __c11_atomic_load(&__a_, __m);} 579 _LIBCPP_INLINE_VISIBILITY 580 operator _Tp() const volatile _NOEXCEPT {return load();} 581 _LIBCPP_INLINE_VISIBILITY 582 operator _Tp() const _NOEXCEPT {return load();} 583 _LIBCPP_INLINE_VISIBILITY 584 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 585 {return __c11_atomic_exchange(&__a_, __d, __m);} 586 _LIBCPP_INLINE_VISIBILITY 587 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT 588 {return __c11_atomic_exchange(&__a_, __d, __m);} 589 _LIBCPP_INLINE_VISIBILITY 590 bool compare_exchange_weak(_Tp& __e, _Tp __d, 591 memory_order __s, memory_order __f) volatile _NOEXCEPT 592 {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);} 593 _LIBCPP_INLINE_VISIBILITY 594 bool compare_exchange_weak(_Tp& __e, _Tp __d, 595 memory_order __s, memory_order __f) _NOEXCEPT 596 {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);} 597 _LIBCPP_INLINE_VISIBILITY 598 bool compare_exchange_strong(_Tp& __e, _Tp __d, 599 memory_order __s, memory_order __f) volatile _NOEXCEPT 600 {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);} 601 _LIBCPP_INLINE_VISIBILITY 602 bool compare_exchange_strong(_Tp& __e, _Tp __d, 603 memory_order __s, memory_order __f) _NOEXCEPT 604 {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);} 605 _LIBCPP_INLINE_VISIBILITY 606 bool compare_exchange_weak(_Tp& __e, _Tp __d, 607 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 608 {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);} 609 _LIBCPP_INLINE_VISIBILITY 610 bool compare_exchange_weak(_Tp& __e, _Tp __d, 611 memory_order __m = memory_order_seq_cst) _NOEXCEPT 612 {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);} 613 _LIBCPP_INLINE_VISIBILITY 614 bool compare_exchange_strong(_Tp& __e, _Tp __d, 615 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 616 {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);} 617 _LIBCPP_INLINE_VISIBILITY 618 bool compare_exchange_strong(_Tp& __e, _Tp __d, 619 memory_order __m = memory_order_seq_cst) _NOEXCEPT 620 {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);} 621 622 _LIBCPP_INLINE_VISIBILITY 623 __atomic_base() _NOEXCEPT {} // = default; 624 _LIBCPP_INLINE_VISIBILITY 625 _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {} 626 #ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS 627 __atomic_base(const __atomic_base&) = delete; 628 __atomic_base& operator=(const __atomic_base&) = delete; 629 __atomic_base& operator=(const __atomic_base&) volatile = delete; 630 #else // _LIBCPP_HAS_NO_DELETED_FUNCTIONS 631 private: 632 __atomic_base(const __atomic_base&); 633 __atomic_base& operator=(const __atomic_base&); 634 __atomic_base& operator=(const __atomic_base&) volatile; 635 #endif // _LIBCPP_HAS_NO_DELETED_FUNCTIONS 636 }; 637 638 // atomic<Integral> 639 640 template <class _Tp> 641 struct __atomic_base<_Tp, true> 642 : public __atomic_base<_Tp, false> 643 { 644 typedef __atomic_base<_Tp, false> __base; 645 _LIBCPP_INLINE_VISIBILITY 646 __atomic_base() _NOEXCEPT {} // = default; 647 _LIBCPP_INLINE_VISIBILITY 648 _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {} 649 650 _LIBCPP_INLINE_VISIBILITY 651 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 652 {return __c11_atomic_fetch_add(&this->__a_, __op, __m);} 653 _LIBCPP_INLINE_VISIBILITY 654 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 655 {return __c11_atomic_fetch_add(&this->__a_, __op, __m);} 656 _LIBCPP_INLINE_VISIBILITY 657 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 658 {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);} 659 _LIBCPP_INLINE_VISIBILITY 660 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 661 {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);} 662 _LIBCPP_INLINE_VISIBILITY 663 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 664 {return __c11_atomic_fetch_and(&this->__a_, __op, __m);} 665 _LIBCPP_INLINE_VISIBILITY 666 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 667 {return __c11_atomic_fetch_and(&this->__a_, __op, __m);} 668 _LIBCPP_INLINE_VISIBILITY 669 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 670 {return __c11_atomic_fetch_or(&this->__a_, __op, __m);} 671 _LIBCPP_INLINE_VISIBILITY 672 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 673 {return __c11_atomic_fetch_or(&this->__a_, __op, __m);} 674 _LIBCPP_INLINE_VISIBILITY 675 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 676 {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);} 677 _LIBCPP_INLINE_VISIBILITY 678 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 679 {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);} 680 681 _LIBCPP_INLINE_VISIBILITY 682 _Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));} 683 _LIBCPP_INLINE_VISIBILITY 684 _Tp operator++(int) _NOEXCEPT {return fetch_add(_Tp(1));} 685 _LIBCPP_INLINE_VISIBILITY 686 _Tp operator--(int) volatile _NOEXCEPT {return fetch_sub(_Tp(1));} 687 _LIBCPP_INLINE_VISIBILITY 688 _Tp operator--(int) _NOEXCEPT {return fetch_sub(_Tp(1));} 689 _LIBCPP_INLINE_VISIBILITY 690 _Tp operator++() volatile _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);} 691 _LIBCPP_INLINE_VISIBILITY 692 _Tp operator++() _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);} 693 _LIBCPP_INLINE_VISIBILITY 694 _Tp operator--() volatile _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);} 695 _LIBCPP_INLINE_VISIBILITY 696 _Tp operator--() _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);} 697 _LIBCPP_INLINE_VISIBILITY 698 _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;} 699 _LIBCPP_INLINE_VISIBILITY 700 _Tp operator+=(_Tp __op) _NOEXCEPT {return fetch_add(__op) + __op;} 701 _LIBCPP_INLINE_VISIBILITY 702 _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;} 703 _LIBCPP_INLINE_VISIBILITY 704 _Tp operator-=(_Tp __op) _NOEXCEPT {return fetch_sub(__op) - __op;} 705 _LIBCPP_INLINE_VISIBILITY 706 _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;} 707 _LIBCPP_INLINE_VISIBILITY 708 _Tp operator&=(_Tp __op) _NOEXCEPT {return fetch_and(__op) & __op;} 709 _LIBCPP_INLINE_VISIBILITY 710 _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;} 711 _LIBCPP_INLINE_VISIBILITY 712 _Tp operator|=(_Tp __op) _NOEXCEPT {return fetch_or(__op) | __op;} 713 _LIBCPP_INLINE_VISIBILITY 714 _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;} 715 _LIBCPP_INLINE_VISIBILITY 716 _Tp operator^=(_Tp __op) _NOEXCEPT {return fetch_xor(__op) ^ __op;} 717 }; 718 719 // atomic<T> 720 721 template <class _Tp> 722 struct atomic 723 : public __atomic_base<_Tp> 724 { 725 typedef __atomic_base<_Tp> __base; 726 _LIBCPP_INLINE_VISIBILITY 727 atomic() _NOEXCEPT {} // = default; 728 _LIBCPP_INLINE_VISIBILITY 729 _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {} 730 731 _LIBCPP_INLINE_VISIBILITY 732 _Tp operator=(_Tp __d) volatile _NOEXCEPT 733 {__base::store(__d); return __d;} 734 _LIBCPP_INLINE_VISIBILITY 735 _Tp operator=(_Tp __d) _NOEXCEPT 736 {__base::store(__d); return __d;} 737 }; 738 739 // atomic<T*> 740 741 template <class _Tp> 742 struct atomic<_Tp*> 743 : public __atomic_base<_Tp*> 744 { 745 typedef __atomic_base<_Tp*> __base; 746 _LIBCPP_INLINE_VISIBILITY 747 atomic() _NOEXCEPT {} // = default; 748 _LIBCPP_INLINE_VISIBILITY 749 _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {} 750 751 _LIBCPP_INLINE_VISIBILITY 752 _Tp* operator=(_Tp* __d) volatile _NOEXCEPT 753 {__base::store(__d); return __d;} 754 _LIBCPP_INLINE_VISIBILITY 755 _Tp* operator=(_Tp* __d) _NOEXCEPT 756 {__base::store(__d); return __d;} 757 758 _LIBCPP_INLINE_VISIBILITY 759 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) 760 volatile _NOEXCEPT 761 {return __c11_atomic_fetch_add(&this->__a_, __op, __m);} 762 _LIBCPP_INLINE_VISIBILITY 763 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 764 {return __c11_atomic_fetch_add(&this->__a_, __op, __m);} 765 _LIBCPP_INLINE_VISIBILITY 766 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) 767 volatile _NOEXCEPT 768 {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);} 769 _LIBCPP_INLINE_VISIBILITY 770 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 771 {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);} 772 773 _LIBCPP_INLINE_VISIBILITY 774 _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);} 775 _LIBCPP_INLINE_VISIBILITY 776 _Tp* operator++(int) _NOEXCEPT {return fetch_add(1);} 777 _LIBCPP_INLINE_VISIBILITY 778 _Tp* operator--(int) volatile _NOEXCEPT {return fetch_sub(1);} 779 _LIBCPP_INLINE_VISIBILITY 780 _Tp* operator--(int) _NOEXCEPT {return fetch_sub(1);} 781 _LIBCPP_INLINE_VISIBILITY 782 _Tp* operator++() volatile _NOEXCEPT {return fetch_add(1) + 1;} 783 _LIBCPP_INLINE_VISIBILITY 784 _Tp* operator++() _NOEXCEPT {return fetch_add(1) + 1;} 785 _LIBCPP_INLINE_VISIBILITY 786 _Tp* operator--() volatile _NOEXCEPT {return fetch_sub(1) - 1;} 787 _LIBCPP_INLINE_VISIBILITY 788 _Tp* operator--() _NOEXCEPT {return fetch_sub(1) - 1;} 789 _LIBCPP_INLINE_VISIBILITY 790 _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;} 791 _LIBCPP_INLINE_VISIBILITY 792 _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT {return fetch_add(__op) + __op;} 793 _LIBCPP_INLINE_VISIBILITY 794 _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;} 795 _LIBCPP_INLINE_VISIBILITY 796 _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;} 797 }; 798 799 // atomic_is_lock_free 800 801 template <class _Tp> 802 inline _LIBCPP_INLINE_VISIBILITY 803 bool 804 atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT 805 { 806 return __o->is_lock_free(); 807 } 808 809 template <class _Tp> 810 inline _LIBCPP_INLINE_VISIBILITY 811 bool 812 atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT 813 { 814 return __o->is_lock_free(); 815 } 816 817 // atomic_init 818 819 template <class _Tp> 820 inline _LIBCPP_INLINE_VISIBILITY 821 void 822 atomic_init(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 823 { 824 __c11_atomic_init(&__o->__a_, __d); 825 } 826 827 template <class _Tp> 828 inline _LIBCPP_INLINE_VISIBILITY 829 void 830 atomic_init(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 831 { 832 __c11_atomic_init(&__o->__a_, __d); 833 } 834 835 // atomic_store 836 837 template <class _Tp> 838 inline _LIBCPP_INLINE_VISIBILITY 839 void 840 atomic_store(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 841 { 842 __o->store(__d); 843 } 844 845 template <class _Tp> 846 inline _LIBCPP_INLINE_VISIBILITY 847 void 848 atomic_store(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 849 { 850 __o->store(__d); 851 } 852 853 // atomic_store_explicit 854 855 template <class _Tp> 856 inline _LIBCPP_INLINE_VISIBILITY 857 void 858 atomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT 859 { 860 __o->store(__d, __m); 861 } 862 863 template <class _Tp> 864 inline _LIBCPP_INLINE_VISIBILITY 865 void 866 atomic_store_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT 867 { 868 __o->store(__d, __m); 869 } 870 871 // atomic_load 872 873 template <class _Tp> 874 inline _LIBCPP_INLINE_VISIBILITY 875 _Tp 876 atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT 877 { 878 return __o->load(); 879 } 880 881 template <class _Tp> 882 inline _LIBCPP_INLINE_VISIBILITY 883 _Tp 884 atomic_load(const atomic<_Tp>* __o) _NOEXCEPT 885 { 886 return __o->load(); 887 } 888 889 // atomic_load_explicit 890 891 template <class _Tp> 892 inline _LIBCPP_INLINE_VISIBILITY 893 _Tp 894 atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT 895 { 896 return __o->load(__m); 897 } 898 899 template <class _Tp> 900 inline _LIBCPP_INLINE_VISIBILITY 901 _Tp 902 atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT 903 { 904 return __o->load(__m); 905 } 906 907 // atomic_exchange 908 909 template <class _Tp> 910 inline _LIBCPP_INLINE_VISIBILITY 911 _Tp 912 atomic_exchange(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 913 { 914 return __o->exchange(__d); 915 } 916 917 template <class _Tp> 918 inline _LIBCPP_INLINE_VISIBILITY 919 _Tp 920 atomic_exchange(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 921 { 922 return __o->exchange(__d); 923 } 924 925 // atomic_exchange_explicit 926 927 template <class _Tp> 928 inline _LIBCPP_INLINE_VISIBILITY 929 _Tp 930 atomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT 931 { 932 return __o->exchange(__d, __m); 933 } 934 935 template <class _Tp> 936 inline _LIBCPP_INLINE_VISIBILITY 937 _Tp 938 atomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT 939 { 940 return __o->exchange(__d, __m); 941 } 942 943 // atomic_compare_exchange_weak 944 945 template <class _Tp> 946 inline _LIBCPP_INLINE_VISIBILITY 947 bool 948 atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT 949 { 950 return __o->compare_exchange_weak(*__e, __d); 951 } 952 953 template <class _Tp> 954 inline _LIBCPP_INLINE_VISIBILITY 955 bool 956 atomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT 957 { 958 return __o->compare_exchange_weak(*__e, __d); 959 } 960 961 // atomic_compare_exchange_strong 962 963 template <class _Tp> 964 inline _LIBCPP_INLINE_VISIBILITY 965 bool 966 atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT 967 { 968 return __o->compare_exchange_strong(*__e, __d); 969 } 970 971 template <class _Tp> 972 inline _LIBCPP_INLINE_VISIBILITY 973 bool 974 atomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT 975 { 976 return __o->compare_exchange_strong(*__e, __d); 977 } 978 979 // atomic_compare_exchange_weak_explicit 980 981 template <class _Tp> 982 inline _LIBCPP_INLINE_VISIBILITY 983 bool 984 atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e, 985 _Tp __d, 986 memory_order __s, memory_order __f) _NOEXCEPT 987 { 988 return __o->compare_exchange_weak(*__e, __d, __s, __f); 989 } 990 991 template <class _Tp> 992 inline _LIBCPP_INLINE_VISIBILITY 993 bool 994 atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d, 995 memory_order __s, memory_order __f) _NOEXCEPT 996 { 997 return __o->compare_exchange_weak(*__e, __d, __s, __f); 998 } 999 1000 // atomic_compare_exchange_strong_explicit 1001 1002 template <class _Tp> 1003 inline _LIBCPP_INLINE_VISIBILITY 1004 bool 1005 atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o, 1006 _Tp* __e, _Tp __d, 1007 memory_order __s, memory_order __f) _NOEXCEPT 1008 { 1009 return __o->compare_exchange_strong(*__e, __d, __s, __f); 1010 } 1011 1012 template <class _Tp> 1013 inline _LIBCPP_INLINE_VISIBILITY 1014 bool 1015 atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e, 1016 _Tp __d, 1017 memory_order __s, memory_order __f) _NOEXCEPT 1018 { 1019 return __o->compare_exchange_strong(*__e, __d, __s, __f); 1020 } 1021 1022 // atomic_fetch_add 1023 1024 template <class _Tp> 1025 inline _LIBCPP_INLINE_VISIBILITY 1026 typename enable_if 1027 < 1028 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1029 _Tp 1030 >::type 1031 atomic_fetch_add(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1032 { 1033 return __o->fetch_add(__op); 1034 } 1035 1036 template <class _Tp> 1037 inline _LIBCPP_INLINE_VISIBILITY 1038 typename enable_if 1039 < 1040 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1041 _Tp 1042 >::type 1043 atomic_fetch_add(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1044 { 1045 return __o->fetch_add(__op); 1046 } 1047 1048 template <class _Tp> 1049 inline _LIBCPP_INLINE_VISIBILITY 1050 _Tp* 1051 atomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT 1052 { 1053 return __o->fetch_add(__op); 1054 } 1055 1056 template <class _Tp> 1057 inline _LIBCPP_INLINE_VISIBILITY 1058 _Tp* 1059 atomic_fetch_add(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT 1060 { 1061 return __o->fetch_add(__op); 1062 } 1063 1064 // atomic_fetch_add_explicit 1065 1066 template <class _Tp> 1067 inline _LIBCPP_INLINE_VISIBILITY 1068 typename enable_if 1069 < 1070 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1071 _Tp 1072 >::type 1073 atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1074 { 1075 return __o->fetch_add(__op, __m); 1076 } 1077 1078 template <class _Tp> 1079 inline _LIBCPP_INLINE_VISIBILITY 1080 typename enable_if 1081 < 1082 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1083 _Tp 1084 >::type 1085 atomic_fetch_add_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1086 { 1087 return __o->fetch_add(__op, __m); 1088 } 1089 1090 template <class _Tp> 1091 inline _LIBCPP_INLINE_VISIBILITY 1092 _Tp* 1093 atomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op, 1094 memory_order __m) _NOEXCEPT 1095 { 1096 return __o->fetch_add(__op, __m); 1097 } 1098 1099 template <class _Tp> 1100 inline _LIBCPP_INLINE_VISIBILITY 1101 _Tp* 1102 atomic_fetch_add_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT 1103 { 1104 return __o->fetch_add(__op, __m); 1105 } 1106 1107 // atomic_fetch_sub 1108 1109 template <class _Tp> 1110 inline _LIBCPP_INLINE_VISIBILITY 1111 typename enable_if 1112 < 1113 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1114 _Tp 1115 >::type 1116 atomic_fetch_sub(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1117 { 1118 return __o->fetch_sub(__op); 1119 } 1120 1121 template <class _Tp> 1122 inline _LIBCPP_INLINE_VISIBILITY 1123 typename enable_if 1124 < 1125 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1126 _Tp 1127 >::type 1128 atomic_fetch_sub(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1129 { 1130 return __o->fetch_sub(__op); 1131 } 1132 1133 template <class _Tp> 1134 inline _LIBCPP_INLINE_VISIBILITY 1135 _Tp* 1136 atomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT 1137 { 1138 return __o->fetch_sub(__op); 1139 } 1140 1141 template <class _Tp> 1142 inline _LIBCPP_INLINE_VISIBILITY 1143 _Tp* 1144 atomic_fetch_sub(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT 1145 { 1146 return __o->fetch_sub(__op); 1147 } 1148 1149 // atomic_fetch_sub_explicit 1150 1151 template <class _Tp> 1152 inline _LIBCPP_INLINE_VISIBILITY 1153 typename enable_if 1154 < 1155 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1156 _Tp 1157 >::type 1158 atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1159 { 1160 return __o->fetch_sub(__op, __m); 1161 } 1162 1163 template <class _Tp> 1164 inline _LIBCPP_INLINE_VISIBILITY 1165 typename enable_if 1166 < 1167 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1168 _Tp 1169 >::type 1170 atomic_fetch_sub_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1171 { 1172 return __o->fetch_sub(__op, __m); 1173 } 1174 1175 template <class _Tp> 1176 inline _LIBCPP_INLINE_VISIBILITY 1177 _Tp* 1178 atomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op, 1179 memory_order __m) _NOEXCEPT 1180 { 1181 return __o->fetch_sub(__op, __m); 1182 } 1183 1184 template <class _Tp> 1185 inline _LIBCPP_INLINE_VISIBILITY 1186 _Tp* 1187 atomic_fetch_sub_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT 1188 { 1189 return __o->fetch_sub(__op, __m); 1190 } 1191 1192 // atomic_fetch_and 1193 1194 template <class _Tp> 1195 inline _LIBCPP_INLINE_VISIBILITY 1196 typename enable_if 1197 < 1198 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1199 _Tp 1200 >::type 1201 atomic_fetch_and(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1202 { 1203 return __o->fetch_and(__op); 1204 } 1205 1206 template <class _Tp> 1207 inline _LIBCPP_INLINE_VISIBILITY 1208 typename enable_if 1209 < 1210 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1211 _Tp 1212 >::type 1213 atomic_fetch_and(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1214 { 1215 return __o->fetch_and(__op); 1216 } 1217 1218 // atomic_fetch_and_explicit 1219 1220 template <class _Tp> 1221 inline _LIBCPP_INLINE_VISIBILITY 1222 typename enable_if 1223 < 1224 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1225 _Tp 1226 >::type 1227 atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1228 { 1229 return __o->fetch_and(__op, __m); 1230 } 1231 1232 template <class _Tp> 1233 inline _LIBCPP_INLINE_VISIBILITY 1234 typename enable_if 1235 < 1236 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1237 _Tp 1238 >::type 1239 atomic_fetch_and_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1240 { 1241 return __o->fetch_and(__op, __m); 1242 } 1243 1244 // atomic_fetch_or 1245 1246 template <class _Tp> 1247 inline _LIBCPP_INLINE_VISIBILITY 1248 typename enable_if 1249 < 1250 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1251 _Tp 1252 >::type 1253 atomic_fetch_or(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1254 { 1255 return __o->fetch_or(__op); 1256 } 1257 1258 template <class _Tp> 1259 inline _LIBCPP_INLINE_VISIBILITY 1260 typename enable_if 1261 < 1262 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1263 _Tp 1264 >::type 1265 atomic_fetch_or(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1266 { 1267 return __o->fetch_or(__op); 1268 } 1269 1270 // atomic_fetch_or_explicit 1271 1272 template <class _Tp> 1273 inline _LIBCPP_INLINE_VISIBILITY 1274 typename enable_if 1275 < 1276 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1277 _Tp 1278 >::type 1279 atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1280 { 1281 return __o->fetch_or(__op, __m); 1282 } 1283 1284 template <class _Tp> 1285 inline _LIBCPP_INLINE_VISIBILITY 1286 typename enable_if 1287 < 1288 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1289 _Tp 1290 >::type 1291 atomic_fetch_or_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1292 { 1293 return __o->fetch_or(__op, __m); 1294 } 1295 1296 // atomic_fetch_xor 1297 1298 template <class _Tp> 1299 inline _LIBCPP_INLINE_VISIBILITY 1300 typename enable_if 1301 < 1302 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1303 _Tp 1304 >::type 1305 atomic_fetch_xor(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1306 { 1307 return __o->fetch_xor(__op); 1308 } 1309 1310 template <class _Tp> 1311 inline _LIBCPP_INLINE_VISIBILITY 1312 typename enable_if 1313 < 1314 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1315 _Tp 1316 >::type 1317 atomic_fetch_xor(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1318 { 1319 return __o->fetch_xor(__op); 1320 } 1321 1322 // atomic_fetch_xor_explicit 1323 1324 template <class _Tp> 1325 inline _LIBCPP_INLINE_VISIBILITY 1326 typename enable_if 1327 < 1328 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1329 _Tp 1330 >::type 1331 atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1332 { 1333 return __o->fetch_xor(__op, __m); 1334 } 1335 1336 template <class _Tp> 1337 inline _LIBCPP_INLINE_VISIBILITY 1338 typename enable_if 1339 < 1340 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1341 _Tp 1342 >::type 1343 atomic_fetch_xor_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1344 { 1345 return __o->fetch_xor(__op, __m); 1346 } 1347 1348 // flag type and operations 1349 1350 typedef struct atomic_flag 1351 { 1352 _Atomic(bool) __a_; 1353 1354 _LIBCPP_INLINE_VISIBILITY 1355 bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1356 {return __c11_atomic_exchange(&__a_, true, __m);} 1357 _LIBCPP_INLINE_VISIBILITY 1358 bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT 1359 {return __c11_atomic_exchange(&__a_, true, __m);} 1360 _LIBCPP_INLINE_VISIBILITY 1361 void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1362 {__c11_atomic_store(&__a_, false, __m);} 1363 _LIBCPP_INLINE_VISIBILITY 1364 void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT 1365 {__c11_atomic_store(&__a_, false, __m);} 1366 1367 _LIBCPP_INLINE_VISIBILITY 1368 atomic_flag() _NOEXCEPT {} // = default; 1369 _LIBCPP_INLINE_VISIBILITY 1370 atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} 1371 1372 #ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS 1373 atomic_flag(const atomic_flag&) = delete; 1374 atomic_flag& operator=(const atomic_flag&) = delete; 1375 atomic_flag& operator=(const atomic_flag&) volatile = delete; 1376 #else // _LIBCPP_HAS_NO_DELETED_FUNCTIONS 1377 private: 1378 atomic_flag(const atomic_flag&); 1379 atomic_flag& operator=(const atomic_flag&); 1380 atomic_flag& operator=(const atomic_flag&) volatile; 1381 #endif // _LIBCPP_HAS_NO_DELETED_FUNCTIONS 1382 } atomic_flag; 1383 1384 inline _LIBCPP_INLINE_VISIBILITY 1385 bool 1386 atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT 1387 { 1388 return __o->test_and_set(); 1389 } 1390 1391 inline _LIBCPP_INLINE_VISIBILITY 1392 bool 1393 atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT 1394 { 1395 return __o->test_and_set(); 1396 } 1397 1398 inline _LIBCPP_INLINE_VISIBILITY 1399 bool 1400 atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT 1401 { 1402 return __o->test_and_set(__m); 1403 } 1404 1405 inline _LIBCPP_INLINE_VISIBILITY 1406 bool 1407 atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT 1408 { 1409 return __o->test_and_set(__m); 1410 } 1411 1412 inline _LIBCPP_INLINE_VISIBILITY 1413 void 1414 atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT 1415 { 1416 __o->clear(); 1417 } 1418 1419 inline _LIBCPP_INLINE_VISIBILITY 1420 void 1421 atomic_flag_clear(atomic_flag* __o) _NOEXCEPT 1422 { 1423 __o->clear(); 1424 } 1425 1426 inline _LIBCPP_INLINE_VISIBILITY 1427 void 1428 atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT 1429 { 1430 __o->clear(__m); 1431 } 1432 1433 inline _LIBCPP_INLINE_VISIBILITY 1434 void 1435 atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT 1436 { 1437 __o->clear(__m); 1438 } 1439 1440 // fences 1441 1442 inline _LIBCPP_INLINE_VISIBILITY 1443 void 1444 atomic_thread_fence(memory_order __m) _NOEXCEPT 1445 { 1446 __c11_atomic_thread_fence(__m); 1447 } 1448 1449 inline _LIBCPP_INLINE_VISIBILITY 1450 void 1451 atomic_signal_fence(memory_order __m) _NOEXCEPT 1452 { 1453 __c11_atomic_signal_fence(__m); 1454 } 1455 1456 // Atomics for standard typedef types 1457 1458 typedef atomic<bool> atomic_bool; 1459 typedef atomic<char> atomic_char; 1460 typedef atomic<signed char> atomic_schar; 1461 typedef atomic<unsigned char> atomic_uchar; 1462 typedef atomic<short> atomic_short; 1463 typedef atomic<unsigned short> atomic_ushort; 1464 typedef atomic<int> atomic_int; 1465 typedef atomic<unsigned int> atomic_uint; 1466 typedef atomic<long> atomic_long; 1467 typedef atomic<unsigned long> atomic_ulong; 1468 typedef atomic<long long> atomic_llong; 1469 typedef atomic<unsigned long long> atomic_ullong; 1470 typedef atomic<char16_t> atomic_char16_t; 1471 typedef atomic<char32_t> atomic_char32_t; 1472 typedef atomic<wchar_t> atomic_wchar_t; 1473 1474 typedef atomic<int_least8_t> atomic_int_least8_t; 1475 typedef atomic<uint_least8_t> atomic_uint_least8_t; 1476 typedef atomic<int_least16_t> atomic_int_least16_t; 1477 typedef atomic<uint_least16_t> atomic_uint_least16_t; 1478 typedef atomic<int_least32_t> atomic_int_least32_t; 1479 typedef atomic<uint_least32_t> atomic_uint_least32_t; 1480 typedef atomic<int_least64_t> atomic_int_least64_t; 1481 typedef atomic<uint_least64_t> atomic_uint_least64_t; 1482 1483 typedef atomic<int_fast8_t> atomic_int_fast8_t; 1484 typedef atomic<uint_fast8_t> atomic_uint_fast8_t; 1485 typedef atomic<int_fast16_t> atomic_int_fast16_t; 1486 typedef atomic<uint_fast16_t> atomic_uint_fast16_t; 1487 typedef atomic<int_fast32_t> atomic_int_fast32_t; 1488 typedef atomic<uint_fast32_t> atomic_uint_fast32_t; 1489 typedef atomic<int_fast64_t> atomic_int_fast64_t; 1490 typedef atomic<uint_fast64_t> atomic_uint_fast64_t; 1491 1492 typedef atomic<intptr_t> atomic_intptr_t; 1493 typedef atomic<uintptr_t> atomic_uintptr_t; 1494 typedef atomic<size_t> atomic_size_t; 1495 typedef atomic<ptrdiff_t> atomic_ptrdiff_t; 1496 typedef atomic<intmax_t> atomic_intmax_t; 1497 typedef atomic<uintmax_t> atomic_uintmax_t; 1498 1499 #define ATOMIC_FLAG_INIT {false} 1500 #define ATOMIC_VAR_INIT(__v) {__v} 1501 1502 // lock-free property 1503 1504 #define ATOMIC_CHAR_LOCK_FREE 0 1505 #define ATOMIC_CHAR16_T_LOCK_FREE 0 1506 #define ATOMIC_CHAR32_T_LOCK_FREE 0 1507 #define ATOMIC_WCHAR_T_LOCK_FREE 0 1508 #define ATOMIC_SHORT_LOCK_FREE 0 1509 #define ATOMIC_INT_LOCK_FREE 0 1510 #define ATOMIC_LONG_LOCK_FREE 0 1511 #define ATOMIC_LLONG_LOCK_FREE 0 1512 1513 #endif // !__has_feature(cxx_atomic) 1514 1515 _LIBCPP_END_NAMESPACE_STD 1516 1517 #endif // _LIBCPP_ATOMIC 1518