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