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 17namespace std 18{ 19 20// feature test macro 21 22#define __cpp_lib_atomic_is_always_lock_free // as specified by SG10 23 24// order and consistency 25 26typedef enum memory_order 27{ 28 memory_order_relaxed, 29 memory_order_consume, // load-consume 30 memory_order_acquire, // load-acquire 31 memory_order_release, // store-release 32 memory_order_acq_rel, // store-release load-acquire 33 memory_order_seq_cst // store-release load-acquire 34} memory_order; 35 36template <class T> T kill_dependency(T y) noexcept; 37 38// lock-free property 39 40#define ATOMIC_BOOL_LOCK_FREE unspecified 41#define ATOMIC_CHAR_LOCK_FREE unspecified 42#define ATOMIC_CHAR16_T_LOCK_FREE unspecified 43#define ATOMIC_CHAR32_T_LOCK_FREE unspecified 44#define ATOMIC_WCHAR_T_LOCK_FREE unspecified 45#define ATOMIC_SHORT_LOCK_FREE unspecified 46#define ATOMIC_INT_LOCK_FREE unspecified 47#define ATOMIC_LONG_LOCK_FREE unspecified 48#define ATOMIC_LLONG_LOCK_FREE unspecified 49#define ATOMIC_POINTER_LOCK_FREE unspecified 50 51// flag type and operations 52 53typedef struct atomic_flag 54{ 55 bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept; 56 bool test_and_set(memory_order m = memory_order_seq_cst) noexcept; 57 void clear(memory_order m = memory_order_seq_cst) volatile noexcept; 58 void clear(memory_order m = memory_order_seq_cst) noexcept; 59 atomic_flag() noexcept = default; 60 atomic_flag(const atomic_flag&) = delete; 61 atomic_flag& operator=(const atomic_flag&) = delete; 62 atomic_flag& operator=(const atomic_flag&) volatile = delete; 63} atomic_flag; 64 65bool 66 atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept; 67 68bool 69 atomic_flag_test_and_set(atomic_flag* obj) noexcept; 70 71bool 72 atomic_flag_test_and_set_explicit(volatile atomic_flag* obj, 73 memory_order m) noexcept; 74 75bool 76 atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept; 77 78void 79 atomic_flag_clear(volatile atomic_flag* obj) noexcept; 80 81void 82 atomic_flag_clear(atomic_flag* obj) noexcept; 83 84void 85 atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept; 86 87void 88 atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept; 89 90#define ATOMIC_FLAG_INIT see below 91#define ATOMIC_VAR_INIT(value) see below 92 93template <class T> 94struct atomic 95{ 96 static constexpr bool is_always_lock_free; 97 bool is_lock_free() const volatile noexcept; 98 bool is_lock_free() const noexcept; 99 void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept; 100 void store(T desr, memory_order m = memory_order_seq_cst) noexcept; 101 T load(memory_order m = memory_order_seq_cst) const volatile noexcept; 102 T load(memory_order m = memory_order_seq_cst) const noexcept; 103 operator T() const volatile noexcept; 104 operator T() const noexcept; 105 T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept; 106 T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept; 107 bool compare_exchange_weak(T& expc, T desr, 108 memory_order s, memory_order f) volatile noexcept; 109 bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept; 110 bool compare_exchange_strong(T& expc, T desr, 111 memory_order s, memory_order f) volatile noexcept; 112 bool compare_exchange_strong(T& expc, T desr, 113 memory_order s, memory_order f) noexcept; 114 bool compare_exchange_weak(T& expc, T desr, 115 memory_order m = memory_order_seq_cst) volatile noexcept; 116 bool compare_exchange_weak(T& expc, T desr, 117 memory_order m = memory_order_seq_cst) noexcept; 118 bool compare_exchange_strong(T& expc, T desr, 119 memory_order m = memory_order_seq_cst) volatile noexcept; 120 bool compare_exchange_strong(T& expc, T desr, 121 memory_order m = memory_order_seq_cst) noexcept; 122 123 atomic() noexcept = default; 124 constexpr atomic(T desr) noexcept; 125 atomic(const atomic&) = delete; 126 atomic& operator=(const atomic&) = delete; 127 atomic& operator=(const atomic&) volatile = delete; 128 T operator=(T) volatile noexcept; 129 T operator=(T) noexcept; 130}; 131 132template <> 133struct atomic<integral> 134{ 135 static constexpr bool is_always_lock_free; 136 bool is_lock_free() const volatile noexcept; 137 bool is_lock_free() const noexcept; 138 void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept; 139 void store(integral desr, memory_order m = memory_order_seq_cst) noexcept; 140 integral load(memory_order m = memory_order_seq_cst) const volatile noexcept; 141 integral load(memory_order m = memory_order_seq_cst) const noexcept; 142 operator integral() const volatile noexcept; 143 operator integral() const noexcept; 144 integral exchange(integral desr, 145 memory_order m = memory_order_seq_cst) volatile noexcept; 146 integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept; 147 bool compare_exchange_weak(integral& expc, integral desr, 148 memory_order s, memory_order f) volatile noexcept; 149 bool compare_exchange_weak(integral& expc, integral desr, 150 memory_order s, memory_order f) noexcept; 151 bool compare_exchange_strong(integral& expc, integral desr, 152 memory_order s, memory_order f) volatile noexcept; 153 bool compare_exchange_strong(integral& expc, integral desr, 154 memory_order s, memory_order f) noexcept; 155 bool compare_exchange_weak(integral& expc, integral desr, 156 memory_order m = memory_order_seq_cst) volatile noexcept; 157 bool compare_exchange_weak(integral& expc, integral desr, 158 memory_order m = memory_order_seq_cst) noexcept; 159 bool compare_exchange_strong(integral& expc, integral desr, 160 memory_order m = memory_order_seq_cst) volatile noexcept; 161 bool compare_exchange_strong(integral& expc, integral desr, 162 memory_order m = memory_order_seq_cst) noexcept; 163 164 integral 165 fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 166 integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept; 167 integral 168 fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 169 integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept; 170 integral 171 fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 172 integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept; 173 integral 174 fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 175 integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept; 176 integral 177 fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 178 integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept; 179 180 atomic() noexcept = default; 181 constexpr atomic(integral desr) noexcept; 182 atomic(const atomic&) = delete; 183 atomic& operator=(const atomic&) = delete; 184 atomic& operator=(const atomic&) volatile = delete; 185 integral operator=(integral desr) volatile noexcept; 186 integral operator=(integral desr) noexcept; 187 188 integral operator++(int) volatile noexcept; 189 integral operator++(int) noexcept; 190 integral operator--(int) volatile noexcept; 191 integral operator--(int) noexcept; 192 integral operator++() volatile noexcept; 193 integral operator++() noexcept; 194 integral operator--() volatile noexcept; 195 integral operator--() noexcept; 196 integral operator+=(integral op) volatile noexcept; 197 integral operator+=(integral op) noexcept; 198 integral operator-=(integral op) volatile noexcept; 199 integral operator-=(integral op) noexcept; 200 integral operator&=(integral op) volatile noexcept; 201 integral operator&=(integral op) noexcept; 202 integral operator|=(integral op) volatile noexcept; 203 integral operator|=(integral op) noexcept; 204 integral operator^=(integral op) volatile noexcept; 205 integral operator^=(integral op) noexcept; 206}; 207 208template <class T> 209struct atomic<T*> 210{ 211 static constexpr bool is_always_lock_free; 212 bool is_lock_free() const volatile noexcept; 213 bool is_lock_free() const noexcept; 214 void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept; 215 void store(T* desr, memory_order m = memory_order_seq_cst) noexcept; 216 T* load(memory_order m = memory_order_seq_cst) const volatile noexcept; 217 T* load(memory_order m = memory_order_seq_cst) const noexcept; 218 operator T*() const volatile noexcept; 219 operator T*() const noexcept; 220 T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept; 221 T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept; 222 bool compare_exchange_weak(T*& expc, T* desr, 223 memory_order s, memory_order f) volatile noexcept; 224 bool compare_exchange_weak(T*& expc, T* desr, 225 memory_order s, memory_order f) noexcept; 226 bool compare_exchange_strong(T*& expc, T* desr, 227 memory_order s, memory_order f) volatile noexcept; 228 bool compare_exchange_strong(T*& expc, T* desr, 229 memory_order s, memory_order f) noexcept; 230 bool compare_exchange_weak(T*& expc, T* desr, 231 memory_order m = memory_order_seq_cst) volatile noexcept; 232 bool compare_exchange_weak(T*& expc, T* desr, 233 memory_order m = memory_order_seq_cst) noexcept; 234 bool compare_exchange_strong(T*& expc, T* desr, 235 memory_order m = memory_order_seq_cst) volatile noexcept; 236 bool compare_exchange_strong(T*& expc, T* desr, 237 memory_order m = memory_order_seq_cst) noexcept; 238 T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept; 239 T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept; 240 T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept; 241 T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept; 242 243 atomic() noexcept = default; 244 constexpr atomic(T* desr) noexcept; 245 atomic(const atomic&) = delete; 246 atomic& operator=(const atomic&) = delete; 247 atomic& operator=(const atomic&) volatile = delete; 248 249 T* operator=(T*) volatile noexcept; 250 T* operator=(T*) noexcept; 251 T* operator++(int) volatile noexcept; 252 T* operator++(int) noexcept; 253 T* operator--(int) volatile noexcept; 254 T* operator--(int) noexcept; 255 T* operator++() volatile noexcept; 256 T* operator++() noexcept; 257 T* operator--() volatile noexcept; 258 T* operator--() noexcept; 259 T* operator+=(ptrdiff_t op) volatile noexcept; 260 T* operator+=(ptrdiff_t op) noexcept; 261 T* operator-=(ptrdiff_t op) volatile noexcept; 262 T* operator-=(ptrdiff_t op) noexcept; 263}; 264 265 266template <class T> 267 bool 268 atomic_is_lock_free(const volatile atomic<T>* obj) noexcept; 269 270template <class T> 271 bool 272 atomic_is_lock_free(const atomic<T>* obj) noexcept; 273 274template <class T> 275 void 276 atomic_init(volatile atomic<T>* obj, T desr) noexcept; 277 278template <class T> 279 void 280 atomic_init(atomic<T>* obj, T desr) noexcept; 281 282template <class T> 283 void 284 atomic_store(volatile atomic<T>* obj, T desr) noexcept; 285 286template <class T> 287 void 288 atomic_store(atomic<T>* obj, T desr) noexcept; 289 290template <class T> 291 void 292 atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept; 293 294template <class T> 295 void 296 atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept; 297 298template <class T> 299 T 300 atomic_load(const volatile atomic<T>* obj) noexcept; 301 302template <class T> 303 T 304 atomic_load(const atomic<T>* obj) noexcept; 305 306template <class T> 307 T 308 atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept; 309 310template <class T> 311 T 312 atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept; 313 314template <class T> 315 T 316 atomic_exchange(volatile atomic<T>* obj, T desr) noexcept; 317 318template <class T> 319 T 320 atomic_exchange(atomic<T>* obj, T desr) noexcept; 321 322template <class T> 323 T 324 atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept; 325 326template <class T> 327 T 328 atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept; 329 330template <class T> 331 bool 332 atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept; 333 334template <class T> 335 bool 336 atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept; 337 338template <class T> 339 bool 340 atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept; 341 342template <class T> 343 bool 344 atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept; 345 346template <class T> 347 bool 348 atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc, 349 T desr, 350 memory_order s, memory_order f) noexcept; 351 352template <class T> 353 bool 354 atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr, 355 memory_order s, memory_order f) noexcept; 356 357template <class T> 358 bool 359 atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj, 360 T* expc, T desr, 361 memory_order s, memory_order f) noexcept; 362 363template <class T> 364 bool 365 atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc, 366 T desr, 367 memory_order s, memory_order f) noexcept; 368 369template <class Integral> 370 Integral 371 atomic_fetch_add(volatile atomic<Integral>* obj, Integral op) noexcept; 372 373template <class Integral> 374 Integral 375 atomic_fetch_add(atomic<Integral>* obj, Integral op) noexcept; 376 377template <class Integral> 378 Integral 379 atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op, 380 memory_order m) noexcept; 381template <class Integral> 382 Integral 383 atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op, 384 memory_order m) noexcept; 385template <class Integral> 386 Integral 387 atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op) noexcept; 388 389template <class Integral> 390 Integral 391 atomic_fetch_sub(atomic<Integral>* obj, Integral op) noexcept; 392 393template <class Integral> 394 Integral 395 atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op, 396 memory_order m) noexcept; 397template <class Integral> 398 Integral 399 atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op, 400 memory_order m) noexcept; 401template <class Integral> 402 Integral 403 atomic_fetch_and(volatile atomic<Integral>* obj, Integral op) noexcept; 404 405template <class Integral> 406 Integral 407 atomic_fetch_and(atomic<Integral>* obj, Integral op) noexcept; 408 409template <class Integral> 410 Integral 411 atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op, 412 memory_order m) noexcept; 413template <class Integral> 414 Integral 415 atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op, 416 memory_order m) noexcept; 417template <class Integral> 418 Integral 419 atomic_fetch_or(volatile atomic<Integral>* obj, Integral op) noexcept; 420 421template <class Integral> 422 Integral 423 atomic_fetch_or(atomic<Integral>* obj, Integral op) noexcept; 424 425template <class Integral> 426 Integral 427 atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op, 428 memory_order m) noexcept; 429template <class Integral> 430 Integral 431 atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op, 432 memory_order m) noexcept; 433template <class Integral> 434 Integral 435 atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op) noexcept; 436 437template <class Integral> 438 Integral 439 atomic_fetch_xor(atomic<Integral>* obj, Integral op) noexcept; 440 441template <class Integral> 442 Integral 443 atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op, 444 memory_order m) noexcept; 445template <class Integral> 446 Integral 447 atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op, 448 memory_order m) noexcept; 449 450template <class T> 451 T* 452 atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op) noexcept; 453 454template <class T> 455 T* 456 atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op) noexcept; 457 458template <class T> 459 T* 460 atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op, 461 memory_order m) noexcept; 462template <class T> 463 T* 464 atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept; 465 466template <class T> 467 T* 468 atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op) noexcept; 469 470template <class T> 471 T* 472 atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op) noexcept; 473 474template <class T> 475 T* 476 atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op, 477 memory_order m) noexcept; 478template <class T> 479 T* 480 atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept; 481 482// Atomics for standard typedef types 483 484typedef atomic<bool> atomic_bool; 485typedef atomic<char> atomic_char; 486typedef atomic<signed char> atomic_schar; 487typedef atomic<unsigned char> atomic_uchar; 488typedef atomic<short> atomic_short; 489typedef atomic<unsigned short> atomic_ushort; 490typedef atomic<int> atomic_int; 491typedef atomic<unsigned int> atomic_uint; 492typedef atomic<long> atomic_long; 493typedef atomic<unsigned long> atomic_ulong; 494typedef atomic<long long> atomic_llong; 495typedef atomic<unsigned long long> atomic_ullong; 496typedef atomic<char16_t> atomic_char16_t; 497typedef atomic<char32_t> atomic_char32_t; 498typedef atomic<wchar_t> atomic_wchar_t; 499 500typedef atomic<int_least8_t> atomic_int_least8_t; 501typedef atomic<uint_least8_t> atomic_uint_least8_t; 502typedef atomic<int_least16_t> atomic_int_least16_t; 503typedef atomic<uint_least16_t> atomic_uint_least16_t; 504typedef atomic<int_least32_t> atomic_int_least32_t; 505typedef atomic<uint_least32_t> atomic_uint_least32_t; 506typedef atomic<int_least64_t> atomic_int_least64_t; 507typedef atomic<uint_least64_t> atomic_uint_least64_t; 508 509typedef atomic<int_fast8_t> atomic_int_fast8_t; 510typedef atomic<uint_fast8_t> atomic_uint_fast8_t; 511typedef atomic<int_fast16_t> atomic_int_fast16_t; 512typedef atomic<uint_fast16_t> atomic_uint_fast16_t; 513typedef atomic<int_fast32_t> atomic_int_fast32_t; 514typedef atomic<uint_fast32_t> atomic_uint_fast32_t; 515typedef atomic<int_fast64_t> atomic_int_fast64_t; 516typedef atomic<uint_fast64_t> atomic_uint_fast64_t; 517 518typedef atomic<int8_t> atomic_int8_t; 519typedef atomic<uint8_t> atomic_uint8_t; 520typedef atomic<int16_t> atomic_int16_t; 521typedef atomic<uint16_t> atomic_uint16_t; 522typedef atomic<int32_t> atomic_int32_t; 523typedef atomic<uint32_t> atomic_uint32_t; 524typedef atomic<int64_t> atomic_int64_t; 525typedef atomic<uint64_t> atomic_uint64_t; 526 527typedef atomic<intptr_t> atomic_intptr_t; 528typedef atomic<uintptr_t> atomic_uintptr_t; 529typedef atomic<size_t> atomic_size_t; 530typedef atomic<ptrdiff_t> atomic_ptrdiff_t; 531typedef atomic<intmax_t> atomic_intmax_t; 532typedef atomic<uintmax_t> atomic_uintmax_t; 533 534// fences 535 536void atomic_thread_fence(memory_order m) noexcept; 537void atomic_signal_fence(memory_order m) noexcept; 538 539} // std 540 541*/ 542 543#include <__config> 544#include <cstddef> 545#include <cstdint> 546#include <type_traits> 547 548#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 549#pragma GCC system_header 550#endif 551 552#ifdef _LIBCPP_HAS_NO_THREADS 553#error <atomic> is not supported on this single threaded system 554#endif 555#if !defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) 556#error <atomic> is not implemented 557#endif 558#ifdef kill_dependency 559#error C++ standard library is incompatible with <stdatomic.h> 560#endif 561 562#if _LIBCPP_STD_VER > 14 563# define __cpp_lib_atomic_is_always_lock_free 201603L 564#endif 565 566#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \ 567 _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \ 568 __m == memory_order_acquire || \ 569 __m == memory_order_acq_rel, \ 570 "memory order argument to atomic operation is invalid") 571 572#define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \ 573 _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \ 574 __m == memory_order_acq_rel, \ 575 "memory order argument to atomic operation is invalid") 576 577#define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \ 578 _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \ 579 __f == memory_order_acq_rel, \ 580 "memory order argument to atomic operation is invalid") 581 582_LIBCPP_BEGIN_NAMESPACE_STD 583 584typedef enum memory_order 585{ 586 memory_order_relaxed, memory_order_consume, memory_order_acquire, 587 memory_order_release, memory_order_acq_rel, memory_order_seq_cst 588} memory_order; 589 590#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) 591namespace __gcc_atomic { 592template <typename _Tp> 593struct __gcc_atomic_t { 594 595#if _GNUC_VER >= 501 596 static_assert(is_trivially_copyable<_Tp>::value, 597 "std::atomic<Tp> requires that 'Tp' be a trivially copyable type"); 598#endif 599 600 _LIBCPP_INLINE_VISIBILITY 601#ifndef _LIBCPP_CXX03_LANG 602 __gcc_atomic_t() _NOEXCEPT = default; 603#else 604 __gcc_atomic_t() _NOEXCEPT : __a_value() {} 605#endif // _LIBCPP_CXX03_LANG 606 _LIBCPP_CONSTEXPR explicit __gcc_atomic_t(_Tp value) _NOEXCEPT 607 : __a_value(value) {} 608 _Tp __a_value; 609}; 610#define _Atomic(x) __gcc_atomic::__gcc_atomic_t<x> 611 612template <typename _Tp> _Tp __create(); 613 614template <typename _Tp, typename _Td> 615typename enable_if<sizeof(_Tp()->__a_value = __create<_Td>()), char>::type 616 __test_atomic_assignable(int); 617template <typename _Tp, typename _Up> 618__two __test_atomic_assignable(...); 619 620template <typename _Tp, typename _Td> 621struct __can_assign { 622 static const bool value = 623 sizeof(__test_atomic_assignable<_Tp, _Td>(1)) == sizeof(char); 624}; 625 626static inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) { 627 // Avoid switch statement to make this a constexpr. 628 return __order == memory_order_relaxed ? __ATOMIC_RELAXED: 629 (__order == memory_order_acquire ? __ATOMIC_ACQUIRE: 630 (__order == memory_order_release ? __ATOMIC_RELEASE: 631 (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST: 632 (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL: 633 __ATOMIC_CONSUME)))); 634} 635 636static inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) { 637 // Avoid switch statement to make this a constexpr. 638 return __order == memory_order_relaxed ? __ATOMIC_RELAXED: 639 (__order == memory_order_acquire ? __ATOMIC_ACQUIRE: 640 (__order == memory_order_release ? __ATOMIC_RELAXED: 641 (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST: 642 (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE: 643 __ATOMIC_CONSUME)))); 644} 645 646} // namespace __gcc_atomic 647 648template <typename _Tp> 649static inline 650typename enable_if< 651 __gcc_atomic::__can_assign<volatile _Atomic(_Tp)*, _Tp>::value>::type 652__c11_atomic_init(volatile _Atomic(_Tp)* __a, _Tp __val) { 653 __a->__a_value = __val; 654} 655 656template <typename _Tp> 657static inline 658typename enable_if< 659 !__gcc_atomic::__can_assign<volatile _Atomic(_Tp)*, _Tp>::value && 660 __gcc_atomic::__can_assign< _Atomic(_Tp)*, _Tp>::value>::type 661__c11_atomic_init(volatile _Atomic(_Tp)* __a, _Tp __val) { 662 // [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because 663 // the default operator= in an object is not volatile, a byte-by-byte copy 664 // is required. 665 volatile char* to = reinterpret_cast<volatile char*>(&__a->__a_value); 666 volatile char* end = to + sizeof(_Tp); 667 char* from = reinterpret_cast<char*>(&__val); 668 while (to != end) { 669 *to++ = *from++; 670 } 671} 672 673template <typename _Tp> 674static inline void __c11_atomic_init(_Atomic(_Tp)* __a, _Tp __val) { 675 __a->__a_value = __val; 676} 677 678static inline void __c11_atomic_thread_fence(memory_order __order) { 679 __atomic_thread_fence(__gcc_atomic::__to_gcc_order(__order)); 680} 681 682static inline void __c11_atomic_signal_fence(memory_order __order) { 683 __atomic_signal_fence(__gcc_atomic::__to_gcc_order(__order)); 684} 685 686template <typename _Tp> 687static inline void __c11_atomic_store(volatile _Atomic(_Tp)* __a, _Tp __val, 688 memory_order __order) { 689 return __atomic_store(&__a->__a_value, &__val, 690 __gcc_atomic::__to_gcc_order(__order)); 691} 692 693template <typename _Tp> 694static inline void __c11_atomic_store(_Atomic(_Tp)* __a, _Tp __val, 695 memory_order __order) { 696 __atomic_store(&__a->__a_value, &__val, 697 __gcc_atomic::__to_gcc_order(__order)); 698} 699 700template <typename _Tp> 701static inline _Tp __c11_atomic_load(const volatile _Atomic(_Tp)* __a, 702 memory_order __order) { 703 _Tp __ret; 704 __atomic_load(&__a->__a_value, &__ret, 705 __gcc_atomic::__to_gcc_order(__order)); 706 return __ret; 707} 708 709template <typename _Tp> 710static inline _Tp __c11_atomic_load(const _Atomic(_Tp)* __a, memory_order __order) { 711 _Tp __ret; 712 __atomic_load(&__a->__a_value, &__ret, 713 __gcc_atomic::__to_gcc_order(__order)); 714 return __ret; 715} 716 717template <typename _Tp> 718static inline _Tp __c11_atomic_exchange(volatile _Atomic(_Tp)* __a, 719 _Tp __value, memory_order __order) { 720 _Tp __ret; 721 __atomic_exchange(&__a->__a_value, &__value, &__ret, 722 __gcc_atomic::__to_gcc_order(__order)); 723 return __ret; 724} 725 726template <typename _Tp> 727static inline _Tp __c11_atomic_exchange(_Atomic(_Tp)* __a, _Tp __value, 728 memory_order __order) { 729 _Tp __ret; 730 __atomic_exchange(&__a->__a_value, &__value, &__ret, 731 __gcc_atomic::__to_gcc_order(__order)); 732 return __ret; 733} 734 735template <typename _Tp> 736static inline bool __c11_atomic_compare_exchange_strong( 737 volatile _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value, 738 memory_order __success, memory_order __failure) { 739 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value, 740 false, 741 __gcc_atomic::__to_gcc_order(__success), 742 __gcc_atomic::__to_gcc_failure_order(__failure)); 743} 744 745template <typename _Tp> 746static inline bool __c11_atomic_compare_exchange_strong( 747 _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value, memory_order __success, 748 memory_order __failure) { 749 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value, 750 false, 751 __gcc_atomic::__to_gcc_order(__success), 752 __gcc_atomic::__to_gcc_failure_order(__failure)); 753} 754 755template <typename _Tp> 756static inline bool __c11_atomic_compare_exchange_weak( 757 volatile _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value, 758 memory_order __success, memory_order __failure) { 759 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value, 760 true, 761 __gcc_atomic::__to_gcc_order(__success), 762 __gcc_atomic::__to_gcc_failure_order(__failure)); 763} 764 765template <typename _Tp> 766static inline bool __c11_atomic_compare_exchange_weak( 767 _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value, memory_order __success, 768 memory_order __failure) { 769 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value, 770 true, 771 __gcc_atomic::__to_gcc_order(__success), 772 __gcc_atomic::__to_gcc_failure_order(__failure)); 773} 774 775template <typename _Tp> 776struct __skip_amt { enum {value = 1}; }; 777 778template <typename _Tp> 779struct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; }; 780 781// FIXME: Haven't figured out what the spec says about using arrays with 782// atomic_fetch_add. Force a failure rather than creating bad behavior. 783template <typename _Tp> 784struct __skip_amt<_Tp[]> { }; 785template <typename _Tp, int n> 786struct __skip_amt<_Tp[n]> { }; 787 788template <typename _Tp, typename _Td> 789static inline _Tp __c11_atomic_fetch_add(volatile _Atomic(_Tp)* __a, 790 _Td __delta, memory_order __order) { 791 return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value, 792 __gcc_atomic::__to_gcc_order(__order)); 793} 794 795template <typename _Tp, typename _Td> 796static inline _Tp __c11_atomic_fetch_add(_Atomic(_Tp)* __a, _Td __delta, 797 memory_order __order) { 798 return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value, 799 __gcc_atomic::__to_gcc_order(__order)); 800} 801 802template <typename _Tp, typename _Td> 803static inline _Tp __c11_atomic_fetch_sub(volatile _Atomic(_Tp)* __a, 804 _Td __delta, memory_order __order) { 805 return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value, 806 __gcc_atomic::__to_gcc_order(__order)); 807} 808 809template <typename _Tp, typename _Td> 810static inline _Tp __c11_atomic_fetch_sub(_Atomic(_Tp)* __a, _Td __delta, 811 memory_order __order) { 812 return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value, 813 __gcc_atomic::__to_gcc_order(__order)); 814} 815 816template <typename _Tp> 817static inline _Tp __c11_atomic_fetch_and(volatile _Atomic(_Tp)* __a, 818 _Tp __pattern, memory_order __order) { 819 return __atomic_fetch_and(&__a->__a_value, __pattern, 820 __gcc_atomic::__to_gcc_order(__order)); 821} 822 823template <typename _Tp> 824static inline _Tp __c11_atomic_fetch_and(_Atomic(_Tp)* __a, 825 _Tp __pattern, memory_order __order) { 826 return __atomic_fetch_and(&__a->__a_value, __pattern, 827 __gcc_atomic::__to_gcc_order(__order)); 828} 829 830template <typename _Tp> 831static inline _Tp __c11_atomic_fetch_or(volatile _Atomic(_Tp)* __a, 832 _Tp __pattern, memory_order __order) { 833 return __atomic_fetch_or(&__a->__a_value, __pattern, 834 __gcc_atomic::__to_gcc_order(__order)); 835} 836 837template <typename _Tp> 838static inline _Tp __c11_atomic_fetch_or(_Atomic(_Tp)* __a, _Tp __pattern, 839 memory_order __order) { 840 return __atomic_fetch_or(&__a->__a_value, __pattern, 841 __gcc_atomic::__to_gcc_order(__order)); 842} 843 844template <typename _Tp> 845static inline _Tp __c11_atomic_fetch_xor(volatile _Atomic(_Tp)* __a, 846 _Tp __pattern, memory_order __order) { 847 return __atomic_fetch_xor(&__a->__a_value, __pattern, 848 __gcc_atomic::__to_gcc_order(__order)); 849} 850 851template <typename _Tp> 852static inline _Tp __c11_atomic_fetch_xor(_Atomic(_Tp)* __a, _Tp __pattern, 853 memory_order __order) { 854 return __atomic_fetch_xor(&__a->__a_value, __pattern, 855 __gcc_atomic::__to_gcc_order(__order)); 856} 857#endif // _LIBCPP_HAS_GCC_ATOMIC_IMP 858 859template <class _Tp> 860inline _LIBCPP_INLINE_VISIBILITY 861_Tp 862kill_dependency(_Tp __y) _NOEXCEPT 863{ 864 return __y; 865} 866 867#if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE) 868# define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE 869# define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE 870# define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE 871# define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE 872# define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE 873# define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE 874# define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE 875# define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE 876# define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE 877# define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE 878#else 879# define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE 880# define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE 881# define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE 882# define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE 883# define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE 884# define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE 885# define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE 886# define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE 887# define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE 888# define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE 889#endif 890 891// general atomic<T> 892 893template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value> 894struct __atomic_base // false 895{ 896 mutable _Atomic(_Tp) __a_; 897 898#if defined(__cpp_lib_atomic_is_always_lock_free) 899 static _LIBCPP_CONSTEXPR bool is_always_lock_free = __atomic_always_lock_free(sizeof(__a_), 0); 900#endif 901 902 _LIBCPP_INLINE_VISIBILITY 903 bool is_lock_free() const volatile _NOEXCEPT 904 { 905#if defined(_LIBCPP_HAS_C_ATOMIC_IMP) 906 return __c11_atomic_is_lock_free(sizeof(_Tp)); 907#else 908 return __atomic_is_lock_free(sizeof(_Tp), 0); 909#endif 910 } 911 _LIBCPP_INLINE_VISIBILITY 912 bool is_lock_free() const _NOEXCEPT 913 {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();} 914 _LIBCPP_INLINE_VISIBILITY 915 void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 916 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) 917 {__c11_atomic_store(&__a_, __d, __m);} 918 _LIBCPP_INLINE_VISIBILITY 919 void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT 920 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) 921 {__c11_atomic_store(&__a_, __d, __m);} 922 _LIBCPP_INLINE_VISIBILITY 923 _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT 924 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) 925 {return __c11_atomic_load(&__a_, __m);} 926 _LIBCPP_INLINE_VISIBILITY 927 _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT 928 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) 929 {return __c11_atomic_load(&__a_, __m);} 930 _LIBCPP_INLINE_VISIBILITY 931 operator _Tp() const volatile _NOEXCEPT {return load();} 932 _LIBCPP_INLINE_VISIBILITY 933 operator _Tp() const _NOEXCEPT {return load();} 934 _LIBCPP_INLINE_VISIBILITY 935 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 936 {return __c11_atomic_exchange(&__a_, __d, __m);} 937 _LIBCPP_INLINE_VISIBILITY 938 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT 939 {return __c11_atomic_exchange(&__a_, __d, __m);} 940 _LIBCPP_INLINE_VISIBILITY 941 bool compare_exchange_weak(_Tp& __e, _Tp __d, 942 memory_order __s, memory_order __f) volatile _NOEXCEPT 943 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) 944 {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);} 945 _LIBCPP_INLINE_VISIBILITY 946 bool compare_exchange_weak(_Tp& __e, _Tp __d, 947 memory_order __s, memory_order __f) _NOEXCEPT 948 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) 949 {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);} 950 _LIBCPP_INLINE_VISIBILITY 951 bool compare_exchange_strong(_Tp& __e, _Tp __d, 952 memory_order __s, memory_order __f) volatile _NOEXCEPT 953 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) 954 {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);} 955 _LIBCPP_INLINE_VISIBILITY 956 bool compare_exchange_strong(_Tp& __e, _Tp __d, 957 memory_order __s, memory_order __f) _NOEXCEPT 958 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) 959 {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);} 960 _LIBCPP_INLINE_VISIBILITY 961 bool compare_exchange_weak(_Tp& __e, _Tp __d, 962 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 963 {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);} 964 _LIBCPP_INLINE_VISIBILITY 965 bool compare_exchange_weak(_Tp& __e, _Tp __d, 966 memory_order __m = memory_order_seq_cst) _NOEXCEPT 967 {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);} 968 _LIBCPP_INLINE_VISIBILITY 969 bool compare_exchange_strong(_Tp& __e, _Tp __d, 970 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 971 {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);} 972 _LIBCPP_INLINE_VISIBILITY 973 bool compare_exchange_strong(_Tp& __e, _Tp __d, 974 memory_order __m = memory_order_seq_cst) _NOEXCEPT 975 {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);} 976 977 _LIBCPP_INLINE_VISIBILITY 978#ifndef _LIBCPP_CXX03_LANG 979 __atomic_base() _NOEXCEPT = default; 980#else 981 __atomic_base() _NOEXCEPT : __a_() {} 982#endif // _LIBCPP_CXX03_LANG 983 984 _LIBCPP_INLINE_VISIBILITY 985 _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {} 986#ifndef _LIBCPP_CXX03_LANG 987 __atomic_base(const __atomic_base&) = delete; 988 __atomic_base& operator=(const __atomic_base&) = delete; 989 __atomic_base& operator=(const __atomic_base&) volatile = delete; 990#else 991private: 992 __atomic_base(const __atomic_base&); 993 __atomic_base& operator=(const __atomic_base&); 994 __atomic_base& operator=(const __atomic_base&) volatile; 995#endif 996}; 997 998#if defined(__cpp_lib_atomic_is_always_lock_free) 999template <class _Tp, bool __b> 1000_LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free; 1001#endif 1002 1003// atomic<Integral> 1004 1005template <class _Tp> 1006struct __atomic_base<_Tp, true> 1007 : public __atomic_base<_Tp, false> 1008{ 1009 typedef __atomic_base<_Tp, false> __base; 1010 _LIBCPP_INLINE_VISIBILITY 1011 __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT 1012 _LIBCPP_INLINE_VISIBILITY 1013 _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {} 1014 1015 _LIBCPP_INLINE_VISIBILITY 1016 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1017 {return __c11_atomic_fetch_add(&this->__a_, __op, __m);} 1018 _LIBCPP_INLINE_VISIBILITY 1019 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 1020 {return __c11_atomic_fetch_add(&this->__a_, __op, __m);} 1021 _LIBCPP_INLINE_VISIBILITY 1022 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1023 {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);} 1024 _LIBCPP_INLINE_VISIBILITY 1025 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 1026 {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);} 1027 _LIBCPP_INLINE_VISIBILITY 1028 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1029 {return __c11_atomic_fetch_and(&this->__a_, __op, __m);} 1030 _LIBCPP_INLINE_VISIBILITY 1031 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 1032 {return __c11_atomic_fetch_and(&this->__a_, __op, __m);} 1033 _LIBCPP_INLINE_VISIBILITY 1034 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1035 {return __c11_atomic_fetch_or(&this->__a_, __op, __m);} 1036 _LIBCPP_INLINE_VISIBILITY 1037 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 1038 {return __c11_atomic_fetch_or(&this->__a_, __op, __m);} 1039 _LIBCPP_INLINE_VISIBILITY 1040 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1041 {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);} 1042 _LIBCPP_INLINE_VISIBILITY 1043 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 1044 {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);} 1045 1046 _LIBCPP_INLINE_VISIBILITY 1047 _Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));} 1048 _LIBCPP_INLINE_VISIBILITY 1049 _Tp operator++(int) _NOEXCEPT {return fetch_add(_Tp(1));} 1050 _LIBCPP_INLINE_VISIBILITY 1051 _Tp operator--(int) volatile _NOEXCEPT {return fetch_sub(_Tp(1));} 1052 _LIBCPP_INLINE_VISIBILITY 1053 _Tp operator--(int) _NOEXCEPT {return fetch_sub(_Tp(1));} 1054 _LIBCPP_INLINE_VISIBILITY 1055 _Tp operator++() volatile _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);} 1056 _LIBCPP_INLINE_VISIBILITY 1057 _Tp operator++() _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);} 1058 _LIBCPP_INLINE_VISIBILITY 1059 _Tp operator--() volatile _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);} 1060 _LIBCPP_INLINE_VISIBILITY 1061 _Tp operator--() _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);} 1062 _LIBCPP_INLINE_VISIBILITY 1063 _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;} 1064 _LIBCPP_INLINE_VISIBILITY 1065 _Tp operator+=(_Tp __op) _NOEXCEPT {return fetch_add(__op) + __op;} 1066 _LIBCPP_INLINE_VISIBILITY 1067 _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;} 1068 _LIBCPP_INLINE_VISIBILITY 1069 _Tp operator-=(_Tp __op) _NOEXCEPT {return fetch_sub(__op) - __op;} 1070 _LIBCPP_INLINE_VISIBILITY 1071 _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;} 1072 _LIBCPP_INLINE_VISIBILITY 1073 _Tp operator&=(_Tp __op) _NOEXCEPT {return fetch_and(__op) & __op;} 1074 _LIBCPP_INLINE_VISIBILITY 1075 _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;} 1076 _LIBCPP_INLINE_VISIBILITY 1077 _Tp operator|=(_Tp __op) _NOEXCEPT {return fetch_or(__op) | __op;} 1078 _LIBCPP_INLINE_VISIBILITY 1079 _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;} 1080 _LIBCPP_INLINE_VISIBILITY 1081 _Tp operator^=(_Tp __op) _NOEXCEPT {return fetch_xor(__op) ^ __op;} 1082}; 1083 1084// atomic<T> 1085 1086template <class _Tp> 1087struct atomic 1088 : public __atomic_base<_Tp> 1089{ 1090 typedef __atomic_base<_Tp> __base; 1091 _LIBCPP_INLINE_VISIBILITY 1092 atomic() _NOEXCEPT _LIBCPP_DEFAULT 1093 _LIBCPP_INLINE_VISIBILITY 1094 _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {} 1095 1096 _LIBCPP_INLINE_VISIBILITY 1097 _Tp operator=(_Tp __d) volatile _NOEXCEPT 1098 {__base::store(__d); return __d;} 1099 _LIBCPP_INLINE_VISIBILITY 1100 _Tp operator=(_Tp __d) _NOEXCEPT 1101 {__base::store(__d); return __d;} 1102}; 1103 1104// atomic<T*> 1105 1106template <class _Tp> 1107struct atomic<_Tp*> 1108 : public __atomic_base<_Tp*> 1109{ 1110 typedef __atomic_base<_Tp*> __base; 1111 _LIBCPP_INLINE_VISIBILITY 1112 atomic() _NOEXCEPT _LIBCPP_DEFAULT 1113 _LIBCPP_INLINE_VISIBILITY 1114 _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {} 1115 1116 _LIBCPP_INLINE_VISIBILITY 1117 _Tp* operator=(_Tp* __d) volatile _NOEXCEPT 1118 {__base::store(__d); return __d;} 1119 _LIBCPP_INLINE_VISIBILITY 1120 _Tp* operator=(_Tp* __d) _NOEXCEPT 1121 {__base::store(__d); return __d;} 1122 1123 _LIBCPP_INLINE_VISIBILITY 1124 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) 1125 volatile _NOEXCEPT 1126 {return __c11_atomic_fetch_add(&this->__a_, __op, __m);} 1127 _LIBCPP_INLINE_VISIBILITY 1128 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 1129 {return __c11_atomic_fetch_add(&this->__a_, __op, __m);} 1130 _LIBCPP_INLINE_VISIBILITY 1131 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) 1132 volatile _NOEXCEPT 1133 {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);} 1134 _LIBCPP_INLINE_VISIBILITY 1135 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 1136 {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);} 1137 1138 _LIBCPP_INLINE_VISIBILITY 1139 _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);} 1140 _LIBCPP_INLINE_VISIBILITY 1141 _Tp* operator++(int) _NOEXCEPT {return fetch_add(1);} 1142 _LIBCPP_INLINE_VISIBILITY 1143 _Tp* operator--(int) volatile _NOEXCEPT {return fetch_sub(1);} 1144 _LIBCPP_INLINE_VISIBILITY 1145 _Tp* operator--(int) _NOEXCEPT {return fetch_sub(1);} 1146 _LIBCPP_INLINE_VISIBILITY 1147 _Tp* operator++() volatile _NOEXCEPT {return fetch_add(1) + 1;} 1148 _LIBCPP_INLINE_VISIBILITY 1149 _Tp* operator++() _NOEXCEPT {return fetch_add(1) + 1;} 1150 _LIBCPP_INLINE_VISIBILITY 1151 _Tp* operator--() volatile _NOEXCEPT {return fetch_sub(1) - 1;} 1152 _LIBCPP_INLINE_VISIBILITY 1153 _Tp* operator--() _NOEXCEPT {return fetch_sub(1) - 1;} 1154 _LIBCPP_INLINE_VISIBILITY 1155 _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;} 1156 _LIBCPP_INLINE_VISIBILITY 1157 _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT {return fetch_add(__op) + __op;} 1158 _LIBCPP_INLINE_VISIBILITY 1159 _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;} 1160 _LIBCPP_INLINE_VISIBILITY 1161 _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;} 1162}; 1163 1164// atomic_is_lock_free 1165 1166template <class _Tp> 1167inline _LIBCPP_INLINE_VISIBILITY 1168bool 1169atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT 1170{ 1171 return __o->is_lock_free(); 1172} 1173 1174template <class _Tp> 1175inline _LIBCPP_INLINE_VISIBILITY 1176bool 1177atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT 1178{ 1179 return __o->is_lock_free(); 1180} 1181 1182// atomic_init 1183 1184template <class _Tp> 1185inline _LIBCPP_INLINE_VISIBILITY 1186void 1187atomic_init(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 1188{ 1189 __c11_atomic_init(&__o->__a_, __d); 1190} 1191 1192template <class _Tp> 1193inline _LIBCPP_INLINE_VISIBILITY 1194void 1195atomic_init(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 1196{ 1197 __c11_atomic_init(&__o->__a_, __d); 1198} 1199 1200// atomic_store 1201 1202template <class _Tp> 1203inline _LIBCPP_INLINE_VISIBILITY 1204void 1205atomic_store(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 1206{ 1207 __o->store(__d); 1208} 1209 1210template <class _Tp> 1211inline _LIBCPP_INLINE_VISIBILITY 1212void 1213atomic_store(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 1214{ 1215 __o->store(__d); 1216} 1217 1218// atomic_store_explicit 1219 1220template <class _Tp> 1221inline _LIBCPP_INLINE_VISIBILITY 1222void 1223atomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT 1224 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) 1225{ 1226 __o->store(__d, __m); 1227} 1228 1229template <class _Tp> 1230inline _LIBCPP_INLINE_VISIBILITY 1231void 1232atomic_store_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT 1233 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) 1234{ 1235 __o->store(__d, __m); 1236} 1237 1238// atomic_load 1239 1240template <class _Tp> 1241inline _LIBCPP_INLINE_VISIBILITY 1242_Tp 1243atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT 1244{ 1245 return __o->load(); 1246} 1247 1248template <class _Tp> 1249inline _LIBCPP_INLINE_VISIBILITY 1250_Tp 1251atomic_load(const atomic<_Tp>* __o) _NOEXCEPT 1252{ 1253 return __o->load(); 1254} 1255 1256// atomic_load_explicit 1257 1258template <class _Tp> 1259inline _LIBCPP_INLINE_VISIBILITY 1260_Tp 1261atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT 1262 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) 1263{ 1264 return __o->load(__m); 1265} 1266 1267template <class _Tp> 1268inline _LIBCPP_INLINE_VISIBILITY 1269_Tp 1270atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT 1271 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) 1272{ 1273 return __o->load(__m); 1274} 1275 1276// atomic_exchange 1277 1278template <class _Tp> 1279inline _LIBCPP_INLINE_VISIBILITY 1280_Tp 1281atomic_exchange(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 1282{ 1283 return __o->exchange(__d); 1284} 1285 1286template <class _Tp> 1287inline _LIBCPP_INLINE_VISIBILITY 1288_Tp 1289atomic_exchange(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 1290{ 1291 return __o->exchange(__d); 1292} 1293 1294// atomic_exchange_explicit 1295 1296template <class _Tp> 1297inline _LIBCPP_INLINE_VISIBILITY 1298_Tp 1299atomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT 1300{ 1301 return __o->exchange(__d, __m); 1302} 1303 1304template <class _Tp> 1305inline _LIBCPP_INLINE_VISIBILITY 1306_Tp 1307atomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT 1308{ 1309 return __o->exchange(__d, __m); 1310} 1311 1312// atomic_compare_exchange_weak 1313 1314template <class _Tp> 1315inline _LIBCPP_INLINE_VISIBILITY 1316bool 1317atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT 1318{ 1319 return __o->compare_exchange_weak(*__e, __d); 1320} 1321 1322template <class _Tp> 1323inline _LIBCPP_INLINE_VISIBILITY 1324bool 1325atomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT 1326{ 1327 return __o->compare_exchange_weak(*__e, __d); 1328} 1329 1330// atomic_compare_exchange_strong 1331 1332template <class _Tp> 1333inline _LIBCPP_INLINE_VISIBILITY 1334bool 1335atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT 1336{ 1337 return __o->compare_exchange_strong(*__e, __d); 1338} 1339 1340template <class _Tp> 1341inline _LIBCPP_INLINE_VISIBILITY 1342bool 1343atomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT 1344{ 1345 return __o->compare_exchange_strong(*__e, __d); 1346} 1347 1348// atomic_compare_exchange_weak_explicit 1349 1350template <class _Tp> 1351inline _LIBCPP_INLINE_VISIBILITY 1352bool 1353atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e, 1354 _Tp __d, 1355 memory_order __s, memory_order __f) _NOEXCEPT 1356 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) 1357{ 1358 return __o->compare_exchange_weak(*__e, __d, __s, __f); 1359} 1360 1361template <class _Tp> 1362inline _LIBCPP_INLINE_VISIBILITY 1363bool 1364atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d, 1365 memory_order __s, memory_order __f) _NOEXCEPT 1366 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) 1367{ 1368 return __o->compare_exchange_weak(*__e, __d, __s, __f); 1369} 1370 1371// atomic_compare_exchange_strong_explicit 1372 1373template <class _Tp> 1374inline _LIBCPP_INLINE_VISIBILITY 1375bool 1376atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o, 1377 _Tp* __e, _Tp __d, 1378 memory_order __s, memory_order __f) _NOEXCEPT 1379 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) 1380{ 1381 return __o->compare_exchange_strong(*__e, __d, __s, __f); 1382} 1383 1384template <class _Tp> 1385inline _LIBCPP_INLINE_VISIBILITY 1386bool 1387atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e, 1388 _Tp __d, 1389 memory_order __s, memory_order __f) _NOEXCEPT 1390 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) 1391{ 1392 return __o->compare_exchange_strong(*__e, __d, __s, __f); 1393} 1394 1395// atomic_fetch_add 1396 1397template <class _Tp> 1398inline _LIBCPP_INLINE_VISIBILITY 1399typename enable_if 1400< 1401 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1402 _Tp 1403>::type 1404atomic_fetch_add(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1405{ 1406 return __o->fetch_add(__op); 1407} 1408 1409template <class _Tp> 1410inline _LIBCPP_INLINE_VISIBILITY 1411typename enable_if 1412< 1413 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1414 _Tp 1415>::type 1416atomic_fetch_add(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1417{ 1418 return __o->fetch_add(__op); 1419} 1420 1421template <class _Tp> 1422inline _LIBCPP_INLINE_VISIBILITY 1423_Tp* 1424atomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT 1425{ 1426 return __o->fetch_add(__op); 1427} 1428 1429template <class _Tp> 1430inline _LIBCPP_INLINE_VISIBILITY 1431_Tp* 1432atomic_fetch_add(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT 1433{ 1434 return __o->fetch_add(__op); 1435} 1436 1437// atomic_fetch_add_explicit 1438 1439template <class _Tp> 1440inline _LIBCPP_INLINE_VISIBILITY 1441typename enable_if 1442< 1443 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1444 _Tp 1445>::type 1446atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1447{ 1448 return __o->fetch_add(__op, __m); 1449} 1450 1451template <class _Tp> 1452inline _LIBCPP_INLINE_VISIBILITY 1453typename enable_if 1454< 1455 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1456 _Tp 1457>::type 1458atomic_fetch_add_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1459{ 1460 return __o->fetch_add(__op, __m); 1461} 1462 1463template <class _Tp> 1464inline _LIBCPP_INLINE_VISIBILITY 1465_Tp* 1466atomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op, 1467 memory_order __m) _NOEXCEPT 1468{ 1469 return __o->fetch_add(__op, __m); 1470} 1471 1472template <class _Tp> 1473inline _LIBCPP_INLINE_VISIBILITY 1474_Tp* 1475atomic_fetch_add_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT 1476{ 1477 return __o->fetch_add(__op, __m); 1478} 1479 1480// atomic_fetch_sub 1481 1482template <class _Tp> 1483inline _LIBCPP_INLINE_VISIBILITY 1484typename enable_if 1485< 1486 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1487 _Tp 1488>::type 1489atomic_fetch_sub(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1490{ 1491 return __o->fetch_sub(__op); 1492} 1493 1494template <class _Tp> 1495inline _LIBCPP_INLINE_VISIBILITY 1496typename enable_if 1497< 1498 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1499 _Tp 1500>::type 1501atomic_fetch_sub(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1502{ 1503 return __o->fetch_sub(__op); 1504} 1505 1506template <class _Tp> 1507inline _LIBCPP_INLINE_VISIBILITY 1508_Tp* 1509atomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT 1510{ 1511 return __o->fetch_sub(__op); 1512} 1513 1514template <class _Tp> 1515inline _LIBCPP_INLINE_VISIBILITY 1516_Tp* 1517atomic_fetch_sub(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT 1518{ 1519 return __o->fetch_sub(__op); 1520} 1521 1522// atomic_fetch_sub_explicit 1523 1524template <class _Tp> 1525inline _LIBCPP_INLINE_VISIBILITY 1526typename enable_if 1527< 1528 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1529 _Tp 1530>::type 1531atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1532{ 1533 return __o->fetch_sub(__op, __m); 1534} 1535 1536template <class _Tp> 1537inline _LIBCPP_INLINE_VISIBILITY 1538typename enable_if 1539< 1540 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1541 _Tp 1542>::type 1543atomic_fetch_sub_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1544{ 1545 return __o->fetch_sub(__op, __m); 1546} 1547 1548template <class _Tp> 1549inline _LIBCPP_INLINE_VISIBILITY 1550_Tp* 1551atomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op, 1552 memory_order __m) _NOEXCEPT 1553{ 1554 return __o->fetch_sub(__op, __m); 1555} 1556 1557template <class _Tp> 1558inline _LIBCPP_INLINE_VISIBILITY 1559_Tp* 1560atomic_fetch_sub_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT 1561{ 1562 return __o->fetch_sub(__op, __m); 1563} 1564 1565// atomic_fetch_and 1566 1567template <class _Tp> 1568inline _LIBCPP_INLINE_VISIBILITY 1569typename enable_if 1570< 1571 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1572 _Tp 1573>::type 1574atomic_fetch_and(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1575{ 1576 return __o->fetch_and(__op); 1577} 1578 1579template <class _Tp> 1580inline _LIBCPP_INLINE_VISIBILITY 1581typename enable_if 1582< 1583 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1584 _Tp 1585>::type 1586atomic_fetch_and(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1587{ 1588 return __o->fetch_and(__op); 1589} 1590 1591// atomic_fetch_and_explicit 1592 1593template <class _Tp> 1594inline _LIBCPP_INLINE_VISIBILITY 1595typename enable_if 1596< 1597 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1598 _Tp 1599>::type 1600atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1601{ 1602 return __o->fetch_and(__op, __m); 1603} 1604 1605template <class _Tp> 1606inline _LIBCPP_INLINE_VISIBILITY 1607typename enable_if 1608< 1609 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1610 _Tp 1611>::type 1612atomic_fetch_and_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1613{ 1614 return __o->fetch_and(__op, __m); 1615} 1616 1617// atomic_fetch_or 1618 1619template <class _Tp> 1620inline _LIBCPP_INLINE_VISIBILITY 1621typename enable_if 1622< 1623 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1624 _Tp 1625>::type 1626atomic_fetch_or(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1627{ 1628 return __o->fetch_or(__op); 1629} 1630 1631template <class _Tp> 1632inline _LIBCPP_INLINE_VISIBILITY 1633typename enable_if 1634< 1635 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1636 _Tp 1637>::type 1638atomic_fetch_or(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1639{ 1640 return __o->fetch_or(__op); 1641} 1642 1643// atomic_fetch_or_explicit 1644 1645template <class _Tp> 1646inline _LIBCPP_INLINE_VISIBILITY 1647typename enable_if 1648< 1649 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1650 _Tp 1651>::type 1652atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1653{ 1654 return __o->fetch_or(__op, __m); 1655} 1656 1657template <class _Tp> 1658inline _LIBCPP_INLINE_VISIBILITY 1659typename enable_if 1660< 1661 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1662 _Tp 1663>::type 1664atomic_fetch_or_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1665{ 1666 return __o->fetch_or(__op, __m); 1667} 1668 1669// atomic_fetch_xor 1670 1671template <class _Tp> 1672inline _LIBCPP_INLINE_VISIBILITY 1673typename enable_if 1674< 1675 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1676 _Tp 1677>::type 1678atomic_fetch_xor(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1679{ 1680 return __o->fetch_xor(__op); 1681} 1682 1683template <class _Tp> 1684inline _LIBCPP_INLINE_VISIBILITY 1685typename enable_if 1686< 1687 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1688 _Tp 1689>::type 1690atomic_fetch_xor(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1691{ 1692 return __o->fetch_xor(__op); 1693} 1694 1695// atomic_fetch_xor_explicit 1696 1697template <class _Tp> 1698inline _LIBCPP_INLINE_VISIBILITY 1699typename enable_if 1700< 1701 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1702 _Tp 1703>::type 1704atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1705{ 1706 return __o->fetch_xor(__op, __m); 1707} 1708 1709template <class _Tp> 1710inline _LIBCPP_INLINE_VISIBILITY 1711typename enable_if 1712< 1713 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1714 _Tp 1715>::type 1716atomic_fetch_xor_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1717{ 1718 return __o->fetch_xor(__op, __m); 1719} 1720 1721// flag type and operations 1722 1723typedef struct atomic_flag 1724{ 1725 _Atomic(bool) __a_; 1726 1727 _LIBCPP_INLINE_VISIBILITY 1728 bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1729 {return __c11_atomic_exchange(&__a_, true, __m);} 1730 _LIBCPP_INLINE_VISIBILITY 1731 bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT 1732 {return __c11_atomic_exchange(&__a_, true, __m);} 1733 _LIBCPP_INLINE_VISIBILITY 1734 void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1735 {__c11_atomic_store(&__a_, false, __m);} 1736 _LIBCPP_INLINE_VISIBILITY 1737 void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT 1738 {__c11_atomic_store(&__a_, false, __m);} 1739 1740 _LIBCPP_INLINE_VISIBILITY 1741#ifndef _LIBCPP_CXX03_LANG 1742 atomic_flag() _NOEXCEPT = default; 1743#else 1744 atomic_flag() _NOEXCEPT : __a_() {} 1745#endif // _LIBCPP_CXX03_LANG 1746 1747 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 1748 atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION 1749 1750#ifndef _LIBCPP_CXX03_LANG 1751 atomic_flag(const atomic_flag&) = delete; 1752 atomic_flag& operator=(const atomic_flag&) = delete; 1753 atomic_flag& operator=(const atomic_flag&) volatile = delete; 1754#else 1755private: 1756 atomic_flag(const atomic_flag&); 1757 atomic_flag& operator=(const atomic_flag&); 1758 atomic_flag& operator=(const atomic_flag&) volatile; 1759#endif 1760} atomic_flag; 1761 1762inline _LIBCPP_INLINE_VISIBILITY 1763bool 1764atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT 1765{ 1766 return __o->test_and_set(); 1767} 1768 1769inline _LIBCPP_INLINE_VISIBILITY 1770bool 1771atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT 1772{ 1773 return __o->test_and_set(); 1774} 1775 1776inline _LIBCPP_INLINE_VISIBILITY 1777bool 1778atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT 1779{ 1780 return __o->test_and_set(__m); 1781} 1782 1783inline _LIBCPP_INLINE_VISIBILITY 1784bool 1785atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT 1786{ 1787 return __o->test_and_set(__m); 1788} 1789 1790inline _LIBCPP_INLINE_VISIBILITY 1791void 1792atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT 1793{ 1794 __o->clear(); 1795} 1796 1797inline _LIBCPP_INLINE_VISIBILITY 1798void 1799atomic_flag_clear(atomic_flag* __o) _NOEXCEPT 1800{ 1801 __o->clear(); 1802} 1803 1804inline _LIBCPP_INLINE_VISIBILITY 1805void 1806atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT 1807{ 1808 __o->clear(__m); 1809} 1810 1811inline _LIBCPP_INLINE_VISIBILITY 1812void 1813atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT 1814{ 1815 __o->clear(__m); 1816} 1817 1818// fences 1819 1820inline _LIBCPP_INLINE_VISIBILITY 1821void 1822atomic_thread_fence(memory_order __m) _NOEXCEPT 1823{ 1824 __c11_atomic_thread_fence(__m); 1825} 1826 1827inline _LIBCPP_INLINE_VISIBILITY 1828void 1829atomic_signal_fence(memory_order __m) _NOEXCEPT 1830{ 1831 __c11_atomic_signal_fence(__m); 1832} 1833 1834// Atomics for standard typedef types 1835 1836typedef atomic<bool> atomic_bool; 1837typedef atomic<char> atomic_char; 1838typedef atomic<signed char> atomic_schar; 1839typedef atomic<unsigned char> atomic_uchar; 1840typedef atomic<short> atomic_short; 1841typedef atomic<unsigned short> atomic_ushort; 1842typedef atomic<int> atomic_int; 1843typedef atomic<unsigned int> atomic_uint; 1844typedef atomic<long> atomic_long; 1845typedef atomic<unsigned long> atomic_ulong; 1846typedef atomic<long long> atomic_llong; 1847typedef atomic<unsigned long long> atomic_ullong; 1848typedef atomic<char16_t> atomic_char16_t; 1849typedef atomic<char32_t> atomic_char32_t; 1850typedef atomic<wchar_t> atomic_wchar_t; 1851 1852typedef atomic<int_least8_t> atomic_int_least8_t; 1853typedef atomic<uint_least8_t> atomic_uint_least8_t; 1854typedef atomic<int_least16_t> atomic_int_least16_t; 1855typedef atomic<uint_least16_t> atomic_uint_least16_t; 1856typedef atomic<int_least32_t> atomic_int_least32_t; 1857typedef atomic<uint_least32_t> atomic_uint_least32_t; 1858typedef atomic<int_least64_t> atomic_int_least64_t; 1859typedef atomic<uint_least64_t> atomic_uint_least64_t; 1860 1861typedef atomic<int_fast8_t> atomic_int_fast8_t; 1862typedef atomic<uint_fast8_t> atomic_uint_fast8_t; 1863typedef atomic<int_fast16_t> atomic_int_fast16_t; 1864typedef atomic<uint_fast16_t> atomic_uint_fast16_t; 1865typedef atomic<int_fast32_t> atomic_int_fast32_t; 1866typedef atomic<uint_fast32_t> atomic_uint_fast32_t; 1867typedef atomic<int_fast64_t> atomic_int_fast64_t; 1868typedef atomic<uint_fast64_t> atomic_uint_fast64_t; 1869 1870typedef atomic< int8_t> atomic_int8_t; 1871typedef atomic<uint8_t> atomic_uint8_t; 1872typedef atomic< int16_t> atomic_int16_t; 1873typedef atomic<uint16_t> atomic_uint16_t; 1874typedef atomic< int32_t> atomic_int32_t; 1875typedef atomic<uint32_t> atomic_uint32_t; 1876typedef atomic< int64_t> atomic_int64_t; 1877typedef atomic<uint64_t> atomic_uint64_t; 1878 1879typedef atomic<intptr_t> atomic_intptr_t; 1880typedef atomic<uintptr_t> atomic_uintptr_t; 1881typedef atomic<size_t> atomic_size_t; 1882typedef atomic<ptrdiff_t> atomic_ptrdiff_t; 1883typedef atomic<intmax_t> atomic_intmax_t; 1884typedef atomic<uintmax_t> atomic_uintmax_t; 1885 1886#define ATOMIC_FLAG_INIT {false} 1887#define ATOMIC_VAR_INIT(__v) {__v} 1888 1889_LIBCPP_END_NAMESPACE_STD 1890 1891#endif // _LIBCPP_ATOMIC 1892