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