1 // -*- C++ -*- header. 2 3 // Copyright (C) 2008, 2009 4 // Free Software Foundation, Inc. 5 // 6 // This file is part of the GNU ISO C++ Library. This library is free 7 // software; you can redistribute it and/or modify it under the 8 // terms of the GNU General Public License as published by the 9 // Free Software Foundation; either version 3, or (at your option) 10 // any later version. 11 12 // This library is distributed in the hope that it will be useful, 13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 // GNU General Public License for more details. 16 17 // Under Section 7 of GPL version 3, you are granted additional 18 // permissions described in the GCC Runtime Library Exception, version 19 // 3.1, as published by the Free Software Foundation. 20 21 // You should have received a copy of the GNU General Public License and 22 // a copy of the GCC Runtime Library Exception along with this program; 23 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24 // <http://www.gnu.org/licenses/>. 25 26 /** @file cstdatomic 27 * This is a Standard C++ Library file. You should @c #include this file 28 * in your programs, rather than any of the "*.h" implementation files. 29 * 30 * This is the C++ version of the Standard C Library header @c stdatomic.h, 31 * and its contents are (mostly) the same as that header, but are all 32 * contained in the namespace @c std (except for names which are defined 33 * as macros in C). 34 */ 35 36 // Based on "C++ Atomic Types and Operations" by Hans Boehm and Lawrence Crowl. 37 // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html 38 39 #ifndef _GLIBCXX_STDATOMIC 40 #define _GLIBCXX_STDATOMIC 1 41 42 #pragma GCC system_header 43 44 #ifndef __GXX_EXPERIMENTAL_CXX0X__ 45 # include <c++0x_warning.h> 46 #endif 47 48 #include <stdatomic.h> 49 #include <cstddef> 50 51 _GLIBCXX_BEGIN_NAMESPACE(std) 52 53 /** 54 * @addtogroup atomics 55 * @{ 56 */ 57 58 /// kill_dependency 59 template<typename _Tp> 60 inline _Tp 61 kill_dependency(_Tp __y) 62 { 63 _Tp ret(__y); 64 return ret; 65 } 66 67 inline memory_order 68 __calculate_memory_order(memory_order __m) 69 { 70 const bool __cond1 = __m == memory_order_release; 71 const bool __cond2 = __m == memory_order_acq_rel; 72 memory_order __mo1(__cond1 ? memory_order_relaxed : __m); 73 memory_order __mo2(__cond2 ? memory_order_acquire : __mo1); 74 return __mo2; 75 } 76 77 // 78 // Three nested namespaces for atomic implementation details. 79 // 80 // The nested namespace inlined into std:: is determined by the value 81 // of the _GLIBCXX_ATOMIC_PROPERTY macro and the resulting 82 // ATOMIC_*_LOCK_FREE macros. See file stdatomic.h. 83 // 84 // 0 == __atomic0 == Never lock-free 85 // 1 == __atomic1 == Best available, sometimes lock-free 86 // 2 == __atomic2 == Always lock-free 87 #include <bits/atomic_0.h> 88 #include <bits/atomic_2.h> 89 90 /// atomic 91 /// 29.4.3, Generic atomic type, primary class template. 92 template<typename _Tp> 93 struct atomic 94 { 95 private: 96 _Tp _M_i; 97 98 public: 99 atomic() = default; 100 ~atomic() = default; 101 atomic(const atomic&) = delete; 102 atomic& operator=(const atomic&) = delete; 103 104 atomic(_Tp __i) : _M_i(__i) { } 105 106 operator _Tp() const volatile; 107 108 _Tp 109 operator=(_Tp __i) volatile { store(__i); return __i; } 110 111 bool 112 is_lock_free() const volatile; 113 114 void 115 store(_Tp, memory_order = memory_order_seq_cst) volatile; 116 117 _Tp 118 load(memory_order = memory_order_seq_cst) const volatile; 119 120 _Tp 121 exchange(_Tp __i, memory_order = memory_order_seq_cst) volatile; 122 123 bool 124 compare_exchange_weak(_Tp&, _Tp, memory_order, memory_order) volatile; 125 126 bool 127 compare_exchange_strong(_Tp&, _Tp, memory_order, memory_order) volatile; 128 129 bool 130 compare_exchange_weak(_Tp&, _Tp, 131 memory_order = memory_order_seq_cst) volatile; 132 133 bool 134 compare_exchange_strong(_Tp&, _Tp, 135 memory_order = memory_order_seq_cst) volatile; 136 }; 137 138 139 /// Partial specialization for pointer types. 140 template<typename _Tp> 141 struct atomic<_Tp*> : atomic_address 142 { 143 atomic() = default; 144 ~atomic() = default; 145 atomic(const atomic&) = delete; 146 atomic& operator=(const atomic&) = delete; 147 148 atomic(_Tp* __v) : atomic_address(__v) { } 149 150 void 151 store(_Tp*, memory_order = memory_order_seq_cst) volatile; 152 153 _Tp* 154 load(memory_order = memory_order_seq_cst) const volatile; 155 156 _Tp* 157 exchange(_Tp*, memory_order = memory_order_seq_cst) volatile; 158 159 bool 160 compare_exchange_weak(_Tp*&, _Tp*, memory_order, memory_order) volatile; 161 162 bool 163 compare_exchange_strong(_Tp*&, _Tp*, memory_order, memory_order) volatile; 164 165 bool 166 compare_exchange_weak(_Tp*&, _Tp*, 167 memory_order = memory_order_seq_cst) volatile; 168 169 bool 170 compare_exchange_strong(_Tp*&, _Tp*, 171 memory_order = memory_order_seq_cst) volatile; 172 173 _Tp* 174 fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst) volatile; 175 176 _Tp* 177 fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst) volatile; 178 179 operator _Tp*() const volatile 180 { return load(); } 181 182 _Tp* 183 operator=(_Tp* __v) volatile 184 { 185 store(__v); 186 return __v; 187 } 188 189 _Tp* 190 operator++(int) volatile { return fetch_add(1); } 191 192 _Tp* 193 operator--(int) volatile { return fetch_sub(1); } 194 195 _Tp* 196 operator++() volatile { return fetch_add(1) + 1; } 197 198 _Tp* 199 operator--() volatile { return fetch_sub(1) - 1; } 200 201 _Tp* 202 operator+=(ptrdiff_t __d) volatile 203 { return fetch_add(__d) + __d; } 204 205 _Tp* 206 operator-=(ptrdiff_t __d) volatile 207 { return fetch_sub(__d) - __d; } 208 }; 209 210 211 /// Explicit specialization for void* 212 template<> 213 struct atomic<void*> : public atomic_address 214 { 215 typedef void* __integral_type; 216 typedef atomic_address __base_type; 217 218 atomic() = default; 219 ~atomic() = default; 220 atomic(const atomic&) = delete; 221 atomic& operator=(const atomic&) = delete; 222 223 atomic(__integral_type __i) : __base_type(__i) { } 224 225 using __base_type::operator __integral_type; 226 using __base_type::operator=; 227 }; 228 229 /// Explicit specialization for bool. 230 template<> 231 struct atomic<bool> : public atomic_bool 232 { 233 typedef bool __integral_type; 234 typedef atomic_bool __base_type; 235 236 atomic() = default; 237 ~atomic() = default; 238 atomic(const atomic&) = delete; 239 atomic& operator=(const atomic&) = delete; 240 241 atomic(__integral_type __i) : __base_type(__i) { } 242 243 using __base_type::operator __integral_type; 244 using __base_type::operator=; 245 }; 246 247 /// Explicit specialization for char. 248 template<> 249 struct atomic<char> : public atomic_char 250 { 251 typedef char __integral_type; 252 typedef atomic_char __base_type; 253 254 atomic() = default; 255 ~atomic() = default; 256 atomic(const atomic&) = delete; 257 atomic& operator=(const atomic&) = delete; 258 259 atomic(__integral_type __i) : __base_type(__i) { } 260 261 using __base_type::operator __integral_type; 262 using __base_type::operator=; 263 }; 264 265 /// Explicit specialization for signed char. 266 template<> 267 struct atomic<signed char> : public atomic_schar 268 { 269 typedef signed char __integral_type; 270 typedef atomic_schar __base_type; 271 272 atomic() = default; 273 ~atomic() = default; 274 atomic(const atomic&) = delete; 275 atomic& operator=(const atomic&) = delete; 276 277 atomic(__integral_type __i) : __base_type(__i) { } 278 279 using __base_type::operator __integral_type; 280 using __base_type::operator=; 281 }; 282 283 /// Explicit specialization for unsigned char. 284 template<> 285 struct atomic<unsigned char> : public atomic_uchar 286 { 287 typedef unsigned char __integral_type; 288 typedef atomic_uchar __base_type; 289 290 atomic() = default; 291 ~atomic() = default; 292 atomic(const atomic&) = delete; 293 atomic& operator=(const atomic&) = delete; 294 295 atomic(__integral_type __i) : __base_type(__i) { } 296 297 using __base_type::operator __integral_type; 298 using __base_type::operator=; 299 }; 300 301 /// Explicit specialization for short. 302 template<> 303 struct atomic<short> : public atomic_short 304 { 305 typedef short __integral_type; 306 typedef atomic_short __base_type; 307 308 atomic() = default; 309 ~atomic() = default; 310 atomic(const atomic&) = delete; 311 atomic& operator=(const atomic&) = delete; 312 313 atomic(__integral_type __i) : __base_type(__i) { } 314 315 using __base_type::operator __integral_type; 316 using __base_type::operator=; 317 }; 318 319 /// Explicit specialization for unsigned short. 320 template<> 321 struct atomic<unsigned short> : public atomic_ushort 322 { 323 typedef unsigned short __integral_type; 324 typedef atomic_ushort __base_type; 325 326 atomic() = default; 327 ~atomic() = default; 328 atomic(const atomic&) = delete; 329 atomic& operator=(const atomic&) = delete; 330 331 atomic(__integral_type __i) : __base_type(__i) { } 332 333 using __base_type::operator __integral_type; 334 using __base_type::operator=; 335 }; 336 337 /// Explicit specialization for int. 338 template<> 339 struct atomic<int> : atomic_int 340 { 341 typedef int __integral_type; 342 typedef atomic_int __base_type; 343 344 atomic() = default; 345 ~atomic() = default; 346 atomic(const atomic&) = delete; 347 atomic& operator=(const atomic&) = delete; 348 349 atomic(__integral_type __i) : __base_type(__i) { } 350 351 using __base_type::operator __integral_type; 352 using __base_type::operator=; 353 }; 354 355 /// Explicit specialization for unsigned int. 356 template<> 357 struct atomic<unsigned int> : public atomic_uint 358 { 359 typedef unsigned int __integral_type; 360 typedef atomic_uint __base_type; 361 362 atomic() = default; 363 ~atomic() = default; 364 atomic(const atomic&) = delete; 365 atomic& operator=(const atomic&) = delete; 366 367 atomic(__integral_type __i) : __base_type(__i) { } 368 369 using __base_type::operator __integral_type; 370 using __base_type::operator=; 371 }; 372 373 /// Explicit specialization for long. 374 template<> 375 struct atomic<long> : public atomic_long 376 { 377 typedef long __integral_type; 378 typedef atomic_long __base_type; 379 380 atomic() = default; 381 ~atomic() = default; 382 atomic(const atomic&) = delete; 383 atomic& operator=(const atomic&) = delete; 384 385 atomic(__integral_type __i) : __base_type(__i) { } 386 387 using __base_type::operator __integral_type; 388 using __base_type::operator=; 389 }; 390 391 /// Explicit specialization for unsigned long. 392 template<> 393 struct atomic<unsigned long> : public atomic_ulong 394 { 395 typedef unsigned long __integral_type; 396 typedef atomic_ulong __base_type; 397 398 atomic() = default; 399 ~atomic() = default; 400 atomic(const atomic&) = delete; 401 atomic& operator=(const atomic&) = delete; 402 403 atomic(__integral_type __i) : __base_type(__i) { } 404 405 using __base_type::operator __integral_type; 406 using __base_type::operator=; 407 }; 408 409 /// Explicit specialization for long long. 410 template<> 411 struct atomic<long long> : public atomic_llong 412 { 413 typedef long long __integral_type; 414 typedef atomic_llong __base_type; 415 416 atomic() = default; 417 ~atomic() = default; 418 atomic(const atomic&) = delete; 419 atomic& operator=(const atomic&) = delete; 420 421 atomic(__integral_type __i) : __base_type(__i) { } 422 423 using __base_type::operator __integral_type; 424 using __base_type::operator=; 425 }; 426 427 /// Explicit specialization for unsigned long long. 428 template<> 429 struct atomic<unsigned long long> : public atomic_ullong 430 { 431 typedef unsigned long long __integral_type; 432 typedef atomic_ullong __base_type; 433 434 atomic() = default; 435 ~atomic() = default; 436 atomic(const atomic&) = delete; 437 atomic& operator=(const atomic&) = delete; 438 439 atomic(__integral_type __i) : __base_type(__i) { } 440 441 using __base_type::operator __integral_type; 442 using __base_type::operator=; 443 }; 444 445 /// Explicit specialization for wchar_t. 446 template<> 447 struct atomic<wchar_t> : public atomic_wchar_t 448 { 449 typedef wchar_t __integral_type; 450 typedef atomic_wchar_t __base_type; 451 452 atomic() = default; 453 ~atomic() = default; 454 atomic(const atomic&) = delete; 455 atomic& operator=(const atomic&) = delete; 456 457 atomic(__integral_type __i) : __base_type(__i) { } 458 459 using __base_type::operator __integral_type; 460 using __base_type::operator=; 461 }; 462 463 /// Explicit specialization for char16_t. 464 template<> 465 struct atomic<char16_t> : public atomic_char16_t 466 { 467 typedef char16_t __integral_type; 468 typedef atomic_char16_t __base_type; 469 470 atomic() = default; 471 ~atomic() = default; 472 atomic(const atomic&) = delete; 473 atomic& operator=(const atomic&) = delete; 474 475 atomic(__integral_type __i) : __base_type(__i) { } 476 477 using __base_type::operator __integral_type; 478 using __base_type::operator=; 479 }; 480 481 /// Explicit specialization for char32_t. 482 template<> 483 struct atomic<char32_t> : public atomic_char32_t 484 { 485 typedef char32_t __integral_type; 486 typedef atomic_char32_t __base_type; 487 488 atomic() = default; 489 ~atomic() = default; 490 atomic(const atomic&) = delete; 491 atomic& operator=(const atomic&) = delete; 492 493 atomic(__integral_type __i) : __base_type(__i) { } 494 495 using __base_type::operator __integral_type; 496 using __base_type::operator=; 497 }; 498 499 500 template<typename _Tp> 501 _Tp* 502 atomic<_Tp*>::load(memory_order __m) const volatile 503 { return static_cast<_Tp*>(atomic_address::load(__m)); } 504 505 template<typename _Tp> 506 _Tp* 507 atomic<_Tp*>::exchange(_Tp* __v, memory_order __m) volatile 508 { return static_cast<_Tp*>(atomic_address::exchange(__v, __m)); } 509 510 template<typename _Tp> 511 bool 512 atomic<_Tp*>::compare_exchange_weak(_Tp*& __r, _Tp* __v, memory_order __m1, 513 memory_order __m2) volatile 514 { 515 void** __vr = reinterpret_cast<void**>(&__r); 516 void* __vv = static_cast<void*>(__v); 517 return atomic_address::compare_exchange_weak(*__vr, __vv, __m1, __m2); 518 } 519 520 template<typename _Tp> 521 bool 522 atomic<_Tp*>::compare_exchange_strong(_Tp*& __r, _Tp* __v, 523 memory_order __m1, 524 memory_order __m2) volatile 525 { 526 void** __vr = reinterpret_cast<void**>(&__r); 527 void* __vv = static_cast<void*>(__v); 528 return atomic_address::compare_exchange_strong(*__vr, __vv, __m1, __m2); 529 } 530 531 template<typename _Tp> 532 bool 533 atomic<_Tp*>::compare_exchange_weak(_Tp*& __r, _Tp* __v, 534 memory_order __m) volatile 535 { 536 return compare_exchange_weak(__r, __v, __m, 537 __calculate_memory_order(__m)); 538 } 539 540 template<typename _Tp> 541 bool 542 atomic<_Tp*>::compare_exchange_strong(_Tp*& __r, _Tp* __v, 543 memory_order __m) volatile 544 { 545 return compare_exchange_strong(__r, __v, __m, 546 __calculate_memory_order(__m)); 547 } 548 549 template<typename _Tp> 550 _Tp* 551 atomic<_Tp*>::fetch_add(ptrdiff_t __d, memory_order __m) volatile 552 { 553 void* __p = atomic_fetch_add_explicit(this, sizeof(_Tp) * __d, __m); 554 return static_cast<_Tp*>(__p); 555 } 556 557 template<typename _Tp> 558 _Tp* 559 atomic<_Tp*>::fetch_sub(ptrdiff_t __d, memory_order __m) volatile 560 { 561 void* __p = atomic_fetch_sub_explicit(this, sizeof(_Tp) * __d, __m); 562 return static_cast<_Tp*>(__p); 563 } 564 565 // Convenience function definitions, atomic_flag. 566 inline bool 567 atomic_flag_test_and_set_explicit(volatile atomic_flag* __a, memory_order __m) 568 { return __a->test_and_set(__m); } 569 570 inline void 571 atomic_flag_clear_explicit(volatile atomic_flag* __a, memory_order __m) 572 { return __a->clear(__m); } 573 574 575 // Convenience function definitions, atomic_address. 576 inline bool 577 atomic_is_lock_free(const volatile atomic_address* __a) 578 { return __a->is_lock_free(); } 579 580 inline void 581 atomic_store(volatile atomic_address* __a, void* __v) 582 { __a->store(__v); } 583 584 inline void 585 atomic_store_explicit(volatile atomic_address* __a, void* __v, 586 memory_order __m) 587 { __a->store(__v, __m); } 588 589 inline void* 590 atomic_load(const volatile atomic_address* __a) 591 { return __a->load(); } 592 593 inline void* 594 atomic_load_explicit(const volatile atomic_address* __a, memory_order __m) 595 { return __a->load(__m); } 596 597 inline void* 598 atomic_exchange(volatile atomic_address* __a, void* __v) 599 { return __a->exchange(__v); } 600 601 inline void* 602 atomic_exchange_explicit(volatile atomic_address* __a, void* __v, 603 memory_order __m) 604 { return __a->exchange(__v, __m); } 605 606 inline bool 607 atomic_compare_exchange_weak(volatile atomic_address* __a, 608 void** __v1, void* __v2) 609 { 610 return __a->compare_exchange_weak(*__v1, __v2, memory_order_seq_cst, 611 memory_order_seq_cst); 612 } 613 614 inline bool 615 atomic_compare_exchange_strong(volatile atomic_address* __a, 616 void** __v1, void* __v2) 617 { 618 return __a->compare_exchange_strong(*__v1, __v2, memory_order_seq_cst, 619 memory_order_seq_cst); 620 } 621 622 inline bool 623 atomic_compare_exchange_weak_explicit(volatile atomic_address* __a, 624 void** __v1, void* __v2, 625 memory_order __m1, memory_order __m2) 626 { return __a->compare_exchange_weak(*__v1, __v2, __m1, __m2); } 627 628 inline bool 629 atomic_compare_exchange_strong_explicit(volatile atomic_address* __a, 630 void** __v1, void* __v2, 631 memory_order __m1, memory_order __m2) 632 { return __a->compare_exchange_strong(*__v1, __v2, __m1, __m2); } 633 634 inline void* 635 atomic_fetch_add_explicit(volatile atomic_address* __a, ptrdiff_t __d, 636 memory_order __m) 637 { return __a->fetch_add(__d, __m); } 638 639 inline void* 640 atomic_fetch_add(volatile atomic_address* __a, ptrdiff_t __d) 641 { return __a->fetch_add(__d); } 642 643 inline void* 644 atomic_fetch_sub_explicit(volatile atomic_address* __a, ptrdiff_t __d, 645 memory_order __m) 646 { return __a->fetch_sub(__d, __m); } 647 648 inline void* 649 atomic_fetch_sub(volatile atomic_address* __a, ptrdiff_t __d) 650 { return __a->fetch_sub(__d); } 651 652 653 // Convenience function definitions, atomic_bool. 654 inline bool 655 atomic_is_lock_free(const volatile atomic_bool* __a) 656 { return __a->is_lock_free(); } 657 658 inline void 659 atomic_store(volatile atomic_bool* __a, bool __i) 660 { __a->store(__i); } 661 662 inline void 663 atomic_store_explicit(volatile atomic_bool* __a, bool __i, memory_order __m) 664 { __a->store(__i, __m); } 665 666 inline bool 667 atomic_load(const volatile atomic_bool* __a) 668 { return __a->load(); } 669 670 inline bool 671 atomic_load_explicit(const volatile atomic_bool* __a, memory_order __m) 672 { return __a->load(__m); } 673 674 inline bool 675 atomic_exchange(volatile atomic_bool* __a, bool __i) 676 { return __a->exchange(__i); } 677 678 inline bool 679 atomic_exchange_explicit(volatile atomic_bool* __a, bool __i, 680 memory_order __m) 681 { return __a->exchange(__i, __m); } 682 683 inline bool 684 atomic_compare_exchange_weak(volatile atomic_bool* __a, bool* __i1, bool __i2) 685 { 686 return __a->compare_exchange_weak(*__i1, __i2, memory_order_seq_cst, 687 memory_order_seq_cst); 688 } 689 690 inline bool 691 atomic_compare_exchange_strong(volatile atomic_bool* __a, 692 bool* __i1, bool __i2) 693 { 694 return __a->compare_exchange_strong(*__i1, __i2, memory_order_seq_cst, 695 memory_order_seq_cst); 696 } 697 698 inline bool 699 atomic_compare_exchange_weak_explicit(volatile atomic_bool* __a, bool* __i1, 700 bool __i2, memory_order __m1, 701 memory_order __m2) 702 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } 703 704 inline bool 705 atomic_compare_exchange_strong_explicit(volatile atomic_bool* __a, 706 bool* __i1, bool __i2, 707 memory_order __m1, memory_order __m2) 708 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } 709 710 711 712 // Free standing functions. Template argument should be constricted 713 // to intergral types as specified in the standard. 714 template<typename _ITp> 715 inline void 716 atomic_store_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 717 memory_order __m) 718 { __a->store(__i, __m); } 719 720 template<typename _ITp> 721 inline _ITp 722 atomic_load_explicit(const volatile __atomic_base<_ITp>* __a, 723 memory_order __m) 724 { return __a->load(__m); } 725 726 template<typename _ITp> 727 inline _ITp 728 atomic_exchange_explicit(volatile __atomic_base<_ITp>* __a, 729 _ITp __i, memory_order __m) 730 { return __a->exchange(__i, __m); } 731 732 template<typename _ITp> 733 inline bool 734 atomic_compare_exchange_weak_explicit(volatile __atomic_base<_ITp>* __a, 735 _ITp* __i1, _ITp __i2, 736 memory_order __m1, memory_order __m2) 737 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } 738 739 template<typename _ITp> 740 inline bool 741 atomic_compare_exchange_strong_explicit(volatile __atomic_base<_ITp>* __a, 742 _ITp* __i1, _ITp __i2, 743 memory_order __m1, 744 memory_order __m2) 745 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } 746 747 template<typename _ITp> 748 inline _ITp 749 atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 750 memory_order __m) 751 { return __a->fetch_add(__i, __m); } 752 753 template<typename _ITp> 754 inline _ITp 755 atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 756 memory_order __m) 757 { return __a->fetch_sub(__i, __m); } 758 759 template<typename _ITp> 760 inline _ITp 761 atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 762 memory_order __m) 763 { return __a->fetch_and(__i, __m); } 764 765 template<typename _ITp> 766 inline _ITp 767 atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 768 memory_order __m) 769 { return __a->fetch_or(__i, __m); } 770 771 template<typename _ITp> 772 inline _ITp 773 atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 774 memory_order __m) 775 { return __a->fetch_xor(__i, __m); } 776 777 template<typename _ITp> 778 inline bool 779 atomic_is_lock_free(const volatile __atomic_base<_ITp>* __a) 780 { return __a->is_lock_free(); } 781 782 template<typename _ITp> 783 inline void 784 atomic_store(volatile __atomic_base<_ITp>* __a, _ITp __i) 785 { atomic_store_explicit(__a, __i, memory_order_seq_cst); } 786 787 template<typename _ITp> 788 inline _ITp 789 atomic_load(const volatile __atomic_base<_ITp>* __a) 790 { return atomic_load_explicit(__a, memory_order_seq_cst); } 791 792 template<typename _ITp> 793 inline _ITp 794 atomic_exchange(volatile __atomic_base<_ITp>* __a, _ITp __i) 795 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); } 796 797 template<typename _ITp> 798 inline bool 799 atomic_compare_exchange_weak(volatile __atomic_base<_ITp>* __a, 800 _ITp* __i1, _ITp __i2) 801 { 802 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2, 803 memory_order_seq_cst, 804 memory_order_seq_cst); 805 } 806 807 template<typename _ITp> 808 inline bool 809 atomic_compare_exchange_strong(volatile __atomic_base<_ITp>* __a, 810 _ITp* __i1, _ITp __i2) 811 { 812 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2, 813 memory_order_seq_cst, 814 memory_order_seq_cst); 815 } 816 817 template<typename _ITp> 818 inline _ITp 819 atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) 820 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); } 821 822 template<typename _ITp> 823 inline _ITp 824 atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) 825 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); } 826 827 template<typename _ITp> 828 inline _ITp 829 atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) 830 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); } 831 832 template<typename _ITp> 833 inline _ITp 834 atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) 835 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); } 836 837 template<typename _ITp> 838 inline _ITp 839 atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) 840 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); } 841 842 // @} group atomics 843 844 _GLIBCXX_END_NAMESPACE 845 846 #endif 847 848 849