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