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