3 // Copyright (C) 2008-2014 Free Software Foundation, Inc.
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)
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.
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.
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/>.
25 /** @file include/atomic
26 * This is a Standard C++ Library header.
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
32 #ifndef _GLIBCXX_ATOMIC
33 #define _GLIBCXX_ATOMIC 1
35 #pragma GCC system_header
37 #if __cplusplus < 201103L
38 # include <bits/c++0x_warning.h>
41 #include <bits/atomic_base.h>
43 namespace std _GLIBCXX_VISIBILITY(default)
45 _GLIBCXX_BEGIN_NAMESPACE_VERSION
53 // NB: No operators or fetch-operations for this type.
57 __atomic_base<bool> _M_base;
60 atomic_bool() noexcept = default;
61 ~atomic_bool() noexcept = default;
62 atomic_bool(const atomic_bool&) = delete;
63 atomic_bool& operator=(const atomic_bool&) = delete;
64 atomic_bool& operator=(const atomic_bool&) volatile = delete;
66 constexpr atomic_bool(bool __i) noexcept : _M_base(__i) { }
69 operator=(bool __i) noexcept
70 { return _M_base.operator=(__i); }
73 operator=(bool __i) volatile noexcept
74 { return _M_base.operator=(__i); }
76 operator bool() const noexcept
77 { return _M_base.load(); }
79 operator bool() const volatile noexcept
80 { return _M_base.load(); }
83 is_lock_free() const noexcept { return _M_base.is_lock_free(); }
86 is_lock_free() const volatile noexcept { return _M_base.is_lock_free(); }
89 store(bool __i, memory_order __m = memory_order_seq_cst) noexcept
90 { _M_base.store(__i, __m); }
93 store(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept
94 { _M_base.store(__i, __m); }
97 load(memory_order __m = memory_order_seq_cst) const noexcept
98 { return _M_base.load(__m); }
101 load(memory_order __m = memory_order_seq_cst) const volatile noexcept
102 { return _M_base.load(__m); }
105 exchange(bool __i, memory_order __m = memory_order_seq_cst) noexcept
106 { return _M_base.exchange(__i, __m); }
110 memory_order __m = memory_order_seq_cst) volatile noexcept
111 { return _M_base.exchange(__i, __m); }
114 compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
115 memory_order __m2) noexcept
116 { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
119 compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
120 memory_order __m2) volatile noexcept
121 { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
124 compare_exchange_weak(bool& __i1, bool __i2,
125 memory_order __m = memory_order_seq_cst) noexcept
126 { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
129 compare_exchange_weak(bool& __i1, bool __i2,
130 memory_order __m = memory_order_seq_cst) volatile noexcept
131 { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
134 compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
135 memory_order __m2) noexcept
136 { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
139 compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
140 memory_order __m2) volatile noexcept
141 { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
144 compare_exchange_strong(bool& __i1, bool __i2,
145 memory_order __m = memory_order_seq_cst) noexcept
146 { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
149 compare_exchange_strong(bool& __i1, bool __i2,
150 memory_order __m = memory_order_seq_cst) volatile noexcept
151 { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
156 * @brief Generic atomic type, primary class template.
158 * @tparam _Tp Type to be made atomic, must be trivally copyable.
160 template<typename _Tp>
164 // Align 1/2/4/8/16-byte types the same as integer types of that size.
165 // This matches the alignment effects of the C11 _Atomic qualifier.
166 static constexpr int _S_min_alignment
167 = sizeof(_Tp) == sizeof(char) ? alignof(char)
168 : sizeof(_Tp) == sizeof(short) ? alignof(short)
169 : sizeof(_Tp) == sizeof(int) ? alignof(int)
170 : sizeof(_Tp) == sizeof(long) ? alignof(long)
171 : sizeof(_Tp) == sizeof(long long) ? alignof(long long)
172 #ifdef _GLIBCXX_USE_INT128
173 : sizeof(_Tp) == sizeof(__int128) ? alignof(__int128)
177 static constexpr int _S_alignment
178 = _S_min_alignment > alignof(_Tp) ? _S_min_alignment : alignof(_Tp);
180 alignas(_S_alignment) _Tp _M_i;
183 atomic() noexcept = default;
184 ~atomic() noexcept = default;
185 atomic(const atomic&) = delete;
186 atomic& operator=(const atomic&) = delete;
187 atomic& operator=(const atomic&) volatile = delete;
189 constexpr atomic(_Tp __i) noexcept : _M_i(__i) { }
191 operator _Tp() const noexcept
194 operator _Tp() const volatile noexcept
198 operator=(_Tp __i) noexcept
199 { store(__i); return __i; }
202 operator=(_Tp __i) volatile noexcept
203 { store(__i); return __i; }
206 is_lock_free() const noexcept
207 { return __atomic_is_lock_free(sizeof(_M_i), nullptr); }
210 is_lock_free() const volatile noexcept
211 { return __atomic_is_lock_free(sizeof(_M_i), nullptr); }
214 store(_Tp __i, memory_order _m = memory_order_seq_cst) noexcept
215 { __atomic_store(&_M_i, &__i, _m); }
218 store(_Tp __i, memory_order _m = memory_order_seq_cst) volatile noexcept
219 { __atomic_store(&_M_i, &__i, _m); }
222 load(memory_order _m = memory_order_seq_cst) const noexcept
225 __atomic_load(&_M_i, &tmp, _m);
230 load(memory_order _m = memory_order_seq_cst) const volatile noexcept
233 __atomic_load(&_M_i, &tmp, _m);
238 exchange(_Tp __i, memory_order _m = memory_order_seq_cst) noexcept
241 __atomic_exchange(&_M_i, &__i, &tmp, _m);
247 memory_order _m = memory_order_seq_cst) volatile noexcept
250 __atomic_exchange(&_M_i, &__i, &tmp, _m);
255 compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
256 memory_order __f) noexcept
258 return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f);
262 compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
263 memory_order __f) volatile noexcept
265 return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f);
269 compare_exchange_weak(_Tp& __e, _Tp __i,
270 memory_order __m = memory_order_seq_cst) noexcept
271 { return compare_exchange_weak(__e, __i, __m,
272 __cmpexch_failure_order(__m)); }
275 compare_exchange_weak(_Tp& __e, _Tp __i,
276 memory_order __m = memory_order_seq_cst) volatile noexcept
277 { return compare_exchange_weak(__e, __i, __m,
278 __cmpexch_failure_order(__m)); }
281 compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
282 memory_order __f) noexcept
284 return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f);
288 compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
289 memory_order __f) volatile noexcept
291 return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f);
295 compare_exchange_strong(_Tp& __e, _Tp __i,
296 memory_order __m = memory_order_seq_cst) noexcept
297 { return compare_exchange_strong(__e, __i, __m,
298 __cmpexch_failure_order(__m)); }
301 compare_exchange_strong(_Tp& __e, _Tp __i,
302 memory_order __m = memory_order_seq_cst) volatile noexcept
303 { return compare_exchange_strong(__e, __i, __m,
304 __cmpexch_failure_order(__m)); }
308 /// Partial specialization for pointer types.
309 template<typename _Tp>
312 typedef _Tp* __pointer_type;
313 typedef __atomic_base<_Tp*> __base_type;
316 atomic() noexcept = default;
317 ~atomic() noexcept = default;
318 atomic(const atomic&) = delete;
319 atomic& operator=(const atomic&) = delete;
320 atomic& operator=(const atomic&) volatile = delete;
322 constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { }
324 operator __pointer_type() const noexcept
325 { return __pointer_type(_M_b); }
327 operator __pointer_type() const volatile noexcept
328 { return __pointer_type(_M_b); }
331 operator=(__pointer_type __p) noexcept
332 { return _M_b.operator=(__p); }
335 operator=(__pointer_type __p) volatile noexcept
336 { return _M_b.operator=(__p); }
339 operator++(int) noexcept
343 operator++(int) volatile noexcept
347 operator--(int) noexcept
351 operator--(int) volatile noexcept
355 operator++() noexcept
359 operator++() volatile noexcept
363 operator--() noexcept
367 operator--() volatile noexcept
371 operator+=(ptrdiff_t __d) noexcept
372 { return _M_b.operator+=(__d); }
375 operator+=(ptrdiff_t __d) volatile noexcept
376 { return _M_b.operator+=(__d); }
379 operator-=(ptrdiff_t __d) noexcept
380 { return _M_b.operator-=(__d); }
383 operator-=(ptrdiff_t __d) volatile noexcept
384 { return _M_b.operator-=(__d); }
387 is_lock_free() const noexcept
388 { return _M_b.is_lock_free(); }
391 is_lock_free() const volatile noexcept
392 { return _M_b.is_lock_free(); }
395 store(__pointer_type __p,
396 memory_order __m = memory_order_seq_cst) noexcept
397 { return _M_b.store(__p, __m); }
400 store(__pointer_type __p,
401 memory_order __m = memory_order_seq_cst) volatile noexcept
402 { return _M_b.store(__p, __m); }
405 load(memory_order __m = memory_order_seq_cst) const noexcept
406 { return _M_b.load(__m); }
409 load(memory_order __m = memory_order_seq_cst) const volatile noexcept
410 { return _M_b.load(__m); }
413 exchange(__pointer_type __p,
414 memory_order __m = memory_order_seq_cst) noexcept
415 { return _M_b.exchange(__p, __m); }
418 exchange(__pointer_type __p,
419 memory_order __m = memory_order_seq_cst) volatile noexcept
420 { return _M_b.exchange(__p, __m); }
423 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
424 memory_order __m1, memory_order __m2) noexcept
425 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
428 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
430 memory_order __m2) volatile noexcept
431 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
434 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
435 memory_order __m = memory_order_seq_cst) noexcept
437 return compare_exchange_weak(__p1, __p2, __m,
438 __cmpexch_failure_order(__m));
442 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
443 memory_order __m = memory_order_seq_cst) volatile noexcept
445 return compare_exchange_weak(__p1, __p2, __m,
446 __cmpexch_failure_order(__m));
450 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
451 memory_order __m1, memory_order __m2) noexcept
452 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
455 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
457 memory_order __m2) volatile noexcept
458 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
461 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
462 memory_order __m = memory_order_seq_cst) noexcept
464 return _M_b.compare_exchange_strong(__p1, __p2, __m,
465 __cmpexch_failure_order(__m));
469 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
470 memory_order __m = memory_order_seq_cst) volatile noexcept
472 return _M_b.compare_exchange_strong(__p1, __p2, __m,
473 __cmpexch_failure_order(__m));
477 fetch_add(ptrdiff_t __d,
478 memory_order __m = memory_order_seq_cst) noexcept
479 { return _M_b.fetch_add(__d, __m); }
482 fetch_add(ptrdiff_t __d,
483 memory_order __m = memory_order_seq_cst) volatile noexcept
484 { return _M_b.fetch_add(__d, __m); }
487 fetch_sub(ptrdiff_t __d,
488 memory_order __m = memory_order_seq_cst) noexcept
489 { return _M_b.fetch_sub(__d, __m); }
492 fetch_sub(ptrdiff_t __d,
493 memory_order __m = memory_order_seq_cst) volatile noexcept
494 { return _M_b.fetch_sub(__d, __m); }
498 /// Explicit specialization for bool.
500 struct atomic<bool> : public atomic_bool
502 typedef bool __integral_type;
503 typedef atomic_bool __base_type;
505 atomic() noexcept = default;
506 ~atomic() noexcept = default;
507 atomic(const atomic&) = delete;
508 atomic& operator=(const atomic&) = delete;
509 atomic& operator=(const atomic&) volatile = delete;
511 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
513 using __base_type::operator __integral_type;
514 using __base_type::operator=;
517 /// Explicit specialization for char.
519 struct atomic<char> : public atomic_char
521 typedef char __integral_type;
522 typedef atomic_char __base_type;
524 atomic() noexcept = default;
525 ~atomic() noexcept = default;
526 atomic(const atomic&) = delete;
527 atomic& operator=(const atomic&) = delete;
528 atomic& operator=(const atomic&) volatile = delete;
530 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
532 using __base_type::operator __integral_type;
533 using __base_type::operator=;
536 /// Explicit specialization for signed char.
538 struct atomic<signed char> : public atomic_schar
540 typedef signed char __integral_type;
541 typedef atomic_schar __base_type;
543 atomic() noexcept= default;
544 ~atomic() noexcept = default;
545 atomic(const atomic&) = delete;
546 atomic& operator=(const atomic&) = delete;
547 atomic& operator=(const atomic&) volatile = delete;
549 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
551 using __base_type::operator __integral_type;
552 using __base_type::operator=;
555 /// Explicit specialization for unsigned char.
557 struct atomic<unsigned char> : public atomic_uchar
559 typedef unsigned char __integral_type;
560 typedef atomic_uchar __base_type;
562 atomic() noexcept= default;
563 ~atomic() noexcept = default;
564 atomic(const atomic&) = delete;
565 atomic& operator=(const atomic&) = delete;
566 atomic& operator=(const atomic&) volatile = delete;
568 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
570 using __base_type::operator __integral_type;
571 using __base_type::operator=;
574 /// Explicit specialization for short.
576 struct atomic<short> : public atomic_short
578 typedef short __integral_type;
579 typedef atomic_short __base_type;
581 atomic() noexcept = default;
582 ~atomic() noexcept = default;
583 atomic(const atomic&) = delete;
584 atomic& operator=(const atomic&) = delete;
585 atomic& operator=(const atomic&) volatile = delete;
587 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
589 using __base_type::operator __integral_type;
590 using __base_type::operator=;
593 /// Explicit specialization for unsigned short.
595 struct atomic<unsigned short> : public atomic_ushort
597 typedef unsigned short __integral_type;
598 typedef atomic_ushort __base_type;
600 atomic() noexcept = default;
601 ~atomic() noexcept = default;
602 atomic(const atomic&) = delete;
603 atomic& operator=(const atomic&) = delete;
604 atomic& operator=(const atomic&) volatile = delete;
606 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
608 using __base_type::operator __integral_type;
609 using __base_type::operator=;
612 /// Explicit specialization for int.
614 struct atomic<int> : atomic_int
616 typedef int __integral_type;
617 typedef atomic_int __base_type;
619 atomic() noexcept = default;
620 ~atomic() noexcept = default;
621 atomic(const atomic&) = delete;
622 atomic& operator=(const atomic&) = delete;
623 atomic& operator=(const atomic&) volatile = delete;
625 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
627 using __base_type::operator __integral_type;
628 using __base_type::operator=;
631 /// Explicit specialization for unsigned int.
633 struct atomic<unsigned int> : public atomic_uint
635 typedef unsigned int __integral_type;
636 typedef atomic_uint __base_type;
638 atomic() noexcept = default;
639 ~atomic() noexcept = default;
640 atomic(const atomic&) = delete;
641 atomic& operator=(const atomic&) = delete;
642 atomic& operator=(const atomic&) volatile = delete;
644 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
646 using __base_type::operator __integral_type;
647 using __base_type::operator=;
650 /// Explicit specialization for long.
652 struct atomic<long> : public atomic_long
654 typedef long __integral_type;
655 typedef atomic_long __base_type;
657 atomic() noexcept = default;
658 ~atomic() noexcept = default;
659 atomic(const atomic&) = delete;
660 atomic& operator=(const atomic&) = delete;
661 atomic& operator=(const atomic&) volatile = delete;
663 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
665 using __base_type::operator __integral_type;
666 using __base_type::operator=;
669 /// Explicit specialization for unsigned long.
671 struct atomic<unsigned long> : public atomic_ulong
673 typedef unsigned long __integral_type;
674 typedef atomic_ulong __base_type;
676 atomic() noexcept = default;
677 ~atomic() noexcept = default;
678 atomic(const atomic&) = delete;
679 atomic& operator=(const atomic&) = delete;
680 atomic& operator=(const atomic&) volatile = delete;
682 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
684 using __base_type::operator __integral_type;
685 using __base_type::operator=;
688 /// Explicit specialization for long long.
690 struct atomic<long long> : public atomic_llong
692 typedef long long __integral_type;
693 typedef atomic_llong __base_type;
695 atomic() noexcept = default;
696 ~atomic() noexcept = default;
697 atomic(const atomic&) = delete;
698 atomic& operator=(const atomic&) = delete;
699 atomic& operator=(const atomic&) volatile = delete;
701 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
703 using __base_type::operator __integral_type;
704 using __base_type::operator=;
707 /// Explicit specialization for unsigned long long.
709 struct atomic<unsigned long long> : public atomic_ullong
711 typedef unsigned long long __integral_type;
712 typedef atomic_ullong __base_type;
714 atomic() noexcept = default;
715 ~atomic() noexcept = default;
716 atomic(const atomic&) = delete;
717 atomic& operator=(const atomic&) = delete;
718 atomic& operator=(const atomic&) volatile = delete;
720 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
722 using __base_type::operator __integral_type;
723 using __base_type::operator=;
726 /// Explicit specialization for wchar_t.
728 struct atomic<wchar_t> : public atomic_wchar_t
730 typedef wchar_t __integral_type;
731 typedef atomic_wchar_t __base_type;
733 atomic() noexcept = default;
734 ~atomic() noexcept = default;
735 atomic(const atomic&) = delete;
736 atomic& operator=(const atomic&) = delete;
737 atomic& operator=(const atomic&) volatile = delete;
739 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
741 using __base_type::operator __integral_type;
742 using __base_type::operator=;
745 /// Explicit specialization for char16_t.
747 struct atomic<char16_t> : public atomic_char16_t
749 typedef char16_t __integral_type;
750 typedef atomic_char16_t __base_type;
752 atomic() noexcept = default;
753 ~atomic() noexcept = default;
754 atomic(const atomic&) = delete;
755 atomic& operator=(const atomic&) = delete;
756 atomic& operator=(const atomic&) volatile = delete;
758 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
760 using __base_type::operator __integral_type;
761 using __base_type::operator=;
764 /// Explicit specialization for char32_t.
766 struct atomic<char32_t> : public atomic_char32_t
768 typedef char32_t __integral_type;
769 typedef atomic_char32_t __base_type;
771 atomic() noexcept = default;
772 ~atomic() noexcept = default;
773 atomic(const atomic&) = delete;
774 atomic& operator=(const atomic&) = delete;
775 atomic& operator=(const atomic&) volatile = delete;
777 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
779 using __base_type::operator __integral_type;
780 using __base_type::operator=;
784 // Function definitions, atomic_flag operations.
786 atomic_flag_test_and_set_explicit(atomic_flag* __a,
787 memory_order __m) noexcept
788 { return __a->test_and_set(__m); }
791 atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
792 memory_order __m) noexcept
793 { return __a->test_and_set(__m); }
796 atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept
800 atomic_flag_clear_explicit(volatile atomic_flag* __a,
801 memory_order __m) noexcept
805 atomic_flag_test_and_set(atomic_flag* __a) noexcept
806 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
809 atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept
810 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
813 atomic_flag_clear(atomic_flag* __a) noexcept
814 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
817 atomic_flag_clear(volatile atomic_flag* __a) noexcept
818 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
821 // Function templates generally applicable to atomic types.
822 template<typename _ITp>
824 atomic_is_lock_free(const atomic<_ITp>* __a) noexcept
825 { return __a->is_lock_free(); }
827 template<typename _ITp>
829 atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept
830 { return __a->is_lock_free(); }
832 template<typename _ITp>
834 atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept
835 { __a->store(__i, memory_order_relaxed); }
837 template<typename _ITp>
839 atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept
840 { __a->store(__i, memory_order_relaxed); }
842 template<typename _ITp>
844 atomic_store_explicit(atomic<_ITp>* __a, _ITp __i,
845 memory_order __m) noexcept
846 { __a->store(__i, __m); }
848 template<typename _ITp>
850 atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i,
851 memory_order __m) noexcept
852 { __a->store(__i, __m); }
854 template<typename _ITp>
856 atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept
857 { return __a->load(__m); }
859 template<typename _ITp>
861 atomic_load_explicit(const volatile atomic<_ITp>* __a,
862 memory_order __m) noexcept
863 { return __a->load(__m); }
865 template<typename _ITp>
867 atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i,
868 memory_order __m) noexcept
869 { return __a->exchange(__i, __m); }
871 template<typename _ITp>
873 atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i,
874 memory_order __m) noexcept
875 { return __a->exchange(__i, __m); }
877 template<typename _ITp>
879 atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a,
880 _ITp* __i1, _ITp __i2,
882 memory_order __m2) noexcept
883 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
885 template<typename _ITp>
887 atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a,
888 _ITp* __i1, _ITp __i2,
890 memory_order __m2) noexcept
891 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
893 template<typename _ITp>
895 atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a,
896 _ITp* __i1, _ITp __i2,
898 memory_order __m2) noexcept
899 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
901 template<typename _ITp>
903 atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a,
904 _ITp* __i1, _ITp __i2,
906 memory_order __m2) noexcept
907 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
910 template<typename _ITp>
912 atomic_store(atomic<_ITp>* __a, _ITp __i) noexcept
913 { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
915 template<typename _ITp>
917 atomic_store(volatile atomic<_ITp>* __a, _ITp __i) noexcept
918 { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
920 template<typename _ITp>
922 atomic_load(const atomic<_ITp>* __a) noexcept
923 { return atomic_load_explicit(__a, memory_order_seq_cst); }
925 template<typename _ITp>
927 atomic_load(const volatile atomic<_ITp>* __a) noexcept
928 { return atomic_load_explicit(__a, memory_order_seq_cst); }
930 template<typename _ITp>
932 atomic_exchange(atomic<_ITp>* __a, _ITp __i) noexcept
933 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
935 template<typename _ITp>
937 atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i) noexcept
938 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
940 template<typename _ITp>
942 atomic_compare_exchange_weak(atomic<_ITp>* __a,
943 _ITp* __i1, _ITp __i2) noexcept
945 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
946 memory_order_seq_cst,
947 memory_order_seq_cst);
950 template<typename _ITp>
952 atomic_compare_exchange_weak(volatile atomic<_ITp>* __a,
953 _ITp* __i1, _ITp __i2) noexcept
955 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
956 memory_order_seq_cst,
957 memory_order_seq_cst);
960 template<typename _ITp>
962 atomic_compare_exchange_strong(atomic<_ITp>* __a,
963 _ITp* __i1, _ITp __i2) noexcept
965 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
966 memory_order_seq_cst,
967 memory_order_seq_cst);
970 template<typename _ITp>
972 atomic_compare_exchange_strong(volatile atomic<_ITp>* __a,
973 _ITp* __i1, _ITp __i2) noexcept
975 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
976 memory_order_seq_cst,
977 memory_order_seq_cst);
980 // Function templates for atomic_integral operations only, using
981 // __atomic_base. Template argument should be constricted to
982 // intergral types as specified in the standard, excluding address
984 template<typename _ITp>
986 atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i,
987 memory_order __m) noexcept
988 { return __a->fetch_add(__i, __m); }
990 template<typename _ITp>
992 atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
993 memory_order __m) noexcept
994 { return __a->fetch_add(__i, __m); }
996 template<typename _ITp>
998 atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i,
999 memory_order __m) noexcept
1000 { return __a->fetch_sub(__i, __m); }
1002 template<typename _ITp>
1004 atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1005 memory_order __m) noexcept
1006 { return __a->fetch_sub(__i, __m); }
1008 template<typename _ITp>
1010 atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1011 memory_order __m) noexcept
1012 { return __a->fetch_and(__i, __m); }
1014 template<typename _ITp>
1016 atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1017 memory_order __m) noexcept
1018 { return __a->fetch_and(__i, __m); }
1020 template<typename _ITp>
1022 atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1023 memory_order __m) noexcept
1024 { return __a->fetch_or(__i, __m); }
1026 template<typename _ITp>
1028 atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1029 memory_order __m) noexcept
1030 { return __a->fetch_or(__i, __m); }
1032 template<typename _ITp>
1034 atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1035 memory_order __m) noexcept
1036 { return __a->fetch_xor(__i, __m); }
1038 template<typename _ITp>
1040 atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1041 memory_order __m) noexcept
1042 { return __a->fetch_xor(__i, __m); }
1044 template<typename _ITp>
1046 atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1047 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1049 template<typename _ITp>
1051 atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1052 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1054 template<typename _ITp>
1056 atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1057 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1059 template<typename _ITp>
1061 atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1062 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1064 template<typename _ITp>
1066 atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1067 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1069 template<typename _ITp>
1071 atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1072 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1074 template<typename _ITp>
1076 atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1077 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1079 template<typename _ITp>
1081 atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1082 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1084 template<typename _ITp>
1086 atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1087 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1089 template<typename _ITp>
1091 atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1092 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1095 // Partial specializations for pointers.
1096 template<typename _ITp>
1098 atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
1099 memory_order __m) noexcept
1100 { return __a->fetch_add(__d, __m); }
1102 template<typename _ITp>
1104 atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d,
1105 memory_order __m) noexcept
1106 { return __a->fetch_add(__d, __m); }
1108 template<typename _ITp>
1110 atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1111 { return __a->fetch_add(__d); }
1113 template<typename _ITp>
1115 atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1116 { return __a->fetch_add(__d); }
1118 template<typename _ITp>
1120 atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a,
1121 ptrdiff_t __d, memory_order __m) noexcept
1122 { return __a->fetch_sub(__d, __m); }
1124 template<typename _ITp>
1126 atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
1127 memory_order __m) noexcept
1128 { return __a->fetch_sub(__d, __m); }
1130 template<typename _ITp>
1132 atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1133 { return __a->fetch_sub(__d); }
1135 template<typename _ITp>
1137 atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1138 { return __a->fetch_sub(__d); }
1141 _GLIBCXX_END_NAMESPACE_VERSION