atomic revision 253159
139072Sdfr// -*- C++ -*- 239072Sdfr//===--------------------------- atomic -----------------------------------===// 339072Sdfr// 439072Sdfr// The LLVM Compiler Infrastructure 539072Sdfr// 639072Sdfr// This file is distributed under the University of Illinois Open Source 739072Sdfr// License. See LICENSE.TXT for details. 839072Sdfr// 939072Sdfr//===----------------------------------------------------------------------===// 1039072Sdfr 1139072Sdfr#ifndef _LIBCPP_ATOMIC 1239072Sdfr#define _LIBCPP_ATOMIC 1339072Sdfr 1439072Sdfr/* 1539072Sdfr atomic synopsis 1639072Sdfr 1739072Sdfrnamespace std 1839072Sdfr{ 1939072Sdfr 2039072Sdfr// order and consistency 2139072Sdfr 2239072Sdfrtypedef enum memory_order 2339072Sdfr{ 2439072Sdfr memory_order_relaxed, 2550477Speter memory_order_consume, // load-consume 2639072Sdfr memory_order_acquire, // load-acquire 2739072Sdfr memory_order_release, // store-release 2839072Sdfr memory_order_acq_rel, // store-release load-acquire 2939072Sdfr memory_order_seq_cst // store-release load-acquire 3039072Sdfr} memory_order; 31102808Sjake 32102808Sjaketemplate <class T> T kill_dependency(T y) noexcept; 3339072Sdfr 3439072Sdfr// lock-free property 3539072Sdfr 3639072Sdfr#define ATOMIC_BOOL_LOCK_FREE unspecified 37100384Speter#define ATOMIC_CHAR_LOCK_FREE unspecified 38100384Speter#define ATOMIC_CHAR16_T_LOCK_FREE unspecified 39100384Speter#define ATOMIC_CHAR32_T_LOCK_FREE unspecified 40100384Speter#define ATOMIC_WCHAR_T_LOCK_FREE unspecified 4139072Sdfr#define ATOMIC_SHORT_LOCK_FREE unspecified 4239072Sdfr#define ATOMIC_INT_LOCK_FREE unspecified 43102808Sjake#define ATOMIC_LONG_LOCK_FREE unspecified 44102808Sjake#define ATOMIC_LLONG_LOCK_FREE unspecified 45102808Sjake#define ATOMIC_POINTER_LOCK_FREE unspecified 46102808Sjake 47132282Sgrehan// flag type and operations 4839072Sdfr 49100384Spetertypedef struct atomic_flag 5039072Sdfr{ 51209975Snwhitehorn bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept; 52183322Skib bool test_and_set(memory_order m = memory_order_seq_cst) noexcept; 53183322Skib void clear(memory_order m = memory_order_seq_cst) volatile noexcept; 54183322Skib void clear(memory_order m = memory_order_seq_cst) noexcept; 55183322Skib atomic_flag() noexcept = default; 56183322Skib atomic_flag(const atomic_flag&) = delete; 57183322Skib atomic_flag& operator=(const atomic_flag&) = delete; 58183322Skib atomic_flag& operator=(const atomic_flag&) volatile = delete; 59183322Skib} atomic_flag; 60183322Skib 61183322Skibbool 62209975Snwhitehorn atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept; 63209975Snwhitehorn 64183322Skibbool 65209975Snwhitehorn atomic_flag_test_and_set(atomic_flag* obj) noexcept; 66183322Skib 67183322Skibbool 68183322Skib atomic_flag_test_and_set_explicit(volatile atomic_flag* obj, 69183322Skib memory_order m) noexcept; 70183322Skib 71183322Skibbool 72183322Skib atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept; 73183322Skib 74183322Skibvoid 75183322Skib atomic_flag_clear(volatile atomic_flag* obj) noexcept; 76183322Skib 77183322Skibvoid 78185169Skib atomic_flag_clear(atomic_flag* obj) noexcept; 79217400Skib 80208453Skibvoid 81208453Skib atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept; 82208453Skib 83217400Skibvoid 84217400Skib atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept; 85219405Sdchagin 86100384Speter#define ATOMIC_FLAG_INIT see below 87217400Skib#define ATOMIC_VAR_INIT(value) see below 88100384Speter 89209975Snwhitehorntemplate <class T> 90183322Skibstruct atomic 91209975Snwhitehorn{ 92183322Skib bool is_lock_free() const volatile noexcept; 93183322Skib bool is_lock_free() const noexcept; 94183322Skib void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept; 95209975Snwhitehorn void store(T desr, memory_order m = memory_order_seq_cst) noexcept; 96183322Skib T load(memory_order m = memory_order_seq_cst) const volatile noexcept; 97209975Snwhitehorn T load(memory_order m = memory_order_seq_cst) const noexcept; 98190708Sdchagin operator T() const volatile noexcept; 99183322Skib operator T() const noexcept; 100100384Speter T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept; 101209975Snwhitehorn T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept; 102209975Snwhitehorn bool compare_exchange_weak(T& expc, T desr, 103183322Skib memory_order s, memory_order f) volatile noexcept; 104100384Speter bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept; 105209975Snwhitehorn bool compare_exchange_strong(T& expc, T desr, 106183322Skib memory_order s, memory_order f) volatile noexcept; 107209975Snwhitehorn bool compare_exchange_strong(T& expc, T desr, 108183322Skib memory_order s, memory_order f) noexcept; 109183322Skib bool compare_exchange_weak(T& expc, T desr, 110183322Skib memory_order m = memory_order_seq_cst) volatile noexcept; 111209975Snwhitehorn bool compare_exchange_weak(T& expc, T desr, 112183322Skib memory_order m = memory_order_seq_cst) noexcept; 113209975Snwhitehorn bool compare_exchange_strong(T& expc, T desr, 114190708Sdchagin memory_order m = memory_order_seq_cst) volatile noexcept; 115183322Skib bool compare_exchange_strong(T& expc, T desr, 116123742Speter memory_order m = memory_order_seq_cst) noexcept; 117209975Snwhitehorn 118209975Snwhitehorn atomic() noexcept = default; 119123742Speter constexpr atomic(T desr) noexcept; 120123742Speter atomic(const atomic&) = delete; 121133464Smarcel atomic& operator=(const atomic&) = delete; 122209975Snwhitehorn atomic& operator=(const atomic&) volatile = delete; 123133464Smarcel T operator=(T) volatile noexcept; 124133464Smarcel T operator=(T) noexcept; 125133464Smarcel}; 126133464Smarcel 127133464Smarceltemplate <> 12839072Sdfrstruct atomic<integral> 129109605Sjake{ 130129282Speter bool is_lock_free() const volatile noexcept; 131129282Speter bool is_lock_free() const noexcept; 13239072Sdfr void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept; 13340435Speter void store(integral desr, memory_order m = memory_order_seq_cst) noexcept; 13445958Sdt integral load(memory_order m = memory_order_seq_cst) const volatile noexcept; 13540435Speter integral load(memory_order m = memory_order_seq_cst) const noexcept; 13695410Smarcel operator integral() const volatile noexcept; 13740435Speter operator integral() const noexcept; 13839072Sdfr integral exchange(integral desr, 13940435Speter memory_order m = memory_order_seq_cst) volatile noexcept; 14040435Speter integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept; 141132282Sgrehan bool compare_exchange_weak(integral& expc, integral desr, 14240435Speter memory_order s, memory_order f) volatile noexcept; 14340435Speter bool compare_exchange_weak(integral& expc, integral desr, 14445958Sdt memory_order s, memory_order f) noexcept; 14540435Speter bool compare_exchange_strong(integral& expc, integral desr, 14640435Speter memory_order s, memory_order f) volatile noexcept; 14740435Speter bool compare_exchange_strong(integral& expc, integral desr, 14895410Smarcel memory_order s, memory_order f) noexcept; 14940435Speter bool compare_exchange_weak(integral& expc, integral desr, 15040435Speter memory_order m = memory_order_seq_cst) volatile noexcept; 15140435Speter bool compare_exchange_weak(integral& expc, integral desr, 15240435Speter memory_order m = memory_order_seq_cst) noexcept; 15339072Sdfr bool compare_exchange_strong(integral& expc, integral desr, 15440435Speter memory_order m = memory_order_seq_cst) volatile noexcept; 15539072Sdfr bool compare_exchange_strong(integral& expc, integral desr, 156132282Sgrehan memory_order m = memory_order_seq_cst) noexcept; 157132282Sgrehan 15848840Sdfr integral 159209975Snwhitehorn fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 160132282Sgrehan integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept; 161132282Sgrehan integral 162132282Sgrehan fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 163132282Sgrehan integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept; 164132282Sgrehan integral 165132282Sgrehan fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 16639072Sdfr integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept; 167209975Snwhitehorn integral 168209975Snwhitehorn fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 169209975Snwhitehorn integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept; 17039072Sdfr integral 171209975Snwhitehorn fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 172132562Sgrehan integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept; 173209975Snwhitehorn 174209975Snwhitehorn atomic() noexcept = default; 175132282Sgrehan constexpr atomic(integral desr) noexcept; 17639072Sdfr atomic(const atomic&) = delete; 177132282Sgrehan atomic& operator=(const atomic&) = delete; 178132282Sgrehan atomic& operator=(const atomic&) volatile = delete; 179132282Sgrehan integral operator=(integral desr) volatile noexcept; 180132282Sgrehan integral operator=(integral desr) noexcept; 18139072Sdfr 18239072Sdfr integral operator++(int) volatile noexcept; 18339072Sdfr integral operator++(int) noexcept; 184105469Smarcel integral operator--(int) volatile noexcept; 185105469Smarcel integral operator--(int) noexcept; 186129282Speter integral operator++() volatile noexcept; 187129282Speter integral operator++() noexcept; 188109605Sjake integral operator--() volatile noexcept; 189109605Sjake integral operator--() noexcept; 190129282Speter integral operator+=(integral op) volatile noexcept; 191109605Sjake integral operator+=(integral op) noexcept; 192109605Sjake integral operator-=(integral op) volatile noexcept; 193109605Sjake integral operator-=(integral op) noexcept; 194129282Speter integral operator&=(integral op) volatile noexcept; 195129282Speter integral operator&=(integral op) noexcept; 196109605Sjake integral operator|=(integral op) volatile noexcept; 197109605Sjake integral operator|=(integral op) noexcept; 198129282Speter integral operator^=(integral op) volatile noexcept; 199109605Sjake integral operator^=(integral op) noexcept; 200109605Sjake}; 201109605Sjake 202132428Sgrehantemplate <class T> 203105469Smarcelstruct atomic<T*> 204132428Sgrehan{ 205132428Sgrehan bool is_lock_free() const volatile noexcept; 206132428Sgrehan bool is_lock_free() const noexcept; 207105469Smarcel void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept; 208105469Smarcel void store(T* desr, memory_order m = memory_order_seq_cst) noexcept; 209105469Smarcel T* load(memory_order m = memory_order_seq_cst) const volatile noexcept; 210105469Smarcel T* load(memory_order m = memory_order_seq_cst) const noexcept; 211105469Smarcel operator T*() const volatile noexcept; 212105469Smarcel operator T*() const noexcept; 213105469Smarcel T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept; 214105469Smarcel T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept; 215105469Smarcel 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#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS 626 __atomic_base() _NOEXCEPT = default; 627#else 628 __atomic_base() _NOEXCEPT : __a_() {} 629#endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS 630 631 _LIBCPP_INLINE_VISIBILITY 632 _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {} 633#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS 634 __atomic_base(const __atomic_base&) = delete; 635 __atomic_base& operator=(const __atomic_base&) = delete; 636 __atomic_base& operator=(const __atomic_base&) volatile = delete; 637#else // _LIBCPP_HAS_NO_DELETED_FUNCTIONS 638private: 639 __atomic_base(const __atomic_base&); 640 __atomic_base& operator=(const __atomic_base&); 641 __atomic_base& operator=(const __atomic_base&) volatile; 642#endif // _LIBCPP_HAS_NO_DELETED_FUNCTIONS 643}; 644 645// atomic<Integral> 646 647template <class _Tp> 648struct __atomic_base<_Tp, true> 649 : public __atomic_base<_Tp, false> 650{ 651 typedef __atomic_base<_Tp, false> __base; 652 _LIBCPP_INLINE_VISIBILITY 653 __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT 654 _LIBCPP_INLINE_VISIBILITY 655 _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {} 656 657 _LIBCPP_INLINE_VISIBILITY 658 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 659 {return __c11_atomic_fetch_add(&this->__a_, __op, __m);} 660 _LIBCPP_INLINE_VISIBILITY 661 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 662 {return __c11_atomic_fetch_add(&this->__a_, __op, __m);} 663 _LIBCPP_INLINE_VISIBILITY 664 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 665 {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);} 666 _LIBCPP_INLINE_VISIBILITY 667 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 668 {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);} 669 _LIBCPP_INLINE_VISIBILITY 670 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 671 {return __c11_atomic_fetch_and(&this->__a_, __op, __m);} 672 _LIBCPP_INLINE_VISIBILITY 673 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 674 {return __c11_atomic_fetch_and(&this->__a_, __op, __m);} 675 _LIBCPP_INLINE_VISIBILITY 676 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 677 {return __c11_atomic_fetch_or(&this->__a_, __op, __m);} 678 _LIBCPP_INLINE_VISIBILITY 679 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 680 {return __c11_atomic_fetch_or(&this->__a_, __op, __m);} 681 _LIBCPP_INLINE_VISIBILITY 682 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 683 {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);} 684 _LIBCPP_INLINE_VISIBILITY 685 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 686 {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);} 687 688 _LIBCPP_INLINE_VISIBILITY 689 _Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));} 690 _LIBCPP_INLINE_VISIBILITY 691 _Tp operator++(int) _NOEXCEPT {return fetch_add(_Tp(1));} 692 _LIBCPP_INLINE_VISIBILITY 693 _Tp operator--(int) volatile _NOEXCEPT {return fetch_sub(_Tp(1));} 694 _LIBCPP_INLINE_VISIBILITY 695 _Tp operator--(int) _NOEXCEPT {return fetch_sub(_Tp(1));} 696 _LIBCPP_INLINE_VISIBILITY 697 _Tp operator++() volatile _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);} 698 _LIBCPP_INLINE_VISIBILITY 699 _Tp operator++() _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);} 700 _LIBCPP_INLINE_VISIBILITY 701 _Tp operator--() volatile _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);} 702 _LIBCPP_INLINE_VISIBILITY 703 _Tp operator--() _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);} 704 _LIBCPP_INLINE_VISIBILITY 705 _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;} 706 _LIBCPP_INLINE_VISIBILITY 707 _Tp operator+=(_Tp __op) _NOEXCEPT {return fetch_add(__op) + __op;} 708 _LIBCPP_INLINE_VISIBILITY 709 _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;} 710 _LIBCPP_INLINE_VISIBILITY 711 _Tp operator-=(_Tp __op) _NOEXCEPT {return fetch_sub(__op) - __op;} 712 _LIBCPP_INLINE_VISIBILITY 713 _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;} 714 _LIBCPP_INLINE_VISIBILITY 715 _Tp operator&=(_Tp __op) _NOEXCEPT {return fetch_and(__op) & __op;} 716 _LIBCPP_INLINE_VISIBILITY 717 _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;} 718 _LIBCPP_INLINE_VISIBILITY 719 _Tp operator|=(_Tp __op) _NOEXCEPT {return fetch_or(__op) | __op;} 720 _LIBCPP_INLINE_VISIBILITY 721 _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;} 722 _LIBCPP_INLINE_VISIBILITY 723 _Tp operator^=(_Tp __op) _NOEXCEPT {return fetch_xor(__op) ^ __op;} 724}; 725 726// atomic<T> 727 728template <class _Tp> 729struct atomic 730 : public __atomic_base<_Tp> 731{ 732 typedef __atomic_base<_Tp> __base; 733 _LIBCPP_INLINE_VISIBILITY 734 atomic() _NOEXCEPT _LIBCPP_DEFAULT 735 _LIBCPP_INLINE_VISIBILITY 736 _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {} 737 738 _LIBCPP_INLINE_VISIBILITY 739 _Tp operator=(_Tp __d) volatile _NOEXCEPT 740 {__base::store(__d); return __d;} 741 _LIBCPP_INLINE_VISIBILITY 742 _Tp operator=(_Tp __d) _NOEXCEPT 743 {__base::store(__d); return __d;} 744}; 745 746// atomic<T*> 747 748template <class _Tp> 749struct atomic<_Tp*> 750 : public __atomic_base<_Tp*> 751{ 752 typedef __atomic_base<_Tp*> __base; 753 _LIBCPP_INLINE_VISIBILITY 754 atomic() _NOEXCEPT _LIBCPP_DEFAULT 755 _LIBCPP_INLINE_VISIBILITY 756 _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {} 757 758 _LIBCPP_INLINE_VISIBILITY 759 _Tp* operator=(_Tp* __d) volatile _NOEXCEPT 760 {__base::store(__d); return __d;} 761 _LIBCPP_INLINE_VISIBILITY 762 _Tp* operator=(_Tp* __d) _NOEXCEPT 763 {__base::store(__d); return __d;} 764 765 _LIBCPP_INLINE_VISIBILITY 766 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) 767 volatile _NOEXCEPT 768 {return __c11_atomic_fetch_add(&this->__a_, __op, __m);} 769 _LIBCPP_INLINE_VISIBILITY 770 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 771 {return __c11_atomic_fetch_add(&this->__a_, __op, __m);} 772 _LIBCPP_INLINE_VISIBILITY 773 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) 774 volatile _NOEXCEPT 775 {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);} 776 _LIBCPP_INLINE_VISIBILITY 777 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 778 {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);} 779 780 _LIBCPP_INLINE_VISIBILITY 781 _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);} 782 _LIBCPP_INLINE_VISIBILITY 783 _Tp* operator++(int) _NOEXCEPT {return fetch_add(1);} 784 _LIBCPP_INLINE_VISIBILITY 785 _Tp* operator--(int) volatile _NOEXCEPT {return fetch_sub(1);} 786 _LIBCPP_INLINE_VISIBILITY 787 _Tp* operator--(int) _NOEXCEPT {return fetch_sub(1);} 788 _LIBCPP_INLINE_VISIBILITY 789 _Tp* operator++() volatile _NOEXCEPT {return fetch_add(1) + 1;} 790 _LIBCPP_INLINE_VISIBILITY 791 _Tp* operator++() _NOEXCEPT {return fetch_add(1) + 1;} 792 _LIBCPP_INLINE_VISIBILITY 793 _Tp* operator--() volatile _NOEXCEPT {return fetch_sub(1) - 1;} 794 _LIBCPP_INLINE_VISIBILITY 795 _Tp* operator--() _NOEXCEPT {return fetch_sub(1) - 1;} 796 _LIBCPP_INLINE_VISIBILITY 797 _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;} 798 _LIBCPP_INLINE_VISIBILITY 799 _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT {return fetch_add(__op) + __op;} 800 _LIBCPP_INLINE_VISIBILITY 801 _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;} 802 _LIBCPP_INLINE_VISIBILITY 803 _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;} 804}; 805 806// atomic_is_lock_free 807 808template <class _Tp> 809inline _LIBCPP_INLINE_VISIBILITY 810bool 811atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT 812{ 813 return __o->is_lock_free(); 814} 815 816template <class _Tp> 817inline _LIBCPP_INLINE_VISIBILITY 818bool 819atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT 820{ 821 return __o->is_lock_free(); 822} 823 824// atomic_init 825 826template <class _Tp> 827inline _LIBCPP_INLINE_VISIBILITY 828void 829atomic_init(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 830{ 831 __c11_atomic_init(&__o->__a_, __d); 832} 833 834template <class _Tp> 835inline _LIBCPP_INLINE_VISIBILITY 836void 837atomic_init(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 838{ 839 __c11_atomic_init(&__o->__a_, __d); 840} 841 842// atomic_store 843 844template <class _Tp> 845inline _LIBCPP_INLINE_VISIBILITY 846void 847atomic_store(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 848{ 849 __o->store(__d); 850} 851 852template <class _Tp> 853inline _LIBCPP_INLINE_VISIBILITY 854void 855atomic_store(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 856{ 857 __o->store(__d); 858} 859 860// atomic_store_explicit 861 862template <class _Tp> 863inline _LIBCPP_INLINE_VISIBILITY 864void 865atomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT 866{ 867 __o->store(__d, __m); 868} 869 870template <class _Tp> 871inline _LIBCPP_INLINE_VISIBILITY 872void 873atomic_store_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT 874{ 875 __o->store(__d, __m); 876} 877 878// atomic_load 879 880template <class _Tp> 881inline _LIBCPP_INLINE_VISIBILITY 882_Tp 883atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT 884{ 885 return __o->load(); 886} 887 888template <class _Tp> 889inline _LIBCPP_INLINE_VISIBILITY 890_Tp 891atomic_load(const atomic<_Tp>* __o) _NOEXCEPT 892{ 893 return __o->load(); 894} 895 896// atomic_load_explicit 897 898template <class _Tp> 899inline _LIBCPP_INLINE_VISIBILITY 900_Tp 901atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT 902{ 903 return __o->load(__m); 904} 905 906template <class _Tp> 907inline _LIBCPP_INLINE_VISIBILITY 908_Tp 909atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT 910{ 911 return __o->load(__m); 912} 913 914// atomic_exchange 915 916template <class _Tp> 917inline _LIBCPP_INLINE_VISIBILITY 918_Tp 919atomic_exchange(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 920{ 921 return __o->exchange(__d); 922} 923 924template <class _Tp> 925inline _LIBCPP_INLINE_VISIBILITY 926_Tp 927atomic_exchange(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 928{ 929 return __o->exchange(__d); 930} 931 932// atomic_exchange_explicit 933 934template <class _Tp> 935inline _LIBCPP_INLINE_VISIBILITY 936_Tp 937atomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT 938{ 939 return __o->exchange(__d, __m); 940} 941 942template <class _Tp> 943inline _LIBCPP_INLINE_VISIBILITY 944_Tp 945atomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT 946{ 947 return __o->exchange(__d, __m); 948} 949 950// atomic_compare_exchange_weak 951 952template <class _Tp> 953inline _LIBCPP_INLINE_VISIBILITY 954bool 955atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT 956{ 957 return __o->compare_exchange_weak(*__e, __d); 958} 959 960template <class _Tp> 961inline _LIBCPP_INLINE_VISIBILITY 962bool 963atomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT 964{ 965 return __o->compare_exchange_weak(*__e, __d); 966} 967 968// atomic_compare_exchange_strong 969 970template <class _Tp> 971inline _LIBCPP_INLINE_VISIBILITY 972bool 973atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT 974{ 975 return __o->compare_exchange_strong(*__e, __d); 976} 977 978template <class _Tp> 979inline _LIBCPP_INLINE_VISIBILITY 980bool 981atomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT 982{ 983 return __o->compare_exchange_strong(*__e, __d); 984} 985 986// atomic_compare_exchange_weak_explicit 987 988template <class _Tp> 989inline _LIBCPP_INLINE_VISIBILITY 990bool 991atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e, 992 _Tp __d, 993 memory_order __s, memory_order __f) _NOEXCEPT 994{ 995 return __o->compare_exchange_weak(*__e, __d, __s, __f); 996} 997 998template <class _Tp> 999inline _LIBCPP_INLINE_VISIBILITY 1000bool 1001atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d, 1002 memory_order __s, memory_order __f) _NOEXCEPT 1003{ 1004 return __o->compare_exchange_weak(*__e, __d, __s, __f); 1005} 1006 1007// atomic_compare_exchange_strong_explicit 1008 1009template <class _Tp> 1010inline _LIBCPP_INLINE_VISIBILITY 1011bool 1012atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o, 1013 _Tp* __e, _Tp __d, 1014 memory_order __s, memory_order __f) _NOEXCEPT 1015{ 1016 return __o->compare_exchange_strong(*__e, __d, __s, __f); 1017} 1018 1019template <class _Tp> 1020inline _LIBCPP_INLINE_VISIBILITY 1021bool 1022atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e, 1023 _Tp __d, 1024 memory_order __s, memory_order __f) _NOEXCEPT 1025{ 1026 return __o->compare_exchange_strong(*__e, __d, __s, __f); 1027} 1028 1029// atomic_fetch_add 1030 1031template <class _Tp> 1032inline _LIBCPP_INLINE_VISIBILITY 1033typename enable_if 1034< 1035 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1036 _Tp 1037>::type 1038atomic_fetch_add(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1039{ 1040 return __o->fetch_add(__op); 1041} 1042 1043template <class _Tp> 1044inline _LIBCPP_INLINE_VISIBILITY 1045typename enable_if 1046< 1047 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1048 _Tp 1049>::type 1050atomic_fetch_add(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1051{ 1052 return __o->fetch_add(__op); 1053} 1054 1055template <class _Tp> 1056inline _LIBCPP_INLINE_VISIBILITY 1057_Tp* 1058atomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT 1059{ 1060 return __o->fetch_add(__op); 1061} 1062 1063template <class _Tp> 1064inline _LIBCPP_INLINE_VISIBILITY 1065_Tp* 1066atomic_fetch_add(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT 1067{ 1068 return __o->fetch_add(__op); 1069} 1070 1071// atomic_fetch_add_explicit 1072 1073template <class _Tp> 1074inline _LIBCPP_INLINE_VISIBILITY 1075typename enable_if 1076< 1077 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1078 _Tp 1079>::type 1080atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1081{ 1082 return __o->fetch_add(__op, __m); 1083} 1084 1085template <class _Tp> 1086inline _LIBCPP_INLINE_VISIBILITY 1087typename enable_if 1088< 1089 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1090 _Tp 1091>::type 1092atomic_fetch_add_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1093{ 1094 return __o->fetch_add(__op, __m); 1095} 1096 1097template <class _Tp> 1098inline _LIBCPP_INLINE_VISIBILITY 1099_Tp* 1100atomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op, 1101 memory_order __m) _NOEXCEPT 1102{ 1103 return __o->fetch_add(__op, __m); 1104} 1105 1106template <class _Tp> 1107inline _LIBCPP_INLINE_VISIBILITY 1108_Tp* 1109atomic_fetch_add_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT 1110{ 1111 return __o->fetch_add(__op, __m); 1112} 1113 1114// atomic_fetch_sub 1115 1116template <class _Tp> 1117inline _LIBCPP_INLINE_VISIBILITY 1118typename enable_if 1119< 1120 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1121 _Tp 1122>::type 1123atomic_fetch_sub(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1124{ 1125 return __o->fetch_sub(__op); 1126} 1127 1128template <class _Tp> 1129inline _LIBCPP_INLINE_VISIBILITY 1130typename enable_if 1131< 1132 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1133 _Tp 1134>::type 1135atomic_fetch_sub(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1136{ 1137 return __o->fetch_sub(__op); 1138} 1139 1140template <class _Tp> 1141inline _LIBCPP_INLINE_VISIBILITY 1142_Tp* 1143atomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT 1144{ 1145 return __o->fetch_sub(__op); 1146} 1147 1148template <class _Tp> 1149inline _LIBCPP_INLINE_VISIBILITY 1150_Tp* 1151atomic_fetch_sub(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT 1152{ 1153 return __o->fetch_sub(__op); 1154} 1155 1156// atomic_fetch_sub_explicit 1157 1158template <class _Tp> 1159inline _LIBCPP_INLINE_VISIBILITY 1160typename enable_if 1161< 1162 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1163 _Tp 1164>::type 1165atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1166{ 1167 return __o->fetch_sub(__op, __m); 1168} 1169 1170template <class _Tp> 1171inline _LIBCPP_INLINE_VISIBILITY 1172typename enable_if 1173< 1174 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1175 _Tp 1176>::type 1177atomic_fetch_sub_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1178{ 1179 return __o->fetch_sub(__op, __m); 1180} 1181 1182template <class _Tp> 1183inline _LIBCPP_INLINE_VISIBILITY 1184_Tp* 1185atomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op, 1186 memory_order __m) _NOEXCEPT 1187{ 1188 return __o->fetch_sub(__op, __m); 1189} 1190 1191template <class _Tp> 1192inline _LIBCPP_INLINE_VISIBILITY 1193_Tp* 1194atomic_fetch_sub_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT 1195{ 1196 return __o->fetch_sub(__op, __m); 1197} 1198 1199// atomic_fetch_and 1200 1201template <class _Tp> 1202inline _LIBCPP_INLINE_VISIBILITY 1203typename enable_if 1204< 1205 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1206 _Tp 1207>::type 1208atomic_fetch_and(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1209{ 1210 return __o->fetch_and(__op); 1211} 1212 1213template <class _Tp> 1214inline _LIBCPP_INLINE_VISIBILITY 1215typename enable_if 1216< 1217 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1218 _Tp 1219>::type 1220atomic_fetch_and(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1221{ 1222 return __o->fetch_and(__op); 1223} 1224 1225// atomic_fetch_and_explicit 1226 1227template <class _Tp> 1228inline _LIBCPP_INLINE_VISIBILITY 1229typename enable_if 1230< 1231 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1232 _Tp 1233>::type 1234atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1235{ 1236 return __o->fetch_and(__op, __m); 1237} 1238 1239template <class _Tp> 1240inline _LIBCPP_INLINE_VISIBILITY 1241typename enable_if 1242< 1243 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1244 _Tp 1245>::type 1246atomic_fetch_and_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1247{ 1248 return __o->fetch_and(__op, __m); 1249} 1250 1251// atomic_fetch_or 1252 1253template <class _Tp> 1254inline _LIBCPP_INLINE_VISIBILITY 1255typename enable_if 1256< 1257 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1258 _Tp 1259>::type 1260atomic_fetch_or(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1261{ 1262 return __o->fetch_or(__op); 1263} 1264 1265template <class _Tp> 1266inline _LIBCPP_INLINE_VISIBILITY 1267typename enable_if 1268< 1269 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1270 _Tp 1271>::type 1272atomic_fetch_or(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1273{ 1274 return __o->fetch_or(__op); 1275} 1276 1277// atomic_fetch_or_explicit 1278 1279template <class _Tp> 1280inline _LIBCPP_INLINE_VISIBILITY 1281typename enable_if 1282< 1283 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1284 _Tp 1285>::type 1286atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1287{ 1288 return __o->fetch_or(__op, __m); 1289} 1290 1291template <class _Tp> 1292inline _LIBCPP_INLINE_VISIBILITY 1293typename enable_if 1294< 1295 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1296 _Tp 1297>::type 1298atomic_fetch_or_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1299{ 1300 return __o->fetch_or(__op, __m); 1301} 1302 1303// atomic_fetch_xor 1304 1305template <class _Tp> 1306inline _LIBCPP_INLINE_VISIBILITY 1307typename enable_if 1308< 1309 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1310 _Tp 1311>::type 1312atomic_fetch_xor(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1313{ 1314 return __o->fetch_xor(__op); 1315} 1316 1317template <class _Tp> 1318inline _LIBCPP_INLINE_VISIBILITY 1319typename enable_if 1320< 1321 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1322 _Tp 1323>::type 1324atomic_fetch_xor(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1325{ 1326 return __o->fetch_xor(__op); 1327} 1328 1329// atomic_fetch_xor_explicit 1330 1331template <class _Tp> 1332inline _LIBCPP_INLINE_VISIBILITY 1333typename enable_if 1334< 1335 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1336 _Tp 1337>::type 1338atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1339{ 1340 return __o->fetch_xor(__op, __m); 1341} 1342 1343template <class _Tp> 1344inline _LIBCPP_INLINE_VISIBILITY 1345typename enable_if 1346< 1347 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1348 _Tp 1349>::type 1350atomic_fetch_xor_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1351{ 1352 return __o->fetch_xor(__op, __m); 1353} 1354 1355// flag type and operations 1356 1357typedef struct atomic_flag 1358{ 1359 _Atomic(bool) __a_; 1360 1361 _LIBCPP_INLINE_VISIBILITY 1362 bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1363 {return __c11_atomic_exchange(&__a_, true, __m);} 1364 _LIBCPP_INLINE_VISIBILITY 1365 bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT 1366 {return __c11_atomic_exchange(&__a_, true, __m);} 1367 _LIBCPP_INLINE_VISIBILITY 1368 void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1369 {__c11_atomic_store(&__a_, false, __m);} 1370 _LIBCPP_INLINE_VISIBILITY 1371 void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT 1372 {__c11_atomic_store(&__a_, false, __m);} 1373 1374 _LIBCPP_INLINE_VISIBILITY 1375#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS 1376 atomic_flag() _NOEXCEPT = default; 1377#else 1378 atomic_flag() _NOEXCEPT : __a_() {} 1379#endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS 1380 1381 _LIBCPP_INLINE_VISIBILITY 1382 atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} 1383 1384#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS 1385 atomic_flag(const atomic_flag&) = delete; 1386 atomic_flag& operator=(const atomic_flag&) = delete; 1387 atomic_flag& operator=(const atomic_flag&) volatile = delete; 1388#else // _LIBCPP_HAS_NO_DELETED_FUNCTIONS 1389private: 1390 atomic_flag(const atomic_flag&); 1391 atomic_flag& operator=(const atomic_flag&); 1392 atomic_flag& operator=(const atomic_flag&) volatile; 1393#endif // _LIBCPP_HAS_NO_DELETED_FUNCTIONS 1394} atomic_flag; 1395 1396inline _LIBCPP_INLINE_VISIBILITY 1397bool 1398atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT 1399{ 1400 return __o->test_and_set(); 1401} 1402 1403inline _LIBCPP_INLINE_VISIBILITY 1404bool 1405atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT 1406{ 1407 return __o->test_and_set(); 1408} 1409 1410inline _LIBCPP_INLINE_VISIBILITY 1411bool 1412atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT 1413{ 1414 return __o->test_and_set(__m); 1415} 1416 1417inline _LIBCPP_INLINE_VISIBILITY 1418bool 1419atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT 1420{ 1421 return __o->test_and_set(__m); 1422} 1423 1424inline _LIBCPP_INLINE_VISIBILITY 1425void 1426atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT 1427{ 1428 __o->clear(); 1429} 1430 1431inline _LIBCPP_INLINE_VISIBILITY 1432void 1433atomic_flag_clear(atomic_flag* __o) _NOEXCEPT 1434{ 1435 __o->clear(); 1436} 1437 1438inline _LIBCPP_INLINE_VISIBILITY 1439void 1440atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT 1441{ 1442 __o->clear(__m); 1443} 1444 1445inline _LIBCPP_INLINE_VISIBILITY 1446void 1447atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT 1448{ 1449 __o->clear(__m); 1450} 1451 1452// fences 1453 1454inline _LIBCPP_INLINE_VISIBILITY 1455void 1456atomic_thread_fence(memory_order __m) _NOEXCEPT 1457{ 1458 __c11_atomic_thread_fence(__m); 1459} 1460 1461inline _LIBCPP_INLINE_VISIBILITY 1462void 1463atomic_signal_fence(memory_order __m) _NOEXCEPT 1464{ 1465 __c11_atomic_signal_fence(__m); 1466} 1467 1468// Atomics for standard typedef types 1469 1470typedef atomic<bool> atomic_bool; 1471typedef atomic<char> atomic_char; 1472typedef atomic<signed char> atomic_schar; 1473typedef atomic<unsigned char> atomic_uchar; 1474typedef atomic<short> atomic_short; 1475typedef atomic<unsigned short> atomic_ushort; 1476typedef atomic<int> atomic_int; 1477typedef atomic<unsigned int> atomic_uint; 1478typedef atomic<long> atomic_long; 1479typedef atomic<unsigned long> atomic_ulong; 1480typedef atomic<long long> atomic_llong; 1481typedef atomic<unsigned long long> atomic_ullong; 1482typedef atomic<char16_t> atomic_char16_t; 1483typedef atomic<char32_t> atomic_char32_t; 1484typedef atomic<wchar_t> atomic_wchar_t; 1485 1486typedef atomic<int_least8_t> atomic_int_least8_t; 1487typedef atomic<uint_least8_t> atomic_uint_least8_t; 1488typedef atomic<int_least16_t> atomic_int_least16_t; 1489typedef atomic<uint_least16_t> atomic_uint_least16_t; 1490typedef atomic<int_least32_t> atomic_int_least32_t; 1491typedef atomic<uint_least32_t> atomic_uint_least32_t; 1492typedef atomic<int_least64_t> atomic_int_least64_t; 1493typedef atomic<uint_least64_t> atomic_uint_least64_t; 1494 1495typedef atomic<int_fast8_t> atomic_int_fast8_t; 1496typedef atomic<uint_fast8_t> atomic_uint_fast8_t; 1497typedef atomic<int_fast16_t> atomic_int_fast16_t; 1498typedef atomic<uint_fast16_t> atomic_uint_fast16_t; 1499typedef atomic<int_fast32_t> atomic_int_fast32_t; 1500typedef atomic<uint_fast32_t> atomic_uint_fast32_t; 1501typedef atomic<int_fast64_t> atomic_int_fast64_t; 1502typedef atomic<uint_fast64_t> atomic_uint_fast64_t; 1503 1504typedef atomic<intptr_t> atomic_intptr_t; 1505typedef atomic<uintptr_t> atomic_uintptr_t; 1506typedef atomic<size_t> atomic_size_t; 1507typedef atomic<ptrdiff_t> atomic_ptrdiff_t; 1508typedef atomic<intmax_t> atomic_intmax_t; 1509typedef atomic<uintmax_t> atomic_uintmax_t; 1510 1511#define ATOMIC_FLAG_INIT {false} 1512#define ATOMIC_VAR_INIT(__v) {__v} 1513 1514// lock-free property 1515 1516#define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE 1517#define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE 1518#define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE 1519#define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE 1520#define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE 1521#define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE 1522#define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE 1523#define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE 1524#define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE 1525#define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE 1526 1527#endif // !__has_feature(cxx_atomic) 1528 1529_LIBCPP_END_NAMESPACE_STD 1530 1531#endif // _LIBCPP_ATOMIC 1532