libstdc++
atomic
Go to the documentation of this file.
00001 // -*- C++ -*- header.
00002 
00003 // Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file include/atomic
00026  *  This is a Standard C++ Library header.
00027  */
00028 
00029 // Based on "C++ Atomic Types and Operations" by Hans Boehm and Lawrence Crowl.
00030 // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html
00031 
00032 #ifndef _GLIBCXX_ATOMIC
00033 #define _GLIBCXX_ATOMIC 1
00034 
00035 #pragma GCC system_header
00036 
00037 #ifndef __GXX_EXPERIMENTAL_CXX0X__
00038 # include <bits/c++0x_warning.h>
00039 #endif
00040 
00041 #include <bits/atomic_base.h>
00042 #include <bits/atomic_0.h>
00043 #include <bits/atomic_2.h>
00044 
00045 namespace std _GLIBCXX_VISIBILITY(default)
00046 {
00047 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00048 
00049   /**
00050    * @addtogroup atomics
00051    * @{
00052    */
00053 
00054   /// atomic_bool
00055   // NB: No operators or fetch-operations for this type.
00056   struct atomic_bool
00057   {
00058   private:
00059     __atomic_base<bool> _M_base;
00060 
00061   public:
00062     atomic_bool() = default;
00063     ~atomic_bool() = default;
00064     atomic_bool(const atomic_bool&) = delete;
00065     atomic_bool& operator=(const atomic_bool&) = delete;
00066     atomic_bool& operator=(const atomic_bool&) volatile = delete;
00067 
00068     constexpr atomic_bool(bool __i) : _M_base(__i) { }
00069 
00070     bool
00071     operator=(bool __i)
00072     { return _M_base.operator=(__i); }
00073 
00074     operator bool() const
00075     { return _M_base.load(); }
00076 
00077     operator bool() const volatile
00078     { return _M_base.load(); }
00079 
00080     bool
00081     is_lock_free() const { return _M_base.is_lock_free(); }
00082 
00083     bool
00084     is_lock_free() const volatile { return _M_base.is_lock_free(); }
00085 
00086     void
00087     store(bool __i, memory_order __m = memory_order_seq_cst)
00088     { _M_base.store(__i, __m); }
00089 
00090     void
00091     store(bool __i, memory_order __m = memory_order_seq_cst) volatile
00092     { _M_base.store(__i, __m); }
00093 
00094     bool
00095     load(memory_order __m = memory_order_seq_cst) const
00096     { return _M_base.load(__m); }
00097 
00098     bool
00099     load(memory_order __m = memory_order_seq_cst) const volatile
00100     { return _M_base.load(__m); }
00101 
00102     bool
00103     exchange(bool __i, memory_order __m = memory_order_seq_cst)
00104     { return _M_base.exchange(__i, __m); }
00105 
00106     bool
00107     exchange(bool __i, memory_order __m = memory_order_seq_cst) volatile
00108     { return _M_base.exchange(__i, __m); }
00109 
00110     bool
00111     compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
00112               memory_order __m2)
00113     { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
00114 
00115     bool
00116     compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
00117               memory_order __m2) volatile
00118     { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
00119 
00120     bool
00121     compare_exchange_weak(bool& __i1, bool __i2,
00122               memory_order __m = memory_order_seq_cst)
00123     { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
00124 
00125     bool
00126     compare_exchange_weak(bool& __i1, bool __i2,
00127               memory_order __m = memory_order_seq_cst) volatile
00128     { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
00129 
00130     bool
00131     compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
00132                 memory_order __m2)
00133     { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
00134 
00135     bool
00136     compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
00137                 memory_order __m2) volatile
00138     { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
00139 
00140     bool
00141     compare_exchange_strong(bool& __i1, bool __i2,
00142                 memory_order __m = memory_order_seq_cst)
00143     { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
00144 
00145     bool
00146     compare_exchange_strong(bool& __i1, bool __i2,
00147                 memory_order __m = memory_order_seq_cst) volatile
00148     { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
00149   };
00150 
00151 
00152   /// atomic
00153   /// 29.4.3, Generic atomic type, primary class template.
00154   template<typename _Tp>
00155     struct atomic
00156     {
00157     private:
00158       _Tp _M_i;
00159 
00160     public:
00161       atomic() = default;
00162       ~atomic() = default;
00163       atomic(const atomic&) = delete;
00164       atomic& operator=(const atomic&) = delete;
00165       atomic& operator=(const atomic&) volatile = delete;
00166 
00167       constexpr atomic(_Tp __i) : _M_i(__i) { }
00168 
00169       operator _Tp() const;
00170 
00171       operator _Tp() const volatile;
00172 
00173       _Tp
00174       operator=(_Tp __i) { store(__i); return __i; }
00175 
00176       _Tp
00177       operator=(_Tp __i) volatile { store(__i); return __i; }
00178 
00179       bool
00180       is_lock_free() const;
00181 
00182       bool
00183       is_lock_free() const volatile;
00184 
00185       void
00186       store(_Tp, memory_order = memory_order_seq_cst);
00187 
00188       void
00189       store(_Tp, memory_order = memory_order_seq_cst) volatile;
00190 
00191       _Tp
00192       load(memory_order = memory_order_seq_cst) const;
00193 
00194       _Tp
00195       load(memory_order = memory_order_seq_cst) const volatile;
00196 
00197       _Tp
00198       exchange(_Tp __i, memory_order = memory_order_seq_cst);
00199 
00200       _Tp
00201       exchange(_Tp __i, memory_order = memory_order_seq_cst) volatile;
00202 
00203       bool
00204       compare_exchange_weak(_Tp&, _Tp, memory_order, memory_order);
00205 
00206       bool
00207       compare_exchange_weak(_Tp&, _Tp, memory_order, memory_order) volatile;
00208 
00209       bool
00210       compare_exchange_weak(_Tp&, _Tp, memory_order = memory_order_seq_cst);
00211 
00212       bool
00213       compare_exchange_weak(_Tp&, _Tp,
00214                 memory_order = memory_order_seq_cst) volatile;
00215 
00216       bool
00217       compare_exchange_strong(_Tp&, _Tp, memory_order, memory_order);
00218 
00219       bool
00220       compare_exchange_strong(_Tp&, _Tp, memory_order, memory_order) volatile;
00221 
00222       bool
00223       compare_exchange_strong(_Tp&, _Tp, memory_order = memory_order_seq_cst);
00224 
00225       bool
00226       compare_exchange_strong(_Tp&, _Tp,
00227                   memory_order = memory_order_seq_cst) volatile;
00228     };
00229 
00230 
00231   /// Partial specialization for pointer types.
00232   template<typename _Tp>
00233     struct atomic<_Tp*>
00234     {
00235       typedef _Tp*          __pointer_type;
00236       typedef __atomic_base<_Tp*>   __base_type;
00237       __base_type           _M_b;
00238 
00239       atomic() = default;
00240       ~atomic() = default;
00241       atomic(const atomic&) = delete;
00242       atomic& operator=(const atomic&) = delete;
00243       atomic& operator=(const atomic&) volatile = delete;
00244 
00245       constexpr atomic(__pointer_type __p) : _M_b(__p) { }
00246 
00247       operator __pointer_type() const
00248       { return __pointer_type(_M_b); }
00249 
00250       operator __pointer_type() const volatile
00251       { return __pointer_type(_M_b); }
00252 
00253       __pointer_type
00254       operator=(__pointer_type __p)
00255       { return _M_b.operator=(__p); }
00256 
00257       __pointer_type
00258       operator=(__pointer_type __p) volatile
00259       { return _M_b.operator=(__p); }
00260 
00261       __pointer_type
00262       operator++(int)
00263       { return _M_b++; }
00264 
00265       __pointer_type
00266       operator++(int) volatile
00267       { return _M_b++; }
00268 
00269       __pointer_type
00270       operator--(int)
00271       { return _M_b--; }
00272 
00273       __pointer_type
00274       operator--(int) volatile
00275       { return _M_b--; }
00276 
00277       __pointer_type
00278       operator++()
00279       { return ++_M_b; }
00280 
00281       __pointer_type
00282       operator++() volatile
00283       { return ++_M_b; }
00284 
00285       __pointer_type
00286       operator--()
00287       { return --_M_b; }
00288 
00289       __pointer_type
00290       operator--() volatile
00291       { return --_M_b; }
00292 
00293       __pointer_type
00294       operator+=(ptrdiff_t __d)
00295       { return _M_b.operator+=(__d); }
00296 
00297       __pointer_type
00298       operator+=(ptrdiff_t __d) volatile
00299       { return _M_b.operator+=(__d); }
00300 
00301       __pointer_type
00302       operator-=(ptrdiff_t __d)
00303       { return _M_b.operator-=(__d); }
00304 
00305       __pointer_type
00306       operator-=(ptrdiff_t __d) volatile
00307       { return _M_b.operator-=(__d); }
00308 
00309       bool
00310       is_lock_free() const
00311       { return _M_b.is_lock_free(); }
00312 
00313       bool
00314       is_lock_free() const volatile
00315       { return _M_b.is_lock_free(); }
00316 
00317       void
00318       store(__pointer_type __p, memory_order __m = memory_order_seq_cst)
00319       { return _M_b.store(__p, __m); }
00320 
00321       void
00322       store(__pointer_type __p,
00323         memory_order __m = memory_order_seq_cst) volatile
00324       { return _M_b.store(__p, __m); }
00325 
00326       __pointer_type
00327       load(memory_order __m = memory_order_seq_cst) const
00328       { return _M_b.load(__m); }
00329 
00330       __pointer_type
00331       load(memory_order __m = memory_order_seq_cst) const volatile
00332       { return _M_b.load(__m); }
00333 
00334       __pointer_type
00335       exchange(__pointer_type __p, memory_order __m = memory_order_seq_cst)
00336       { return _M_b.exchange(__p, __m); }
00337 
00338       __pointer_type
00339       exchange(__pointer_type __p,
00340            memory_order __m = memory_order_seq_cst) volatile
00341       { return _M_b.exchange(__p, __m); }
00342 
00343       bool
00344       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
00345                 memory_order __m1, memory_order __m2)
00346       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
00347 
00348       bool
00349       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
00350                 memory_order __m1, memory_order __m2) volatile
00351       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
00352 
00353       bool
00354       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
00355                 memory_order __m = memory_order_seq_cst)
00356       {
00357     return compare_exchange_weak(__p1, __p2, __m,
00358                      __calculate_memory_order(__m));
00359       }
00360 
00361       bool
00362       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
00363                 memory_order __m = memory_order_seq_cst) volatile
00364       {
00365     return compare_exchange_weak(__p1, __p2, __m,
00366                      __calculate_memory_order(__m));
00367       }
00368 
00369       bool
00370       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
00371                   memory_order __m1, memory_order __m2)
00372       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
00373 
00374       bool
00375       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
00376                   memory_order __m1, memory_order __m2) volatile
00377       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
00378 
00379       bool
00380       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
00381                   memory_order __m = memory_order_seq_cst)
00382       {
00383     return _M_b.compare_exchange_strong(__p1, __p2, __m,
00384                         __calculate_memory_order(__m));
00385       }
00386 
00387       bool
00388       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
00389                   memory_order __m = memory_order_seq_cst) volatile
00390       {
00391     return _M_b.compare_exchange_strong(__p1, __p2, __m,
00392                         __calculate_memory_order(__m));
00393       }
00394 
00395       __pointer_type
00396       fetch_add(ptrdiff_t __d, memory_order __m = memory_order_seq_cst)
00397       { return _M_b.fetch_add(__d, __m); }
00398 
00399       __pointer_type
00400       fetch_add(ptrdiff_t __d,
00401         memory_order __m = memory_order_seq_cst) volatile
00402       { return _M_b.fetch_add(__d, __m); }
00403 
00404       __pointer_type
00405       fetch_sub(ptrdiff_t __d, memory_order __m = memory_order_seq_cst)
00406       { return _M_b.fetch_sub(__d, __m); }
00407 
00408       __pointer_type
00409       fetch_sub(ptrdiff_t __d,
00410         memory_order __m = memory_order_seq_cst) volatile
00411       { return _M_b.fetch_sub(__d, __m); }
00412     };
00413 
00414 
00415   /// Explicit specialization for bool.
00416   template<>
00417     struct atomic<bool> : public atomic_bool
00418     {
00419       typedef bool          __integral_type;
00420       typedef atomic_bool       __base_type;
00421 
00422       atomic() = default;
00423       ~atomic() = default;
00424       atomic(const atomic&) = delete;
00425       atomic& operator=(const atomic&) = delete;
00426       atomic& operator=(const atomic&) volatile = delete;
00427 
00428       constexpr atomic(__integral_type __i) : __base_type(__i) { }
00429 
00430       using __base_type::operator __integral_type;
00431       using __base_type::operator=;
00432     };
00433 
00434   /// Explicit specialization for char.
00435   template<>
00436     struct atomic<char> : public atomic_char
00437     {
00438       typedef char          __integral_type;
00439       typedef atomic_char       __base_type;
00440 
00441       atomic() = default;
00442       ~atomic() = default;
00443       atomic(const atomic&) = delete;
00444       atomic& operator=(const atomic&) = delete;
00445       atomic& operator=(const atomic&) volatile = delete;
00446 
00447       constexpr atomic(__integral_type __i) : __base_type(__i) { }
00448 
00449       using __base_type::operator __integral_type;
00450       using __base_type::operator=;
00451     };
00452 
00453   /// Explicit specialization for signed char.
00454   template<>
00455     struct atomic<signed char> : public atomic_schar
00456     {
00457       typedef signed char       __integral_type;
00458       typedef atomic_schar      __base_type;
00459 
00460       atomic() = default;
00461       ~atomic() = default;
00462       atomic(const atomic&) = delete;
00463       atomic& operator=(const atomic&) = delete;
00464       atomic& operator=(const atomic&) volatile = delete;
00465 
00466       constexpr atomic(__integral_type __i) : __base_type(__i) { }
00467 
00468       using __base_type::operator __integral_type;
00469       using __base_type::operator=;
00470     };
00471 
00472   /// Explicit specialization for unsigned char.
00473   template<>
00474     struct atomic<unsigned char> : public atomic_uchar
00475     {
00476       typedef unsigned char         __integral_type;
00477       typedef atomic_uchar      __base_type;
00478 
00479       atomic() = default;
00480       ~atomic() = default;
00481       atomic(const atomic&) = delete;
00482       atomic& operator=(const atomic&) = delete;
00483       atomic& operator=(const atomic&) volatile = delete;
00484 
00485       constexpr atomic(__integral_type __i) : __base_type(__i) { }
00486 
00487       using __base_type::operator __integral_type;
00488       using __base_type::operator=;
00489     };
00490 
00491   /// Explicit specialization for short.
00492   template<>
00493     struct atomic<short> : public atomic_short
00494     {
00495       typedef short             __integral_type;
00496       typedef atomic_short      __base_type;
00497 
00498       atomic() = default;
00499       ~atomic() = default;
00500       atomic(const atomic&) = delete;
00501       atomic& operator=(const atomic&) = delete;
00502       atomic& operator=(const atomic&) volatile = delete;
00503 
00504       constexpr atomic(__integral_type __i) : __base_type(__i) { }
00505 
00506       using __base_type::operator __integral_type;
00507       using __base_type::operator=;
00508     };
00509 
00510   /// Explicit specialization for unsigned short.
00511   template<>
00512     struct atomic<unsigned short> : public atomic_ushort
00513     {
00514       typedef unsigned short            __integral_type;
00515       typedef atomic_ushort         __base_type;
00516 
00517       atomic() = default;
00518       ~atomic() = default;
00519       atomic(const atomic&) = delete;
00520       atomic& operator=(const atomic&) = delete;
00521       atomic& operator=(const atomic&) volatile = delete;
00522 
00523       constexpr atomic(__integral_type __i) : __base_type(__i) { }
00524 
00525       using __base_type::operator __integral_type;
00526       using __base_type::operator=;
00527     };
00528 
00529   /// Explicit specialization for int.
00530   template<>
00531     struct atomic<int> : atomic_int
00532     {
00533       typedef int           __integral_type;
00534       typedef atomic_int        __base_type;
00535 
00536       atomic() = default;
00537       ~atomic() = default;
00538       atomic(const atomic&) = delete;
00539       atomic& operator=(const atomic&) = delete;
00540       atomic& operator=(const atomic&) volatile = delete;
00541 
00542       constexpr atomic(__integral_type __i) : __base_type(__i) { }
00543 
00544       using __base_type::operator __integral_type;
00545       using __base_type::operator=;
00546     };
00547 
00548   /// Explicit specialization for unsigned int.
00549   template<>
00550     struct atomic<unsigned int> : public atomic_uint
00551     {
00552       typedef unsigned int      __integral_type;
00553       typedef atomic_uint       __base_type;
00554 
00555       atomic() = default;
00556       ~atomic() = default;
00557       atomic(const atomic&) = delete;
00558       atomic& operator=(const atomic&) = delete;
00559       atomic& operator=(const atomic&) volatile = delete;
00560 
00561       constexpr atomic(__integral_type __i) : __base_type(__i) { }
00562 
00563       using __base_type::operator __integral_type;
00564       using __base_type::operator=;
00565     };
00566 
00567   /// Explicit specialization for long.
00568   template<>
00569     struct atomic<long> : public atomic_long
00570     {
00571       typedef long          __integral_type;
00572       typedef atomic_long       __base_type;
00573 
00574       atomic() = default;
00575       ~atomic() = default;
00576       atomic(const atomic&) = delete;
00577       atomic& operator=(const atomic&) = delete;
00578       atomic& operator=(const atomic&) volatile = delete;
00579 
00580       constexpr atomic(__integral_type __i) : __base_type(__i) { }
00581 
00582       using __base_type::operator __integral_type;
00583       using __base_type::operator=;
00584     };
00585 
00586   /// Explicit specialization for unsigned long.
00587   template<>
00588     struct atomic<unsigned long> : public atomic_ulong
00589     {
00590       typedef unsigned long         __integral_type;
00591       typedef atomic_ulong      __base_type;
00592 
00593       atomic() = default;
00594       ~atomic() = default;
00595       atomic(const atomic&) = delete;
00596       atomic& operator=(const atomic&) = delete;
00597       atomic& operator=(const atomic&) volatile = delete;
00598 
00599       constexpr atomic(__integral_type __i) : __base_type(__i) { }
00600 
00601       using __base_type::operator __integral_type;
00602       using __base_type::operator=;
00603     };
00604 
00605   /// Explicit specialization for long long.
00606   template<>
00607     struct atomic<long long> : public atomic_llong
00608     {
00609       typedef long long         __integral_type;
00610       typedef atomic_llong      __base_type;
00611 
00612       atomic() = default;
00613       ~atomic() = default;
00614       atomic(const atomic&) = delete;
00615       atomic& operator=(const atomic&) = delete;
00616       atomic& operator=(const atomic&) volatile = delete;
00617 
00618       constexpr atomic(__integral_type __i) : __base_type(__i) { }
00619 
00620       using __base_type::operator __integral_type;
00621       using __base_type::operator=;
00622     };
00623 
00624   /// Explicit specialization for unsigned long long.
00625   template<>
00626     struct atomic<unsigned long long> : public atomic_ullong
00627     {
00628       typedef unsigned long long        __integral_type;
00629       typedef atomic_ullong         __base_type;
00630 
00631       atomic() = default;
00632       ~atomic() = default;
00633       atomic(const atomic&) = delete;
00634       atomic& operator=(const atomic&) = delete;
00635       atomic& operator=(const atomic&) volatile = delete;
00636 
00637       constexpr atomic(__integral_type __i) : __base_type(__i) { }
00638 
00639       using __base_type::operator __integral_type;
00640       using __base_type::operator=;
00641     };
00642 
00643   /// Explicit specialization for wchar_t.
00644   template<>
00645     struct atomic<wchar_t> : public atomic_wchar_t
00646     {
00647       typedef wchar_t           __integral_type;
00648       typedef atomic_wchar_t        __base_type;
00649 
00650       atomic() = default;
00651       ~atomic() = default;
00652       atomic(const atomic&) = delete;
00653       atomic& operator=(const atomic&) = delete;
00654       atomic& operator=(const atomic&) volatile = delete;
00655 
00656       constexpr atomic(__integral_type __i) : __base_type(__i) { }
00657 
00658       using __base_type::operator __integral_type;
00659       using __base_type::operator=;
00660     };
00661 
00662   /// Explicit specialization for char16_t.
00663   template<>
00664     struct atomic<char16_t> : public atomic_char16_t
00665     {
00666       typedef char16_t          __integral_type;
00667       typedef atomic_char16_t       __base_type;
00668 
00669       atomic() = default;
00670       ~atomic() = default;
00671       atomic(const atomic&) = delete;
00672       atomic& operator=(const atomic&) = delete;
00673       atomic& operator=(const atomic&) volatile = delete;
00674 
00675       constexpr atomic(__integral_type __i) : __base_type(__i) { }
00676 
00677       using __base_type::operator __integral_type;
00678       using __base_type::operator=;
00679     };
00680 
00681   /// Explicit specialization for char32_t.
00682   template<>
00683     struct atomic<char32_t> : public atomic_char32_t
00684     {
00685       typedef char32_t          __integral_type;
00686       typedef atomic_char32_t       __base_type;
00687 
00688       atomic() = default;
00689       ~atomic() = default;
00690       atomic(const atomic&) = delete;
00691       atomic& operator=(const atomic&) = delete;
00692       atomic& operator=(const atomic&) volatile = delete;
00693 
00694       constexpr atomic(__integral_type __i) : __base_type(__i) { }
00695 
00696       using __base_type::operator __integral_type;
00697       using __base_type::operator=;
00698     };
00699 
00700 
00701   // Function definitions, atomic_flag operations.
00702   inline bool
00703   atomic_flag_test_and_set_explicit(atomic_flag* __a, memory_order __m)
00704   { return __a->test_and_set(__m); }
00705 
00706   inline bool
00707   atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
00708                     memory_order __m)
00709   { return __a->test_and_set(__m); }
00710 
00711   inline void
00712   atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m)
00713   { __a->clear(__m); }
00714 
00715   inline void
00716   atomic_flag_clear_explicit(volatile atomic_flag* __a, memory_order __m)
00717   { __a->clear(__m); }
00718 
00719   inline bool
00720   atomic_flag_test_and_set(atomic_flag* __a)
00721   { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
00722 
00723   inline bool
00724   atomic_flag_test_and_set(volatile atomic_flag* __a)
00725   { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
00726 
00727   inline void
00728   atomic_flag_clear(atomic_flag* __a)
00729   { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
00730 
00731   inline void
00732   atomic_flag_clear(volatile atomic_flag* __a)
00733   { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
00734 
00735 
00736   // Function templates generally applicable to atomic types.
00737   template<typename _ITp>
00738     inline bool
00739     atomic_is_lock_free(const atomic<_ITp>* __a)
00740     { return __a->is_lock_free(); }
00741 
00742   template<typename _ITp>
00743     inline bool
00744     atomic_is_lock_free(const volatile atomic<_ITp>* __a)
00745     { return __a->is_lock_free(); }
00746 
00747   template<typename _ITp>
00748     inline void
00749     atomic_init(atomic<_ITp>* __a, _ITp __i);
00750 
00751   template<typename _ITp>
00752     inline void
00753     atomic_init(volatile atomic<_ITp>* __a, _ITp __i);
00754 
00755   template<typename _ITp>
00756     inline void
00757     atomic_store_explicit(atomic<_ITp>* __a, _ITp __i, memory_order __m)
00758     { __a->store(__i, __m); }
00759 
00760   template<typename _ITp>
00761     inline void
00762     atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i,
00763               memory_order __m)
00764     { __a->store(__i, __m); }
00765 
00766   template<typename _ITp>
00767     inline _ITp
00768     atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m)
00769     { return __a->load(__m); }
00770 
00771   template<typename _ITp>
00772     inline _ITp
00773     atomic_load_explicit(const volatile atomic<_ITp>* __a,
00774              memory_order __m)
00775     { return __a->load(__m); }
00776 
00777   template<typename _ITp>
00778     inline _ITp
00779     atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i,
00780                  memory_order __m)
00781     { return __a->exchange(__i, __m); }
00782 
00783   template<typename _ITp>
00784     inline _ITp
00785     atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i,
00786                  memory_order __m)
00787     { return __a->exchange(__i, __m); }
00788 
00789   template<typename _ITp>
00790     inline bool
00791     atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a,
00792                       _ITp* __i1, _ITp __i2,
00793                       memory_order __m1, memory_order __m2)
00794     { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
00795 
00796   template<typename _ITp>
00797     inline bool
00798     atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a,
00799                       _ITp* __i1, _ITp __i2,
00800                       memory_order __m1, memory_order __m2)
00801     { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
00802 
00803   template<typename _ITp>
00804     inline bool
00805     atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a,
00806                         _ITp* __i1, _ITp __i2,
00807                         memory_order __m1,
00808                         memory_order __m2)
00809     { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
00810 
00811   template<typename _ITp>
00812     inline bool
00813     atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a,
00814                         _ITp* __i1, _ITp __i2,
00815                         memory_order __m1,
00816                         memory_order __m2)
00817     { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
00818 
00819 
00820   template<typename _ITp>
00821     inline void
00822     atomic_store(atomic<_ITp>* __a, _ITp __i)
00823     { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
00824 
00825   template<typename _ITp>
00826     inline void
00827     atomic_store(volatile atomic<_ITp>* __a, _ITp __i)
00828     { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
00829 
00830   template<typename _ITp>
00831     inline _ITp
00832     atomic_load(const atomic<_ITp>* __a)
00833     { return atomic_load_explicit(__a, memory_order_seq_cst); }
00834 
00835   template<typename _ITp>
00836     inline _ITp
00837     atomic_load(const volatile atomic<_ITp>* __a)
00838     { return atomic_load_explicit(__a, memory_order_seq_cst); }
00839 
00840   template<typename _ITp>
00841     inline _ITp
00842     atomic_exchange(atomic<_ITp>* __a, _ITp __i)
00843     { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
00844 
00845   template<typename _ITp>
00846     inline _ITp
00847     atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i)
00848     { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
00849 
00850   template<typename _ITp>
00851     inline bool
00852     atomic_compare_exchange_weak(atomic<_ITp>* __a,
00853                  _ITp* __i1, _ITp __i2)
00854     {
00855       return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
00856                            memory_order_seq_cst,
00857                            memory_order_seq_cst);
00858     }
00859 
00860   template<typename _ITp>
00861     inline bool
00862     atomic_compare_exchange_weak(volatile atomic<_ITp>* __a,
00863                  _ITp* __i1, _ITp __i2)
00864     {
00865       return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
00866                            memory_order_seq_cst,
00867                            memory_order_seq_cst);
00868     }
00869 
00870   template<typename _ITp>
00871     inline bool
00872     atomic_compare_exchange_strong(atomic<_ITp>* __a,
00873                    _ITp* __i1, _ITp __i2)
00874     {
00875       return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
00876                              memory_order_seq_cst,
00877                              memory_order_seq_cst);
00878     }
00879 
00880   template<typename _ITp>
00881     inline bool
00882     atomic_compare_exchange_strong(volatile atomic<_ITp>* __a,
00883                    _ITp* __i1, _ITp __i2)
00884     {
00885       return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
00886                              memory_order_seq_cst,
00887                              memory_order_seq_cst);
00888     }
00889 
00890   // Function templates for atomic_integral operations only, using
00891   // __atomic_base. Template argument should be constricted to
00892   // intergral types as specified in the standard, excluding address
00893   // types.
00894   template<typename _ITp>
00895     inline _ITp
00896     atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i,
00897                   memory_order __m)
00898     { return __a->fetch_add(__i, __m); }
00899 
00900   template<typename _ITp>
00901     inline _ITp
00902     atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
00903                   memory_order __m)
00904     { return __a->fetch_add(__i, __m); }
00905 
00906   template<typename _ITp>
00907     inline _ITp
00908     atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i,
00909                   memory_order __m)
00910     { return __a->fetch_sub(__i, __m); }
00911 
00912   template<typename _ITp>
00913     inline _ITp
00914     atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
00915                   memory_order __m)
00916     { return __a->fetch_sub(__i, __m); }
00917 
00918   template<typename _ITp>
00919     inline _ITp
00920     atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i,
00921                   memory_order __m)
00922     { return __a->fetch_and(__i, __m); }
00923 
00924   template<typename _ITp>
00925     inline _ITp
00926     atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
00927                   memory_order __m)
00928     { return __a->fetch_and(__i, __m); }
00929 
00930   template<typename _ITp>
00931     inline _ITp
00932     atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i,
00933                  memory_order __m)
00934     { return __a->fetch_or(__i, __m); }
00935 
00936   template<typename _ITp>
00937     inline _ITp
00938     atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
00939                  memory_order __m)
00940     { return __a->fetch_or(__i, __m); }
00941 
00942   template<typename _ITp>
00943     inline _ITp
00944     atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i,
00945                   memory_order __m)
00946     { return __a->fetch_xor(__i, __m); }
00947 
00948   template<typename _ITp>
00949     inline _ITp
00950     atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
00951                   memory_order __m)
00952     { return __a->fetch_xor(__i, __m); }
00953 
00954   template<typename _ITp>
00955     inline _ITp
00956     atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i)
00957     { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
00958 
00959   template<typename _ITp>
00960     inline _ITp
00961     atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i)
00962     { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
00963 
00964   template<typename _ITp>
00965     inline _ITp
00966     atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i)
00967     { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
00968 
00969   template<typename _ITp>
00970     inline _ITp
00971     atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i)
00972     { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
00973 
00974   template<typename _ITp>
00975     inline _ITp
00976     atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i)
00977     { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
00978 
00979   template<typename _ITp>
00980     inline _ITp
00981     atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i)
00982     { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
00983 
00984   template<typename _ITp>
00985     inline _ITp
00986     atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i)
00987     { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
00988 
00989   template<typename _ITp>
00990     inline _ITp
00991     atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i)
00992     { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
00993 
00994   template<typename _ITp>
00995     inline _ITp
00996     atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i)
00997     { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
00998 
00999   template<typename _ITp>
01000     inline _ITp
01001     atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i)
01002     { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
01003 
01004 
01005   // Partial specializations for pointers.
01006   template<typename _ITp>
01007     inline _ITp*
01008     atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
01009                   memory_order __m)
01010     { return __a->fetch_add(__d, __m); }
01011 
01012   template<typename _ITp>
01013     inline _ITp*
01014     atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d,
01015                   memory_order __m)
01016     { return __a->fetch_add(__d, __m); }
01017 
01018   template<typename _ITp>
01019     inline _ITp*
01020     atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d)
01021     { return __a->fetch_add(__d); }
01022 
01023   template<typename _ITp>
01024     inline _ITp*
01025     atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d)
01026     { return __a->fetch_add(__d); }
01027 
01028   template<typename _ITp>
01029     inline _ITp*
01030     atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a,
01031                   ptrdiff_t __d, memory_order __m)
01032     { return __a->fetch_sub(__d, __m); }
01033 
01034   template<typename _ITp>
01035     inline _ITp*
01036     atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
01037                   memory_order __m)
01038     { return __a->fetch_sub(__d, __m); }
01039 
01040   template<typename _ITp>
01041     inline _ITp*
01042     atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d)
01043     { return __a->fetch_sub(__d); }
01044 
01045   template<typename _ITp>
01046     inline _ITp*
01047     atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d)
01048     { return __a->fetch_sub(__d); }
01049   // @} group atomics
01050 
01051 _GLIBCXX_END_NAMESPACE_VERSION
01052 } // namespace
01053 
01054 #endif