3 // Copyright (C) 2008, 2009, 2010 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 #ifndef __GXX_EXPERIMENTAL_CXX0X__
38 # include <bits/c++0x_warning.h>
41 #include <bits/atomic_base.h>
42 #include <bits/atomic_0.h>
43 #include <bits/atomic_2.h>
45 namespace std _GLIBCXX_VISIBILITY(default)
47 _GLIBCXX_BEGIN_NAMESPACE_VERSION
55 // NB: No operators or fetch-operations for this type.
59 __atomic_base<bool> _M_base;
62 atomic_bool() = default;
63 ~atomic_bool() = default;
64 atomic_bool(const atomic_bool&) = delete;
65 atomic_bool& operator=(const atomic_bool&) = delete;
66 atomic_bool& operator=(const atomic_bool&) volatile = delete;
68 constexpr atomic_bool(bool __i) : _M_base(__i) { }
72 { return _M_base.operator=(__i); }
75 { return _M_base.load(); }
77 operator bool() const volatile
78 { return _M_base.load(); }
81 is_lock_free() const { return _M_base.is_lock_free(); }
84 is_lock_free() const volatile { return _M_base.is_lock_free(); }
87 store(bool __i, memory_order __m = memory_order_seq_cst)
88 { _M_base.store(__i, __m); }
91 store(bool __i, memory_order __m = memory_order_seq_cst) volatile
92 { _M_base.store(__i, __m); }
95 load(memory_order __m = memory_order_seq_cst) const
96 { return _M_base.load(__m); }
99 load(memory_order __m = memory_order_seq_cst) const volatile
100 { return _M_base.load(__m); }
103 exchange(bool __i, memory_order __m = memory_order_seq_cst)
104 { return _M_base.exchange(__i, __m); }
107 exchange(bool __i, memory_order __m = memory_order_seq_cst) volatile
108 { return _M_base.exchange(__i, __m); }
111 compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
113 { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
116 compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
117 memory_order __m2) volatile
118 { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
121 compare_exchange_weak(bool& __i1, bool __i2,
122 memory_order __m = memory_order_seq_cst)
123 { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
126 compare_exchange_weak(bool& __i1, bool __i2,
127 memory_order __m = memory_order_seq_cst) volatile
128 { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
131 compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
133 { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
136 compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
137 memory_order __m2) volatile
138 { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
141 compare_exchange_strong(bool& __i1, bool __i2,
142 memory_order __m = memory_order_seq_cst)
143 { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
146 compare_exchange_strong(bool& __i1, bool __i2,
147 memory_order __m = memory_order_seq_cst) volatile
148 { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
153 /// 29.4.3, Generic atomic type, primary class template.
154 template<typename _Tp>
163 atomic(const atomic&) = delete;
164 atomic& operator=(const atomic&) = delete;
165 atomic& operator=(const atomic&) volatile = delete;
167 constexpr atomic(_Tp __i) : _M_i(__i) { }
169 operator _Tp() const;
171 operator _Tp() const volatile;
174 operator=(_Tp __i) { store(__i); return __i; }
177 operator=(_Tp __i) volatile { store(__i); return __i; }
180 is_lock_free() const;
183 is_lock_free() const volatile;
186 store(_Tp, memory_order = memory_order_seq_cst);
189 store(_Tp, memory_order = memory_order_seq_cst) volatile;
192 load(memory_order = memory_order_seq_cst) const;
195 load(memory_order = memory_order_seq_cst) const volatile;
198 exchange(_Tp __i, memory_order = memory_order_seq_cst);
201 exchange(_Tp __i, memory_order = memory_order_seq_cst) volatile;
204 compare_exchange_weak(_Tp&, _Tp, memory_order, memory_order);
207 compare_exchange_weak(_Tp&, _Tp, memory_order, memory_order) volatile;
210 compare_exchange_weak(_Tp&, _Tp, memory_order = memory_order_seq_cst);
213 compare_exchange_weak(_Tp&, _Tp,
214 memory_order = memory_order_seq_cst) volatile;
217 compare_exchange_strong(_Tp&, _Tp, memory_order, memory_order);
220 compare_exchange_strong(_Tp&, _Tp, memory_order, memory_order) volatile;
223 compare_exchange_strong(_Tp&, _Tp, memory_order = memory_order_seq_cst);
226 compare_exchange_strong(_Tp&, _Tp,
227 memory_order = memory_order_seq_cst) volatile;
231 /// Partial specialization for pointer types.
232 template<typename _Tp>
233 struct atomic<_Tp*> : atomic_address
237 atomic(const atomic&) = delete;
238 atomic& operator=(const atomic&) volatile = delete;
240 constexpr atomic(_Tp* __v) : atomic_address(__v) { }
243 store(_Tp*, memory_order = memory_order_seq_cst);
246 store(_Tp*, memory_order = memory_order_seq_cst) volatile;
249 load(memory_order = memory_order_seq_cst) const;
252 load(memory_order = memory_order_seq_cst) const volatile;
255 exchange(_Tp*, memory_order = memory_order_seq_cst);
258 exchange(_Tp*, memory_order = memory_order_seq_cst) volatile;
261 compare_exchange_weak(_Tp*&, _Tp*, memory_order, memory_order);
264 compare_exchange_weak(_Tp*&, _Tp*, memory_order, memory_order) volatile;
267 compare_exchange_weak(_Tp*&, _Tp*, memory_order = memory_order_seq_cst);
270 compare_exchange_weak(_Tp*&, _Tp*,
271 memory_order = memory_order_seq_cst) volatile;
274 compare_exchange_strong(_Tp*&, _Tp*, memory_order, memory_order);
277 compare_exchange_strong(_Tp*&, _Tp*, memory_order, memory_order) volatile;
280 compare_exchange_strong(_Tp*&, _Tp*, memory_order = memory_order_seq_cst);
283 compare_exchange_strong(_Tp*&, _Tp*,
284 memory_order = memory_order_seq_cst) volatile;
287 fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst);
290 fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst) volatile;
293 fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst);
296 fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst) volatile;
298 operator _Tp*() const
301 operator _Tp*() const volatile
312 operator=(_Tp* __v) volatile
319 operator++(int) { return fetch_add(1); }
322 operator++(int) volatile { return fetch_add(1); }
325 operator--(int) { return fetch_sub(1); }
328 operator--(int) volatile { return fetch_sub(1); }
331 operator++() { return fetch_add(1) + 1; }
334 operator++() volatile { return fetch_add(1) + 1; }
337 operator--() { return fetch_sub(1) - 1; }
340 operator--() volatile { return fetch_sub(1) - 1; }
343 operator+=(ptrdiff_t __d)
344 { return fetch_add(__d) + __d; }
347 operator+=(ptrdiff_t __d) volatile
348 { return fetch_add(__d) + __d; }
351 operator-=(ptrdiff_t __d)
352 { return fetch_sub(__d) - __d; }
355 operator-=(ptrdiff_t __d) volatile
356 { return fetch_sub(__d) - __d; }
359 /// Explicit specialization for bool.
361 struct atomic<bool> : public atomic_bool
363 typedef bool __integral_type;
364 typedef atomic_bool __base_type;
368 atomic(const atomic&) = delete;
369 atomic& operator=(const atomic&) = delete;
370 atomic& operator=(const atomic&) volatile = delete;
372 constexpr atomic(__integral_type __i) : __base_type(__i) { }
374 using __base_type::operator __integral_type;
375 using __base_type::operator=;
378 /// Explicit specialization for char.
380 struct atomic<char> : public atomic_char
382 typedef char __integral_type;
383 typedef atomic_char __base_type;
387 atomic(const atomic&) = delete;
388 atomic& operator=(const atomic&) = delete;
389 atomic& operator=(const atomic&) volatile = delete;
391 constexpr atomic(__integral_type __i) : __base_type(__i) { }
393 using __base_type::operator __integral_type;
394 using __base_type::operator=;
397 /// Explicit specialization for signed char.
399 struct atomic<signed char> : public atomic_schar
401 typedef signed char __integral_type;
402 typedef atomic_schar __base_type;
406 atomic(const atomic&) = delete;
407 atomic& operator=(const atomic&) = delete;
408 atomic& operator=(const atomic&) volatile = delete;
410 constexpr atomic(__integral_type __i) : __base_type(__i) { }
412 using __base_type::operator __integral_type;
413 using __base_type::operator=;
416 /// Explicit specialization for unsigned char.
418 struct atomic<unsigned char> : public atomic_uchar
420 typedef unsigned char __integral_type;
421 typedef atomic_uchar __base_type;
425 atomic(const atomic&) = delete;
426 atomic& operator=(const atomic&) = delete;
427 atomic& operator=(const atomic&) volatile = delete;
429 constexpr atomic(__integral_type __i) : __base_type(__i) { }
431 using __base_type::operator __integral_type;
432 using __base_type::operator=;
435 /// Explicit specialization for short.
437 struct atomic<short> : public atomic_short
439 typedef short __integral_type;
440 typedef atomic_short __base_type;
444 atomic(const atomic&) = delete;
445 atomic& operator=(const atomic&) = delete;
446 atomic& operator=(const atomic&) volatile = delete;
448 constexpr atomic(__integral_type __i) : __base_type(__i) { }
450 using __base_type::operator __integral_type;
451 using __base_type::operator=;
454 /// Explicit specialization for unsigned short.
456 struct atomic<unsigned short> : public atomic_ushort
458 typedef unsigned short __integral_type;
459 typedef atomic_ushort __base_type;
463 atomic(const atomic&) = delete;
464 atomic& operator=(const atomic&) = delete;
465 atomic& operator=(const atomic&) volatile = delete;
467 constexpr atomic(__integral_type __i) : __base_type(__i) { }
469 using __base_type::operator __integral_type;
470 using __base_type::operator=;
473 /// Explicit specialization for int.
475 struct atomic<int> : atomic_int
477 typedef int __integral_type;
478 typedef atomic_int __base_type;
482 atomic(const atomic&) = delete;
483 atomic& operator=(const atomic&) = delete;
484 atomic& operator=(const atomic&) volatile = delete;
486 constexpr atomic(__integral_type __i) : __base_type(__i) { }
488 using __base_type::operator __integral_type;
489 using __base_type::operator=;
492 /// Explicit specialization for unsigned int.
494 struct atomic<unsigned int> : public atomic_uint
496 typedef unsigned int __integral_type;
497 typedef atomic_uint __base_type;
501 atomic(const atomic&) = delete;
502 atomic& operator=(const atomic&) = delete;
503 atomic& operator=(const atomic&) volatile = delete;
505 constexpr atomic(__integral_type __i) : __base_type(__i) { }
507 using __base_type::operator __integral_type;
508 using __base_type::operator=;
511 /// Explicit specialization for long.
513 struct atomic<long> : public atomic_long
515 typedef long __integral_type;
516 typedef atomic_long __base_type;
520 atomic(const atomic&) = delete;
521 atomic& operator=(const atomic&) = delete;
522 atomic& operator=(const atomic&) volatile = delete;
524 constexpr atomic(__integral_type __i) : __base_type(__i) { }
526 using __base_type::operator __integral_type;
527 using __base_type::operator=;
530 /// Explicit specialization for unsigned long.
532 struct atomic<unsigned long> : public atomic_ulong
534 typedef unsigned long __integral_type;
535 typedef atomic_ulong __base_type;
539 atomic(const atomic&) = delete;
540 atomic& operator=(const atomic&) = delete;
541 atomic& operator=(const atomic&) volatile = delete;
543 constexpr atomic(__integral_type __i) : __base_type(__i) { }
545 using __base_type::operator __integral_type;
546 using __base_type::operator=;
549 /// Explicit specialization for long long.
551 struct atomic<long long> : public atomic_llong
553 typedef long long __integral_type;
554 typedef atomic_llong __base_type;
558 atomic(const atomic&) = delete;
559 atomic& operator=(const atomic&) = delete;
560 atomic& operator=(const atomic&) volatile = delete;
562 constexpr atomic(__integral_type __i) : __base_type(__i) { }
564 using __base_type::operator __integral_type;
565 using __base_type::operator=;
568 /// Explicit specialization for unsigned long long.
570 struct atomic<unsigned long long> : public atomic_ullong
572 typedef unsigned long long __integral_type;
573 typedef atomic_ullong __base_type;
577 atomic(const atomic&) = delete;
578 atomic& operator=(const atomic&) = delete;
579 atomic& operator=(const atomic&) volatile = delete;
581 constexpr atomic(__integral_type __i) : __base_type(__i) { }
583 using __base_type::operator __integral_type;
584 using __base_type::operator=;
587 /// Explicit specialization for wchar_t.
589 struct atomic<wchar_t> : public atomic_wchar_t
591 typedef wchar_t __integral_type;
592 typedef atomic_wchar_t __base_type;
596 atomic(const atomic&) = delete;
597 atomic& operator=(const atomic&) = delete;
598 atomic& operator=(const atomic&) volatile = delete;
600 constexpr atomic(__integral_type __i) : __base_type(__i) { }
602 using __base_type::operator __integral_type;
603 using __base_type::operator=;
606 /// Explicit specialization for char16_t.
608 struct atomic<char16_t> : public atomic_char16_t
610 typedef char16_t __integral_type;
611 typedef atomic_char16_t __base_type;
615 atomic(const atomic&) = delete;
616 atomic& operator=(const atomic&) = delete;
617 atomic& operator=(const atomic&) volatile = delete;
619 constexpr atomic(__integral_type __i) : __base_type(__i) { }
621 using __base_type::operator __integral_type;
622 using __base_type::operator=;
625 /// Explicit specialization for char32_t.
627 struct atomic<char32_t> : public atomic_char32_t
629 typedef char32_t __integral_type;
630 typedef atomic_char32_t __base_type;
634 atomic(const atomic&) = delete;
635 atomic& operator=(const atomic&) = delete;
636 atomic& operator=(const atomic&) volatile = delete;
638 constexpr atomic(__integral_type __i) : __base_type(__i) { }
640 using __base_type::operator __integral_type;
641 using __base_type::operator=;
645 template<typename _Tp>
647 atomic<_Tp*>::load(memory_order __m) const
648 { return static_cast<_Tp*>(atomic_address::load(__m)); }
650 template<typename _Tp>
652 atomic<_Tp*>::load(memory_order __m) const volatile
653 { return static_cast<_Tp*>(atomic_address::load(__m)); }
655 template<typename _Tp>
657 atomic<_Tp*>::exchange(_Tp* __v, memory_order __m)
658 { return static_cast<_Tp*>(atomic_address::exchange(__v, __m)); }
660 template<typename _Tp>
662 atomic<_Tp*>::exchange(_Tp* __v, memory_order __m) volatile
663 { return static_cast<_Tp*>(atomic_address::exchange(__v, __m)); }
665 template<typename _Tp>
667 atomic<_Tp*>::compare_exchange_weak(_Tp*& __r, _Tp* __v, memory_order __m1,
670 void** __vr = reinterpret_cast<void**>(&__r);
671 void* __vv = static_cast<void*>(__v);
672 return atomic_address::compare_exchange_weak(*__vr, __vv, __m1, __m2);
675 template<typename _Tp>
677 atomic<_Tp*>::compare_exchange_weak(_Tp*& __r, _Tp* __v, memory_order __m1,
678 memory_order __m2) volatile
680 void** __vr = reinterpret_cast<void**>(&__r);
681 void* __vv = static_cast<void*>(__v);
682 return atomic_address::compare_exchange_weak(*__vr, __vv, __m1, __m2);
685 template<typename _Tp>
687 atomic<_Tp*>::compare_exchange_weak(_Tp*& __r, _Tp* __v, memory_order __m)
689 return compare_exchange_weak(__r, __v, __m,
690 __calculate_memory_order(__m));
693 template<typename _Tp>
695 atomic<_Tp*>::compare_exchange_weak(_Tp*& __r, _Tp* __v,
696 memory_order __m) volatile
698 return compare_exchange_weak(__r, __v, __m,
699 __calculate_memory_order(__m));
702 template<typename _Tp>
704 atomic<_Tp*>::compare_exchange_strong(_Tp*& __r, _Tp* __v,
708 void** __vr = reinterpret_cast<void**>(&__r);
709 void* __vv = static_cast<void*>(__v);
710 return atomic_address::compare_exchange_strong(*__vr, __vv, __m1, __m2);
713 template<typename _Tp>
715 atomic<_Tp*>::compare_exchange_strong(_Tp*& __r, _Tp* __v,
717 memory_order __m2) volatile
719 void** __vr = reinterpret_cast<void**>(&__r);
720 void* __vv = static_cast<void*>(__v);
721 return atomic_address::compare_exchange_strong(*__vr, __vv, __m1, __m2);
724 template<typename _Tp>
726 atomic<_Tp*>::compare_exchange_strong(_Tp*& __r, _Tp* __v,
729 return compare_exchange_strong(__r, __v, __m,
730 __calculate_memory_order(__m));
733 template<typename _Tp>
735 atomic<_Tp*>::compare_exchange_strong(_Tp*& __r, _Tp* __v,
736 memory_order __m) volatile
738 return compare_exchange_strong(__r, __v, __m,
739 __calculate_memory_order(__m));
742 template<typename _Tp>
744 atomic<_Tp*>::fetch_add(ptrdiff_t __d, memory_order __m)
746 void* __p = atomic_fetch_add_explicit(this, sizeof(_Tp) * __d, __m);
747 return static_cast<_Tp*>(__p);
750 template<typename _Tp>
752 atomic<_Tp*>::fetch_add(ptrdiff_t __d, memory_order __m) volatile
754 void* __p = atomic_fetch_add_explicit(this, sizeof(_Tp) * __d, __m);
755 return static_cast<_Tp*>(__p);
758 template<typename _Tp>
760 atomic<_Tp*>::fetch_sub(ptrdiff_t __d, memory_order __m)
762 void* __p = atomic_fetch_sub_explicit(this, sizeof(_Tp) * __d, __m);
763 return static_cast<_Tp*>(__p);
766 template<typename _Tp>
768 atomic<_Tp*>::fetch_sub(ptrdiff_t __d, memory_order __m) volatile
770 void* __p = atomic_fetch_sub_explicit(this, sizeof(_Tp) * __d, __m);
771 return static_cast<_Tp*>(__p);
775 // Function definitions, atomic_flag operations.
777 atomic_flag_test_and_set_explicit(atomic_flag* __a, memory_order __m)
778 { return __a->test_and_set(__m); }
781 atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
783 { return __a->test_and_set(__m); }
786 atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m)
790 atomic_flag_clear_explicit(volatile atomic_flag* __a, memory_order __m)
794 atomic_flag_test_and_set(atomic_flag* __a)
795 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
798 atomic_flag_test_and_set(volatile atomic_flag* __a)
799 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
802 atomic_flag_clear(atomic_flag* __a)
803 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
806 atomic_flag_clear(volatile atomic_flag* __a)
807 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
810 // Function definitions, atomic_address operations.
812 atomic_is_lock_free(const atomic_address* __a)
813 { return __a->is_lock_free(); }
816 atomic_is_lock_free(const volatile atomic_address* __a)
817 { return __a->is_lock_free(); }
820 atomic_init(atomic_address* __a, void* __v);
823 atomic_init(volatile atomic_address* __a, void* __v);
826 atomic_store_explicit(atomic_address* __a, void* __v, memory_order __m)
827 { __a->store(__v, __m); }
830 atomic_store_explicit(volatile atomic_address* __a, void* __v,
832 { __a->store(__v, __m); }
835 atomic_store(atomic_address* __a, void* __v)
839 atomic_store(volatile atomic_address* __a, void* __v)
843 atomic_load_explicit(const atomic_address* __a, memory_order __m)
844 { return __a->load(__m); }
847 atomic_load_explicit(const volatile atomic_address* __a, memory_order __m)
848 { return __a->load(__m); }
851 atomic_load(const atomic_address* __a)
852 { return __a->load(); }
855 atomic_load(const volatile atomic_address* __a)
856 { return __a->load(); }
859 atomic_exchange_explicit(atomic_address* __a, void* __v, memory_order __m)
860 { return __a->exchange(__v, __m); }
863 atomic_exchange_explicit(volatile atomic_address* __a, void* __v,
865 { return __a->exchange(__v, __m); }
868 atomic_exchange(atomic_address* __a, void* __v)
869 { return __a->exchange(__v); }
872 atomic_exchange(volatile atomic_address* __a, void* __v)
873 { return __a->exchange(__v); }
877 atomic_compare_exchange_weak_explicit(atomic_address* __a,
878 void** __v1, void* __v2,
879 memory_order __m1, memory_order __m2)
880 { return __a->compare_exchange_weak(*__v1, __v2, __m1, __m2); }
883 atomic_compare_exchange_weak_explicit(volatile atomic_address* __a,
884 void** __v1, void* __v2,
885 memory_order __m1, memory_order __m2)
886 { return __a->compare_exchange_weak(*__v1, __v2, __m1, __m2); }
889 atomic_compare_exchange_weak(atomic_address* __a, void** __v1, void* __v2)
891 return __a->compare_exchange_weak(*__v1, __v2, memory_order_seq_cst,
892 memory_order_seq_cst);
896 atomic_compare_exchange_weak(volatile atomic_address* __a, void** __v1,
899 return __a->compare_exchange_weak(*__v1, __v2, memory_order_seq_cst,
900 memory_order_seq_cst);
904 atomic_compare_exchange_strong_explicit(atomic_address* __a,
905 void** __v1, void* __v2,
906 memory_order __m1, memory_order __m2)
907 { return __a->compare_exchange_strong(*__v1, __v2, __m1, __m2); }
910 atomic_compare_exchange_strong_explicit(volatile atomic_address* __a,
911 void** __v1, void* __v2,
912 memory_order __m1, memory_order __m2)
913 { return __a->compare_exchange_strong(*__v1, __v2, __m1, __m2); }
916 atomic_compare_exchange_strong(atomic_address* __a, void** __v1, void* __v2)
918 return __a->compare_exchange_strong(*__v1, __v2, memory_order_seq_cst,
919 memory_order_seq_cst);
923 atomic_compare_exchange_strong(volatile atomic_address* __a,
924 void** __v1, void* __v2)
926 return __a->compare_exchange_strong(*__v1, __v2, memory_order_seq_cst,
927 memory_order_seq_cst);
931 atomic_fetch_add_explicit(atomic_address* __a, ptrdiff_t __d,
933 { return __a->fetch_add(__d, __m); }
936 atomic_fetch_add_explicit(volatile atomic_address* __a, ptrdiff_t __d,
938 { return __a->fetch_add(__d, __m); }
941 atomic_fetch_add(atomic_address* __a, ptrdiff_t __d)
942 { return __a->fetch_add(__d); }
945 atomic_fetch_add(volatile atomic_address* __a, ptrdiff_t __d)
946 { return __a->fetch_add(__d); }
949 atomic_fetch_sub_explicit(atomic_address* __a, ptrdiff_t __d,
951 { return __a->fetch_sub(__d, __m); }
954 atomic_fetch_sub_explicit(volatile atomic_address* __a, ptrdiff_t __d,
956 { return __a->fetch_sub(__d, __m); }
959 atomic_fetch_sub(atomic_address* __a, ptrdiff_t __d)
960 { return __a->fetch_sub(__d); }
963 atomic_fetch_sub(volatile atomic_address* __a, ptrdiff_t __d)
964 { return __a->fetch_sub(__d); }
967 // Function definitions, atomic_bool operations.
969 atomic_is_lock_free(const atomic_bool* __a)
970 { return __a->is_lock_free(); }
973 atomic_is_lock_free(const volatile atomic_bool* __a)
974 { return __a->is_lock_free(); }
977 atomic_init(atomic_bool* __a, bool __b);
980 atomic_init(volatile atomic_bool* __a, bool __b);
983 atomic_store_explicit(atomic_bool* __a, bool __i, memory_order __m)
984 { __a->store(__i, __m); }
987 atomic_store_explicit(volatile atomic_bool* __a, bool __i, memory_order __m)
988 { __a->store(__i, __m); }
991 atomic_store(atomic_bool* __a, bool __i)
995 atomic_store(volatile atomic_bool* __a, bool __i)
999 atomic_load_explicit(const atomic_bool* __a, memory_order __m)
1000 { return __a->load(__m); }
1003 atomic_load_explicit(const volatile atomic_bool* __a, memory_order __m)
1004 { return __a->load(__m); }
1007 atomic_load(const atomic_bool* __a)
1008 { return __a->load(); }
1011 atomic_load(const volatile atomic_bool* __a)
1012 { return __a->load(); }
1015 atomic_exchange_explicit(atomic_bool* __a, bool __i, memory_order __m)
1016 { return __a->exchange(__i, __m); }
1019 atomic_exchange_explicit(volatile atomic_bool* __a, bool __i,
1021 { return __a->exchange(__i, __m); }
1024 atomic_exchange(atomic_bool* __a, bool __i)
1025 { return __a->exchange(__i); }
1028 atomic_exchange(volatile atomic_bool* __a, bool __i)
1029 { return __a->exchange(__i); }
1032 atomic_compare_exchange_weak_explicit(atomic_bool* __a, bool* __i1,
1033 bool __i2, memory_order __m1,
1035 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
1038 atomic_compare_exchange_weak_explicit(volatile atomic_bool* __a, bool* __i1,
1039 bool __i2, memory_order __m1,
1041 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
1044 atomic_compare_exchange_weak(atomic_bool* __a, bool* __i1, bool __i2)
1046 return __a->compare_exchange_weak(*__i1, __i2, memory_order_seq_cst,
1047 memory_order_seq_cst);
1051 atomic_compare_exchange_weak(volatile atomic_bool* __a, bool* __i1, bool __i2)
1053 return __a->compare_exchange_weak(*__i1, __i2, memory_order_seq_cst,
1054 memory_order_seq_cst);
1058 atomic_compare_exchange_strong_explicit(atomic_bool* __a,
1059 bool* __i1, bool __i2,
1060 memory_order __m1, memory_order __m2)
1061 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
1064 atomic_compare_exchange_strong_explicit(volatile atomic_bool* __a,
1065 bool* __i1, bool __i2,
1066 memory_order __m1, memory_order __m2)
1067 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
1070 atomic_compare_exchange_strong(atomic_bool* __a, bool* __i1, bool __i2)
1072 return __a->compare_exchange_strong(*__i1, __i2, memory_order_seq_cst,
1073 memory_order_seq_cst);
1077 atomic_compare_exchange_strong(volatile atomic_bool* __a,
1078 bool* __i1, bool __i2)
1080 return __a->compare_exchange_strong(*__i1, __i2, memory_order_seq_cst,
1081 memory_order_seq_cst);
1085 // Function templates for atomic_integral operations, using
1086 // __atomic_base . Template argument should be constricted to
1087 // intergral types as specified in the standard.
1088 template<typename _ITp>
1090 atomic_is_lock_free(const __atomic_base<_ITp>* __a)
1091 { return __a->is_lock_free(); }
1093 template<typename _ITp>
1095 atomic_is_lock_free(const volatile __atomic_base<_ITp>* __a)
1096 { return __a->is_lock_free(); }
1098 template<typename _ITp>
1100 atomic_init(__atomic_base<_ITp>* __a, _ITp __i);
1102 template<typename _ITp>
1104 atomic_init(volatile __atomic_base<_ITp>* __a, _ITp __i);
1106 template<typename _ITp>
1108 atomic_store_explicit(__atomic_base<_ITp>* __a, _ITp __i, memory_order __m)
1109 { __a->store(__i, __m); }
1111 template<typename _ITp>
1113 atomic_store_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1115 { __a->store(__i, __m); }
1117 template<typename _ITp>
1119 atomic_load_explicit(const __atomic_base<_ITp>* __a, memory_order __m)
1120 { return __a->load(__m); }
1122 template<typename _ITp>
1124 atomic_load_explicit(const volatile __atomic_base<_ITp>* __a,
1126 { return __a->load(__m); }
1128 template<typename _ITp>
1130 atomic_exchange_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1132 { return __a->exchange(__i, __m); }
1134 template<typename _ITp>
1136 atomic_exchange_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1138 { return __a->exchange(__i, __m); }
1140 template<typename _ITp>
1142 atomic_compare_exchange_weak_explicit(__atomic_base<_ITp>* __a,
1143 _ITp* __i1, _ITp __i2,
1144 memory_order __m1, memory_order __m2)
1145 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
1147 template<typename _ITp>
1149 atomic_compare_exchange_weak_explicit(volatile __atomic_base<_ITp>* __a,
1150 _ITp* __i1, _ITp __i2,
1151 memory_order __m1, memory_order __m2)
1152 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
1154 template<typename _ITp>
1156 atomic_compare_exchange_strong_explicit(__atomic_base<_ITp>* __a,
1157 _ITp* __i1, _ITp __i2,
1160 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
1162 template<typename _ITp>
1164 atomic_compare_exchange_strong_explicit(volatile __atomic_base<_ITp>* __a,
1165 _ITp* __i1, _ITp __i2,
1168 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
1170 template<typename _ITp>
1172 atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1174 { return __a->fetch_add(__i, __m); }
1176 template<typename _ITp>
1178 atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1180 { return __a->fetch_add(__i, __m); }
1182 template<typename _ITp>
1184 atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1186 { return __a->fetch_sub(__i, __m); }
1188 template<typename _ITp>
1190 atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1192 { return __a->fetch_sub(__i, __m); }
1194 template<typename _ITp>
1196 atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1198 { return __a->fetch_and(__i, __m); }
1200 template<typename _ITp>
1202 atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1204 { return __a->fetch_and(__i, __m); }
1206 template<typename _ITp>
1208 atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1210 { return __a->fetch_or(__i, __m); }
1212 template<typename _ITp>
1214 atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1216 { return __a->fetch_or(__i, __m); }
1218 template<typename _ITp>
1220 atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1222 { return __a->fetch_xor(__i, __m); }
1224 template<typename _ITp>
1226 atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1228 { return __a->fetch_xor(__i, __m); }
1230 template<typename _ITp>
1232 atomic_store(__atomic_base<_ITp>* __a, _ITp __i)
1233 { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
1235 template<typename _ITp>
1237 atomic_store(volatile __atomic_base<_ITp>* __a, _ITp __i)
1238 { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
1240 template<typename _ITp>
1242 atomic_load(const __atomic_base<_ITp>* __a)
1243 { return atomic_load_explicit(__a, memory_order_seq_cst); }
1245 template<typename _ITp>
1247 atomic_load(const volatile __atomic_base<_ITp>* __a)
1248 { return atomic_load_explicit(__a, memory_order_seq_cst); }
1250 template<typename _ITp>
1252 atomic_exchange(__atomic_base<_ITp>* __a, _ITp __i)
1253 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
1255 template<typename _ITp>
1257 atomic_exchange(volatile __atomic_base<_ITp>* __a, _ITp __i)
1258 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
1260 template<typename _ITp>
1262 atomic_compare_exchange_weak(__atomic_base<_ITp>* __a,
1263 _ITp* __i1, _ITp __i2)
1265 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
1266 memory_order_seq_cst,
1267 memory_order_seq_cst);
1270 template<typename _ITp>
1272 atomic_compare_exchange_weak(volatile __atomic_base<_ITp>* __a,
1273 _ITp* __i1, _ITp __i2)
1275 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
1276 memory_order_seq_cst,
1277 memory_order_seq_cst);
1280 template<typename _ITp>
1282 atomic_compare_exchange_strong(__atomic_base<_ITp>* __a,
1283 _ITp* __i1, _ITp __i2)
1285 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
1286 memory_order_seq_cst,
1287 memory_order_seq_cst);
1290 template<typename _ITp>
1292 atomic_compare_exchange_strong(volatile __atomic_base<_ITp>* __a,
1293 _ITp* __i1, _ITp __i2)
1295 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
1296 memory_order_seq_cst,
1297 memory_order_seq_cst);
1300 template<typename _ITp>
1302 atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i)
1303 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1305 template<typename _ITp>
1307 atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i)
1308 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1310 template<typename _ITp>
1312 atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i)
1313 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1315 template<typename _ITp>
1317 atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i)
1318 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1320 template<typename _ITp>
1322 atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i)
1323 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1325 template<typename _ITp>
1327 atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i)
1328 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1330 template<typename _ITp>
1332 atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i)
1333 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1335 template<typename _ITp>
1337 atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i)
1338 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1340 template<typename _ITp>
1342 atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i)
1343 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1345 template<typename _ITp>
1347 atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i)
1348 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1352 _GLIBCXX_END_NAMESPACE_VERSION