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 533#if !__has_feature(cxx_atomic) 534#error <atomic> is not implemented 535#else 536 537typedef enum memory_order 538{ 539 memory_order_relaxed, memory_order_consume, memory_order_acquire, 540 memory_order_release, memory_order_acq_rel, memory_order_seq_cst 541} memory_order; 542 543template <class _Tp> 544inline _LIBCPP_INLINE_VISIBILITY 545_Tp 546kill_dependency(_Tp __y) 547{ 548 return __y; 549} 550 551// general atomic<T> 552 553template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value> 554struct __atomic_base // false 555{ 556 _Tp __a_; 557 558 _LIBCPP_INLINE_VISIBILITY 559 bool is_lock_free() const volatile 560 {return __atomic_is_lock_free(_Tp());} 561 _LIBCPP_INLINE_VISIBILITY 562 bool is_lock_free() const 563 {return __atomic_is_lock_free(_Tp());} 564 _LIBCPP_INLINE_VISIBILITY 565 void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile 566 {__atomic_store(&__a_, __d, __m);} 567 _LIBCPP_INLINE_VISIBILITY 568 void store(_Tp __d, memory_order __m = memory_order_seq_cst) 569 {__atomic_store(&__a_, __d, __m);} 570 _LIBCPP_INLINE_VISIBILITY 571 _Tp load(memory_order __m = memory_order_seq_cst) const volatile 572 {return __atomic_load(&__a_, __m);} 573 _LIBCPP_INLINE_VISIBILITY 574 _Tp load(memory_order __m = memory_order_seq_cst) const 575 {return __atomic_load(&__a_, __m);} 576 _LIBCPP_INLINE_VISIBILITY 577 operator _Tp() const volatile {return load();} 578 _LIBCPP_INLINE_VISIBILITY 579 operator _Tp() const {return load();} 580 _LIBCPP_INLINE_VISIBILITY 581 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile 582 {return __atomic_exchange(&__a_, __d, __m);} 583 _LIBCPP_INLINE_VISIBILITY 584 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) 585 {return __atomic_exchange(&__a_, __d, __m);} 586 _LIBCPP_INLINE_VISIBILITY 587 bool compare_exchange_weak(_Tp& __e, _Tp __d, 588 memory_order __s, memory_order __f) volatile 589 {return __atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);} 590 _LIBCPP_INLINE_VISIBILITY 591 bool compare_exchange_weak(_Tp& __e, _Tp __d, 592 memory_order __s, memory_order __f) 593 {return __atomic_compare_exchange_weak(&__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) volatile 597 {return __atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);} 598 _LIBCPP_INLINE_VISIBILITY 599 bool compare_exchange_strong(_Tp& __e, _Tp __d, 600 memory_order __s, memory_order __f) 601 {return __atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);} 602 _LIBCPP_INLINE_VISIBILITY 603 bool compare_exchange_weak(_Tp& __e, _Tp __d, 604 memory_order __m = memory_order_seq_cst) volatile 605 {return __atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);} 606 _LIBCPP_INLINE_VISIBILITY 607 bool compare_exchange_weak(_Tp& __e, _Tp __d, 608 memory_order __m = memory_order_seq_cst) 609 {return __atomic_compare_exchange_weak(&__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) volatile 613 {return __atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);} 614 _LIBCPP_INLINE_VISIBILITY 615 bool compare_exchange_strong(_Tp& __e, _Tp __d, 616 memory_order __m = memory_order_seq_cst) 617 {return __atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);} 618 619 _LIBCPP_INLINE_VISIBILITY 620 __atomic_base() {} // = default; 621 _LIBCPP_INLINE_VISIBILITY 622 /*constexpr*/ __atomic_base(_Tp __d) : __a_(__d) {} 623#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS 624 __atomic_base(const __atomic_base&) = delete; 625 __atomic_base& operator=(const __atomic_base&) = delete; 626 __atomic_base& operator=(const __atomic_base&) volatile = delete; 627#else // _LIBCPP_HAS_NO_DELETED_FUNCTIONS 628private: 629 __atomic_base(const __atomic_base&); 630 __atomic_base& operator=(const __atomic_base&); 631 __atomic_base& operator=(const __atomic_base&) volatile; 632#endif // _LIBCPP_HAS_NO_DELETED_FUNCTIONS 633}; 634 635// atomic<Integral> 636 637template <class _Tp> 638struct __atomic_base<_Tp, true> 639 : public __atomic_base<_Tp, false> 640{ 641 typedef __atomic_base<_Tp, false> __base; 642 _LIBCPP_INLINE_VISIBILITY 643 __atomic_base() {} // = default; 644 _LIBCPP_INLINE_VISIBILITY 645 /*constexpr*/ __atomic_base(_Tp __d) : __base(__d) {} 646 647 _LIBCPP_INLINE_VISIBILITY 648 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile 649 {return __atomic_fetch_add(&this->__a_, __op, __m);} 650 _LIBCPP_INLINE_VISIBILITY 651 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) 652 {return __atomic_fetch_add(&this->__a_, __op, __m);} 653 _LIBCPP_INLINE_VISIBILITY 654 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile 655 {return __atomic_fetch_sub(&this->__a_, __op, __m);} 656 _LIBCPP_INLINE_VISIBILITY 657 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) 658 {return __atomic_fetch_sub(&this->__a_, __op, __m);} 659 _LIBCPP_INLINE_VISIBILITY 660 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile 661 {return __atomic_fetch_and(&this->__a_, __op, __m);} 662 _LIBCPP_INLINE_VISIBILITY 663 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) 664 {return __atomic_fetch_and(&this->__a_, __op, __m);} 665 _LIBCPP_INLINE_VISIBILITY 666 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile 667 {return __atomic_fetch_or(&this->__a_, __op, __m);} 668 _LIBCPP_INLINE_VISIBILITY 669 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) 670 {return __atomic_fetch_or(&this->__a_, __op, __m);} 671 _LIBCPP_INLINE_VISIBILITY 672 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile 673 {return __atomic_fetch_xor(&this->__a_, __op, __m);} 674 _LIBCPP_INLINE_VISIBILITY 675 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) 676 {return __atomic_fetch_xor(&this->__a_, __op, __m);} 677 678 _LIBCPP_INLINE_VISIBILITY 679 _Tp operator++(int) volatile {return fetch_add(_Tp(1));} 680 _LIBCPP_INLINE_VISIBILITY 681 _Tp operator++(int) {return fetch_add(_Tp(1));} 682 _LIBCPP_INLINE_VISIBILITY 683 _Tp operator--(int) volatile {return fetch_sub(_Tp(1));} 684 _LIBCPP_INLINE_VISIBILITY 685 _Tp operator--(int) {return fetch_sub(_Tp(1));} 686 _LIBCPP_INLINE_VISIBILITY 687 _Tp operator++() volatile {return fetch_add(_Tp(1)) + _Tp(1);} 688 _LIBCPP_INLINE_VISIBILITY 689 _Tp operator++() {return fetch_add(_Tp(1)) + _Tp(1);} 690 _LIBCPP_INLINE_VISIBILITY 691 _Tp operator--() volatile {return fetch_sub(_Tp(1)) - _Tp(1);} 692 _LIBCPP_INLINE_VISIBILITY 693 _Tp operator--() {return fetch_sub(_Tp(1)) - _Tp(1);} 694 _LIBCPP_INLINE_VISIBILITY 695 _Tp operator+=(_Tp __op) volatile {return fetch_add(__op) + __op;} 696 _LIBCPP_INLINE_VISIBILITY 697 _Tp operator+=(_Tp __op) {return fetch_add(__op) + __op;} 698 _LIBCPP_INLINE_VISIBILITY 699 _Tp operator-=(_Tp __op) volatile {return fetch_sub(__op) - __op;} 700 _LIBCPP_INLINE_VISIBILITY 701 _Tp operator-=(_Tp __op) {return fetch_sub(__op) - __op;} 702 _LIBCPP_INLINE_VISIBILITY 703 _Tp operator&=(_Tp __op) volatile {return fetch_and(__op) & __op;} 704 _LIBCPP_INLINE_VISIBILITY 705 _Tp operator&=(_Tp __op) {return fetch_and(__op) & __op;} 706 _LIBCPP_INLINE_VISIBILITY 707 _Tp operator|=(_Tp __op) volatile {return fetch_or(__op) | __op;} 708 _LIBCPP_INLINE_VISIBILITY 709 _Tp operator|=(_Tp __op) {return fetch_or(__op) | __op;} 710 _LIBCPP_INLINE_VISIBILITY 711 _Tp operator^=(_Tp __op) volatile {return fetch_xor(__op) ^ __op;} 712 _LIBCPP_INLINE_VISIBILITY 713 _Tp operator^=(_Tp __op) {return fetch_xor(__op) ^ __op;} 714}; 715 716// atomic<T> 717 718template <class _Tp> 719struct atomic 720 : public __atomic_base<_Tp> 721{ 722 typedef __atomic_base<_Tp> __base; 723 _LIBCPP_INLINE_VISIBILITY 724 atomic() {} // = default; 725 _LIBCPP_INLINE_VISIBILITY 726 /*constexpr*/ atomic(_Tp __d) : __base(__d) {} 727 728 _LIBCPP_INLINE_VISIBILITY 729 _Tp operator=(_Tp __d) volatile 730 {__base::store(__d); return __d;} 731 _LIBCPP_INLINE_VISIBILITY 732 _Tp operator=(_Tp __d) 733 {__base::store(__d); return __d;} 734}; 735 736// atomic<T*> 737 738template <class _Tp> 739struct atomic<_Tp*> 740 : public __atomic_base<_Tp*> 741{ 742 typedef __atomic_base<_Tp*> __base; 743 _LIBCPP_INLINE_VISIBILITY 744 atomic() {} // = default; 745 _LIBCPP_INLINE_VISIBILITY 746 /*constexpr*/ atomic(_Tp* __d) : __base(__d) {} 747 748 _LIBCPP_INLINE_VISIBILITY 749 _Tp* operator=(_Tp* __d) volatile 750 {__base::store(__d); return __d;} 751 _LIBCPP_INLINE_VISIBILITY 752 _Tp* operator=(_Tp* __d) 753 {__base::store(__d); return __d;} 754 755 _LIBCPP_INLINE_VISIBILITY 756 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) 757 volatile 758 {return __atomic_fetch_add(&this->__a_, __op, __m);} 759 _LIBCPP_INLINE_VISIBILITY 760 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) 761 {return __atomic_fetch_add(&this->__a_, __op, __m);} 762 _LIBCPP_INLINE_VISIBILITY 763 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) 764 volatile 765 {return __atomic_fetch_sub(&this->__a_, __op, __m);} 766 _LIBCPP_INLINE_VISIBILITY 767 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) 768 {return __atomic_fetch_sub(&this->__a_, __op, __m);} 769 770 _LIBCPP_INLINE_VISIBILITY 771 _Tp* operator++(int) volatile {return fetch_add(1);} 772 _LIBCPP_INLINE_VISIBILITY 773 _Tp* operator++(int) {return fetch_add(1);} 774 _LIBCPP_INLINE_VISIBILITY 775 _Tp* operator--(int) volatile {return fetch_sub(1);} 776 _LIBCPP_INLINE_VISIBILITY 777 _Tp* operator--(int) {return fetch_sub(1);} 778 _LIBCPP_INLINE_VISIBILITY 779 _Tp* operator++() volatile {return fetch_add(1) + 1;} 780 _LIBCPP_INLINE_VISIBILITY 781 _Tp* operator++() {return fetch_add(1) + 1;} 782 _LIBCPP_INLINE_VISIBILITY 783 _Tp* operator--() volatile {return fetch_sub(1) - 1;} 784 _LIBCPP_INLINE_VISIBILITY 785 _Tp* operator--() {return fetch_sub(1) - 1;} 786 _LIBCPP_INLINE_VISIBILITY 787 _Tp* operator+=(ptrdiff_t __op) volatile {return fetch_add(__op) + __op;} 788 _LIBCPP_INLINE_VISIBILITY 789 _Tp* operator+=(ptrdiff_t __op) {return fetch_add(__op) + __op;} 790 _LIBCPP_INLINE_VISIBILITY 791 _Tp* operator-=(ptrdiff_t __op) volatile {return fetch_sub(__op) - __op;} 792 _LIBCPP_INLINE_VISIBILITY 793 _Tp* operator-=(ptrdiff_t __op) {return fetch_sub(__op) - __op;} 794}; 795 796// atomic_is_lock_free 797 798template <class _Tp> 799inline _LIBCPP_INLINE_VISIBILITY 800bool 801atomic_is_lock_free(const volatile atomic<_Tp>* __o) 802{ 803 return __o->is_lock_free(); 804} 805 806template <class _Tp> 807inline _LIBCPP_INLINE_VISIBILITY 808bool 809atomic_is_lock_free(const atomic<_Tp>* __o) 810{ 811 return __o->is_lock_free(); 812} 813 814// atomic_init 815 816template <class _Tp> 817inline _LIBCPP_INLINE_VISIBILITY 818void 819atomic_init(volatile atomic<_Tp>* __o, _Tp __d) 820{ 821 __o->__a_ = __d; 822} 823 824template <class _Tp> 825inline _LIBCPP_INLINE_VISIBILITY 826void 827atomic_init(atomic<_Tp>* __o, _Tp __d) 828{ 829 __o->__a_ = __d; 830} 831 832// atomic_store 833 834template <class _Tp> 835inline _LIBCPP_INLINE_VISIBILITY 836void 837atomic_store(volatile atomic<_Tp>* __o, _Tp __d) 838{ 839 __o->store(__d); 840} 841 842template <class _Tp> 843inline _LIBCPP_INLINE_VISIBILITY 844void 845atomic_store(atomic<_Tp>* __o, _Tp __d) 846{ 847 __o->store(__d); 848} 849 850// atomic_store_explicit 851 852template <class _Tp> 853inline _LIBCPP_INLINE_VISIBILITY 854void 855atomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) 856{ 857 __o->store(__d, __m); 858} 859 860template <class _Tp> 861inline _LIBCPP_INLINE_VISIBILITY 862void 863atomic_store_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) 864{ 865 __o->store(__d, __m); 866} 867 868// atomic_load 869 870template <class _Tp> 871inline _LIBCPP_INLINE_VISIBILITY 872_Tp 873atomic_load(const volatile atomic<_Tp>* __o) 874{ 875 return __o->load(); 876} 877 878template <class _Tp> 879inline _LIBCPP_INLINE_VISIBILITY 880_Tp 881atomic_load(const atomic<_Tp>* __o) 882{ 883 return __o->load(); 884} 885 886// atomic_load_explicit 887 888template <class _Tp> 889inline _LIBCPP_INLINE_VISIBILITY 890_Tp 891atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) 892{ 893 return __o->load(__m); 894} 895 896template <class _Tp> 897inline _LIBCPP_INLINE_VISIBILITY 898_Tp 899atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) 900{ 901 return __o->load(__m); 902} 903 904// atomic_exchange 905 906template <class _Tp> 907inline _LIBCPP_INLINE_VISIBILITY 908_Tp 909atomic_exchange(volatile atomic<_Tp>* __o, _Tp __d) 910{ 911 return __o->exchange(__d); 912} 913 914template <class _Tp> 915inline _LIBCPP_INLINE_VISIBILITY 916_Tp 917atomic_exchange(atomic<_Tp>* __o, _Tp __d) 918{ 919 return __o->exchange(__d); 920} 921 922// atomic_exchange_explicit 923 924template <class _Tp> 925inline _LIBCPP_INLINE_VISIBILITY 926_Tp 927atomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) 928{ 929 return __o->exchange(__d, __m); 930} 931 932template <class _Tp> 933inline _LIBCPP_INLINE_VISIBILITY 934_Tp 935atomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) 936{ 937 return __o->exchange(__d, __m); 938} 939 940// atomic_compare_exchange_weak 941 942template <class _Tp> 943inline _LIBCPP_INLINE_VISIBILITY 944bool 945atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) 946{ 947 return __o->compare_exchange_weak(*__e, __d); 948} 949 950template <class _Tp> 951inline _LIBCPP_INLINE_VISIBILITY 952bool 953atomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d) 954{ 955 return __o->compare_exchange_weak(*__e, __d); 956} 957 958// atomic_compare_exchange_strong 959 960template <class _Tp> 961inline _LIBCPP_INLINE_VISIBILITY 962bool 963atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) 964{ 965 return __o->compare_exchange_strong(*__e, __d); 966} 967 968template <class _Tp> 969inline _LIBCPP_INLINE_VISIBILITY 970bool 971atomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d) 972{ 973 return __o->compare_exchange_strong(*__e, __d); 974} 975 976// atomic_compare_exchange_weak_explicit 977 978template <class _Tp> 979inline _LIBCPP_INLINE_VISIBILITY 980bool 981atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e, 982 _Tp __d, 983 memory_order __s, memory_order __f) 984{ 985 return __o->compare_exchange_weak(*__e, __d, __s, __f); 986} 987 988template <class _Tp> 989inline _LIBCPP_INLINE_VISIBILITY 990bool 991atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d, 992 memory_order __s, memory_order __f) 993{ 994 return __o->compare_exchange_weak(*__e, __d, __s, __f); 995} 996 997// atomic_compare_exchange_strong_explicit 998 999template <class _Tp> 1000inline _LIBCPP_INLINE_VISIBILITY 1001bool 1002atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o, 1003 _Tp* __e, _Tp __d, 1004 memory_order __s, memory_order __f) 1005{ 1006 return __o->compare_exchange_strong(*__e, __d, __s, __f); 1007} 1008 1009template <class _Tp> 1010inline _LIBCPP_INLINE_VISIBILITY 1011bool 1012atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e, 1013 _Tp __d, 1014 memory_order __s, memory_order __f) 1015{ 1016 return __o->compare_exchange_strong(*__e, __d, __s, __f); 1017} 1018 1019// atomic_fetch_add 1020 1021template <class _Tp> 1022inline _LIBCPP_INLINE_VISIBILITY 1023typename enable_if 1024< 1025 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1026 _Tp 1027>::type 1028atomic_fetch_add(volatile atomic<_Tp>* __o, _Tp __op) 1029{ 1030 return __o->fetch_add(__op); 1031} 1032 1033template <class _Tp> 1034inline _LIBCPP_INLINE_VISIBILITY 1035typename enable_if 1036< 1037 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1038 _Tp 1039>::type 1040atomic_fetch_add(atomic<_Tp>* __o, _Tp __op) 1041{ 1042 return __o->fetch_add(__op); 1043} 1044 1045template <class _Tp> 1046inline _LIBCPP_INLINE_VISIBILITY 1047_Tp* 1048atomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op) 1049{ 1050 return __o->fetch_add(__op); 1051} 1052 1053template <class _Tp> 1054inline _LIBCPP_INLINE_VISIBILITY 1055_Tp* 1056atomic_fetch_add(atomic<_Tp*>* __o, ptrdiff_t __op) 1057{ 1058 return __o->fetch_add(__op); 1059} 1060 1061// atomic_fetch_add_explicit 1062 1063template <class _Tp> 1064inline _LIBCPP_INLINE_VISIBILITY 1065typename enable_if 1066< 1067 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1068 _Tp 1069>::type 1070atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) 1071{ 1072 return __o->fetch_add(__op, __m); 1073} 1074 1075template <class _Tp> 1076inline _LIBCPP_INLINE_VISIBILITY 1077typename enable_if 1078< 1079 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1080 _Tp 1081>::type 1082atomic_fetch_add_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) 1083{ 1084 return __o->fetch_add(__op, __m); 1085} 1086 1087template <class _Tp> 1088inline _LIBCPP_INLINE_VISIBILITY 1089_Tp* 1090atomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op, 1091 memory_order __m) 1092{ 1093 return __o->fetch_add(__op, __m); 1094} 1095 1096template <class _Tp> 1097inline _LIBCPP_INLINE_VISIBILITY 1098_Tp* 1099atomic_fetch_add_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) 1100{ 1101 return __o->fetch_add(__op, __m); 1102} 1103 1104// atomic_fetch_sub 1105 1106template <class _Tp> 1107inline _LIBCPP_INLINE_VISIBILITY 1108typename enable_if 1109< 1110 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1111 _Tp 1112>::type 1113atomic_fetch_sub(volatile atomic<_Tp>* __o, _Tp __op) 1114{ 1115 return __o->fetch_sub(__op); 1116} 1117 1118template <class _Tp> 1119inline _LIBCPP_INLINE_VISIBILITY 1120typename enable_if 1121< 1122 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1123 _Tp 1124>::type 1125atomic_fetch_sub(atomic<_Tp>* __o, _Tp __op) 1126{ 1127 return __o->fetch_sub(__op); 1128} 1129 1130template <class _Tp> 1131inline _LIBCPP_INLINE_VISIBILITY 1132_Tp* 1133atomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op) 1134{ 1135 return __o->fetch_sub(__op); 1136} 1137 1138template <class _Tp> 1139inline _LIBCPP_INLINE_VISIBILITY 1140_Tp* 1141atomic_fetch_sub(atomic<_Tp*>* __o, ptrdiff_t __op) 1142{ 1143 return __o->fetch_sub(__op); 1144} 1145 1146// atomic_fetch_sub_explicit 1147 1148template <class _Tp> 1149inline _LIBCPP_INLINE_VISIBILITY 1150typename enable_if 1151< 1152 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1153 _Tp 1154>::type 1155atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) 1156{ 1157 return __o->fetch_sub(__op, __m); 1158} 1159 1160template <class _Tp> 1161inline _LIBCPP_INLINE_VISIBILITY 1162typename enable_if 1163< 1164 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1165 _Tp 1166>::type 1167atomic_fetch_sub_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) 1168{ 1169 return __o->fetch_sub(__op, __m); 1170} 1171 1172template <class _Tp> 1173inline _LIBCPP_INLINE_VISIBILITY 1174_Tp* 1175atomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op, 1176 memory_order __m) 1177{ 1178 return __o->fetch_sub(__op, __m); 1179} 1180 1181template <class _Tp> 1182inline _LIBCPP_INLINE_VISIBILITY 1183_Tp* 1184atomic_fetch_sub_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) 1185{ 1186 return __o->fetch_sub(__op, __m); 1187} 1188 1189// atomic_fetch_and 1190 1191template <class _Tp> 1192inline _LIBCPP_INLINE_VISIBILITY 1193typename enable_if 1194< 1195 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1196 _Tp 1197>::type 1198atomic_fetch_and(volatile atomic<_Tp>* __o, _Tp __op) 1199{ 1200 return __o->fetch_and(__op); 1201} 1202 1203template <class _Tp> 1204inline _LIBCPP_INLINE_VISIBILITY 1205typename enable_if 1206< 1207 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1208 _Tp 1209>::type 1210atomic_fetch_and(atomic<_Tp>* __o, _Tp __op) 1211{ 1212 return __o->fetch_and(__op); 1213} 1214 1215// atomic_fetch_and_explicit 1216 1217template <class _Tp> 1218inline _LIBCPP_INLINE_VISIBILITY 1219typename enable_if 1220< 1221 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1222 _Tp 1223>::type 1224atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) 1225{ 1226 return __o->fetch_and(__op, __m); 1227} 1228 1229template <class _Tp> 1230inline _LIBCPP_INLINE_VISIBILITY 1231typename enable_if 1232< 1233 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1234 _Tp 1235>::type 1236atomic_fetch_and_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) 1237{ 1238 return __o->fetch_and(__op, __m); 1239} 1240 1241// atomic_fetch_or 1242 1243template <class _Tp> 1244inline _LIBCPP_INLINE_VISIBILITY 1245typename enable_if 1246< 1247 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1248 _Tp 1249>::type 1250atomic_fetch_or(volatile atomic<_Tp>* __o, _Tp __op) 1251{ 1252 return __o->fetch_or(__op); 1253} 1254 1255template <class _Tp> 1256inline _LIBCPP_INLINE_VISIBILITY 1257typename enable_if 1258< 1259 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1260 _Tp 1261>::type 1262atomic_fetch_or(atomic<_Tp>* __o, _Tp __op) 1263{ 1264 return __o->fetch_or(__op); 1265} 1266 1267// atomic_fetch_or_explicit 1268 1269template <class _Tp> 1270inline _LIBCPP_INLINE_VISIBILITY 1271typename enable_if 1272< 1273 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1274 _Tp 1275>::type 1276atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) 1277{ 1278 return __o->fetch_or(__op, __m); 1279} 1280 1281template <class _Tp> 1282inline _LIBCPP_INLINE_VISIBILITY 1283typename enable_if 1284< 1285 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1286 _Tp 1287>::type 1288atomic_fetch_or_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) 1289{ 1290 return __o->fetch_or(__op, __m); 1291} 1292 1293// atomic_fetch_xor 1294 1295template <class _Tp> 1296inline _LIBCPP_INLINE_VISIBILITY 1297typename enable_if 1298< 1299 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1300 _Tp 1301>::type 1302atomic_fetch_xor(volatile atomic<_Tp>* __o, _Tp __op) 1303{ 1304 return __o->fetch_xor(__op); 1305} 1306 1307template <class _Tp> 1308inline _LIBCPP_INLINE_VISIBILITY 1309typename enable_if 1310< 1311 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1312 _Tp 1313>::type 1314atomic_fetch_xor(atomic<_Tp>* __o, _Tp __op) 1315{ 1316 return __o->fetch_xor(__op); 1317} 1318 1319// atomic_fetch_xor_explicit 1320 1321template <class _Tp> 1322inline _LIBCPP_INLINE_VISIBILITY 1323typename enable_if 1324< 1325 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1326 _Tp 1327>::type 1328atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) 1329{ 1330 return __o->fetch_xor(__op, __m); 1331} 1332 1333template <class _Tp> 1334inline _LIBCPP_INLINE_VISIBILITY 1335typename enable_if 1336< 1337 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1338 _Tp 1339>::type 1340atomic_fetch_xor_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) 1341{ 1342 return __o->fetch_xor(__op, __m); 1343} 1344 1345// flag type and operations 1346 1347typedef struct atomic_flag 1348{ 1349 bool __a_; 1350 1351 _LIBCPP_INLINE_VISIBILITY 1352 bool test_and_set(memory_order __m = memory_order_seq_cst) volatile 1353 {return __atomic_exchange(&__a_, true, __m);} 1354 _LIBCPP_INLINE_VISIBILITY 1355 bool test_and_set(memory_order __m = memory_order_seq_cst) 1356 {return __atomic_exchange(&__a_, true, __m);} 1357 _LIBCPP_INLINE_VISIBILITY 1358 void clear(memory_order __m = memory_order_seq_cst) volatile 1359 {__atomic_store(&__a_, false, __m);} 1360 _LIBCPP_INLINE_VISIBILITY 1361 void clear(memory_order __m = memory_order_seq_cst) 1362 {__atomic_store(&__a_, false, __m);} 1363 1364 _LIBCPP_INLINE_VISIBILITY 1365 atomic_flag() {} // = default; 1366 _LIBCPP_INLINE_VISIBILITY 1367 atomic_flag(bool __b) : __a_(__b) {} 1368 1369#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS 1370 atomic_flag(const atomic_flag&) = delete; 1371 atomic_flag& operator=(const atomic_flag&) = delete; 1372 atomic_flag& operator=(const atomic_flag&) volatile = delete; 1373#else // _LIBCPP_HAS_NO_DELETED_FUNCTIONS 1374private: 1375 atomic_flag(const atomic_flag&); 1376 atomic_flag& operator=(const atomic_flag&); 1377 atomic_flag& operator=(const atomic_flag&) volatile; 1378#endif // _LIBCPP_HAS_NO_DELETED_FUNCTIONS 1379} atomic_flag; 1380 1381inline _LIBCPP_INLINE_VISIBILITY 1382bool 1383atomic_flag_test_and_set(volatile atomic_flag* __o) 1384{ 1385 return __o->test_and_set(); 1386} 1387 1388inline _LIBCPP_INLINE_VISIBILITY 1389bool 1390atomic_flag_test_and_set(atomic_flag* __o) 1391{ 1392 return __o->test_and_set(); 1393} 1394 1395inline _LIBCPP_INLINE_VISIBILITY 1396bool 1397atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) 1398{ 1399 return __o->test_and_set(__m); 1400} 1401 1402inline _LIBCPP_INLINE_VISIBILITY 1403bool 1404atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) 1405{ 1406 return __o->test_and_set(__m); 1407} 1408 1409inline _LIBCPP_INLINE_VISIBILITY 1410void 1411atomic_flag_clear(volatile atomic_flag* __o) 1412{ 1413 __o->clear(); 1414} 1415 1416inline _LIBCPP_INLINE_VISIBILITY 1417void 1418atomic_flag_clear(atomic_flag* __o) 1419{ 1420 __o->clear(); 1421} 1422 1423inline _LIBCPP_INLINE_VISIBILITY 1424void 1425atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) 1426{ 1427 __o->clear(__m); 1428} 1429 1430inline _LIBCPP_INLINE_VISIBILITY 1431void 1432atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) 1433{ 1434 __o->clear(__m); 1435} 1436 1437// fences 1438 1439inline _LIBCPP_INLINE_VISIBILITY 1440void 1441atomic_thread_fence(memory_order __m) 1442{ 1443 __atomic_thread_fence(__m); 1444} 1445 1446inline _LIBCPP_INLINE_VISIBILITY 1447void 1448atomic_signal_fence(memory_order __m) 1449{ 1450 __atomic_signal_fence(__m); 1451} 1452 1453// Atomics for standard typedef types 1454 1455typedef atomic<char> atomic_char; 1456typedef atomic<signed char> atomic_schar; 1457typedef atomic<unsigned char> atomic_uchar; 1458typedef atomic<short> atomic_short; 1459typedef atomic<unsigned short> atomic_ushort; 1460typedef atomic<int> atomic_int; 1461typedef atomic<unsigned int> atomic_uint; 1462typedef atomic<long> atomic_long; 1463typedef atomic<unsigned long> atomic_ulong; 1464typedef atomic<long long> atomic_llong; 1465typedef atomic<unsigned long long> atomic_ullong; 1466typedef atomic<char16_t> atomic_char16_t; 1467typedef atomic<char32_t> atomic_char32_t; 1468typedef atomic<wchar_t> atomic_wchar_t; 1469 1470typedef atomic<int_least8_t> atomic_int_least8_t; 1471typedef atomic<uint_least8_t> atomic_uint_least8_t; 1472typedef atomic<int_least16_t> atomic_int_least16_t; 1473typedef atomic<uint_least16_t> atomic_uint_least16_t; 1474typedef atomic<int_least32_t> atomic_int_least32_t; 1475typedef atomic<uint_least32_t> atomic_uint_least32_t; 1476typedef atomic<int_least64_t> atomic_int_least64_t; 1477typedef atomic<uint_least64_t> atomic_uint_least64_t; 1478 1479typedef atomic<int_fast8_t> atomic_int_fast8_t; 1480typedef atomic<uint_fast8_t> atomic_uint_fast8_t; 1481typedef atomic<int_fast16_t> atomic_int_fast16_t; 1482typedef atomic<uint_fast16_t> atomic_uint_fast16_t; 1483typedef atomic<int_fast32_t> atomic_int_fast32_t; 1484typedef atomic<uint_fast32_t> atomic_uint_fast32_t; 1485typedef atomic<int_fast64_t> atomic_int_fast64_t; 1486typedef atomic<uint_fast64_t> atomic_uint_fast64_t; 1487 1488typedef atomic<intptr_t> atomic_intptr_t; 1489typedef atomic<uintptr_t> atomic_uintptr_t; 1490typedef atomic<size_t> atomic_size_t; 1491typedef atomic<ptrdiff_t> atomic_ptrdiff_t; 1492typedef atomic<intmax_t> atomic_intmax_t; 1493typedef atomic<uintmax_t> atomic_uintmax_t; 1494 1495#define ATOMIC_FLAG_INIT {false} 1496#define ATOMIC_VAR_INIT(__v) {__v} 1497 1498// lock-free property 1499 1500#define ATOMIC_CHAR_LOCK_FREE 0 1501#define ATOMIC_CHAR16_T_LOCK_FREE 0 1502#define ATOMIC_CHAR32_T_LOCK_FREE 0 1503#define ATOMIC_WCHAR_T_LOCK_FREE 0 1504#define ATOMIC_SHORT_LOCK_FREE 0 1505#define ATOMIC_INT_LOCK_FREE 0 1506#define ATOMIC_LONG_LOCK_FREE 0 1507#define ATOMIC_LLONG_LOCK_FREE 0 1508 1509#endif // !__has_feature(cxx_atomic) 1510 1511_LIBCPP_END_NAMESPACE_STD 1512 1513#endif // _LIBCPP_ATOMIC 1514