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