atomic

Go to the documentation of this file.
00001 // -*- C++ -*- header.
00002 
00003 // Copyright (C) 2008, 2009, 2010 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 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 <cstddef>
00043 
00044 _GLIBCXX_BEGIN_NAMESPACE(std)
00045 
00046   /**
00047    * @addtogroup atomics
00048    * @{
00049    */
00050 
00051   /// kill_dependency
00052   template<typename _Tp>
00053     inline _Tp
00054     kill_dependency(_Tp __y)
00055     {
00056       _Tp ret(__y);
00057       return ret;
00058     }
00059 
00060   inline memory_order
00061   __calculate_memory_order(memory_order __m)
00062   {
00063     const bool __cond1 = __m == memory_order_release;
00064     const bool __cond2 = __m == memory_order_acq_rel;
00065     memory_order __mo1(__cond1 ? memory_order_relaxed : __m);
00066     memory_order __mo2(__cond2 ? memory_order_acquire : __mo1);
00067     return __mo2;
00068   }
00069 
00070   //
00071   // Three nested namespaces for atomic implementation details.
00072   //
00073   // The nested namespace inlined into std:: is determined by the value
00074   // of the _GLIBCXX_ATOMIC_PROPERTY macro and the resulting
00075   // ATOMIC_*_LOCK_FREE macros. See file atomic_base.h.
00076   //
00077   // 0 == __atomic0 == Never lock-free
00078   // 1 == __atomic1 == Best available, sometimes lock-free
00079   // 2 == __atomic2 == Always lock-free
00080 #include <bits/atomic_0.h>
00081 #include <bits/atomic_2.h>
00082 
00083   /// atomic
00084   /// 29.4.3, Generic atomic type, primary class template.
00085   template<typename _Tp>
00086     struct atomic
00087     {
00088     private:
00089       _Tp _M_i;
00090 
00091     public:
00092       atomic() = default;
00093       ~atomic() = default;
00094       atomic(const atomic&) = delete;
00095       atomic& operator=(const atomic&) volatile = delete;
00096 
00097       atomic(_Tp __i) : _M_i(__i) { }
00098 
00099       operator _Tp() const;
00100 
00101       _Tp
00102       operator=(_Tp __i) { store(__i); return __i; }
00103 
00104       bool
00105       is_lock_free() const volatile;
00106 
00107       void
00108       store(_Tp, memory_order = memory_order_seq_cst) volatile;
00109 
00110       _Tp
00111       load(memory_order = memory_order_seq_cst) const volatile;
00112 
00113       _Tp
00114       exchange(_Tp __i, memory_order = memory_order_seq_cst) volatile;
00115 
00116       bool
00117       compare_exchange_weak(_Tp&, _Tp, memory_order, memory_order) volatile;
00118 
00119       bool
00120       compare_exchange_strong(_Tp&, _Tp, memory_order, memory_order) volatile;
00121 
00122       bool
00123       compare_exchange_weak(_Tp&, _Tp,
00124                 memory_order = memory_order_seq_cst) volatile;
00125 
00126       bool
00127       compare_exchange_strong(_Tp&, _Tp,
00128                   memory_order = memory_order_seq_cst) volatile;
00129     };
00130 
00131 
00132   /// Partial specialization for pointer types.
00133   template<typename _Tp>
00134     struct atomic<_Tp*> : atomic_address
00135     {
00136       atomic() = default;
00137       ~atomic() = default;
00138       atomic(const atomic&) = delete;
00139       atomic& operator=(const atomic&) volatile = delete;
00140 
00141       atomic(_Tp* __v) : atomic_address(__v) { }
00142 
00143       void
00144       store(_Tp* __v, memory_order __m = memory_order_seq_cst)
00145       { atomic_address::store(__v, __m); }
00146 
00147       _Tp*
00148       load(memory_order __m = memory_order_seq_cst) const
00149       { return static_cast<_Tp*>(atomic_address::load(__m)); }
00150 
00151       _Tp*
00152       exchange(_Tp* __v, memory_order __m = memory_order_seq_cst)
00153       { return static_cast<_Tp*>(atomic_address::exchange(__v, __m)); }
00154 
00155       bool
00156       compare_exchange_weak(_Tp*&, _Tp*, memory_order, memory_order);
00157 
00158       bool
00159       compare_exchange_strong(_Tp*&, _Tp*, memory_order, memory_order);
00160 
00161       bool
00162       compare_exchange_weak(_Tp*&, _Tp*, memory_order = memory_order_seq_cst);
00163 
00164       bool
00165       compare_exchange_strong(_Tp*&, _Tp*, memory_order = memory_order_seq_cst);
00166 
00167       _Tp*
00168       fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst);
00169 
00170       _Tp*
00171       fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst);
00172 
00173       operator _Tp*() const
00174       { return load(); }
00175 
00176       _Tp*
00177       operator=(_Tp* __v)
00178       {
00179     store(__v);
00180     return __v;
00181       }
00182 
00183       _Tp*
00184       operator++(int) { return fetch_add(1); }
00185 
00186       _Tp*
00187       operator--(int) { return fetch_sub(1); }
00188 
00189       _Tp*
00190       operator++() { return fetch_add(1) + 1; }
00191 
00192       _Tp*
00193       operator--() { return fetch_sub(1) - 1; }
00194 
00195       _Tp*
00196       operator+=(ptrdiff_t __d)
00197       { return fetch_add(__d) + __d; }
00198 
00199       _Tp*
00200       operator-=(ptrdiff_t __d)
00201       { return fetch_sub(__d) - __d; }
00202     };
00203 
00204 
00205   /// Explicit specialization for void*
00206   template<>
00207     struct atomic<void*> : public atomic_address
00208     {
00209       typedef void*             __integral_type;
00210       typedef atomic_address        __base_type;
00211 
00212       atomic() = default;
00213       ~atomic() = default;
00214       atomic(const atomic&) = delete;
00215       atomic& operator=(const atomic&) volatile = delete;
00216 
00217       atomic(__integral_type __i) : __base_type(__i) { }
00218 
00219       using __base_type::operator __integral_type;
00220       using __base_type::operator=;
00221     };
00222 
00223   /// Explicit specialization for bool.
00224   template<>
00225     struct atomic<bool> : public atomic_bool
00226     {
00227       typedef bool          __integral_type;
00228       typedef atomic_bool       __base_type;
00229 
00230       atomic() = default;
00231       ~atomic() = default;
00232       atomic(const atomic&) = delete;
00233       atomic& operator=(const atomic&) volatile = delete;
00234 
00235       atomic(__integral_type __i) : __base_type(__i) { }
00236 
00237       using __base_type::operator __integral_type;
00238       using __base_type::operator=;
00239     };
00240 
00241   /// Explicit specialization for char.
00242   template<>
00243     struct atomic<char> : public atomic_char
00244     {
00245       typedef char          __integral_type;
00246       typedef atomic_char       __base_type;
00247 
00248       atomic() = default;
00249       ~atomic() = default;
00250       atomic(const atomic&) = delete;
00251       atomic& operator=(const atomic&) volatile = delete;
00252 
00253       atomic(__integral_type __i) : __base_type(__i) { }
00254 
00255       using __base_type::operator __integral_type;
00256       using __base_type::operator=;
00257     };
00258 
00259   /// Explicit specialization for signed char.
00260   template<>
00261     struct atomic<signed char> : public atomic_schar
00262     {
00263       typedef signed char       __integral_type;
00264       typedef atomic_schar      __base_type;
00265 
00266       atomic() = default;
00267       ~atomic() = default;
00268       atomic(const atomic&) = delete;
00269       atomic& operator=(const atomic&) volatile = delete;
00270 
00271       atomic(__integral_type __i) : __base_type(__i) { }
00272 
00273       using __base_type::operator __integral_type;
00274       using __base_type::operator=;
00275     };
00276 
00277   /// Explicit specialization for unsigned char.
00278   template<>
00279     struct atomic<unsigned char> : public atomic_uchar
00280     {
00281       typedef unsigned char         __integral_type;
00282       typedef atomic_uchar      __base_type;
00283 
00284       atomic() = default;
00285       ~atomic() = default;
00286       atomic(const atomic&) = delete;
00287       atomic& operator=(const atomic&) volatile = delete;
00288 
00289       atomic(__integral_type __i) : __base_type(__i) { }
00290 
00291       using __base_type::operator __integral_type;
00292       using __base_type::operator=;
00293     };
00294 
00295   /// Explicit specialization for short.
00296   template<>
00297     struct atomic<short> : public atomic_short
00298     {
00299       typedef short             __integral_type;
00300       typedef atomic_short      __base_type;
00301 
00302       atomic() = default;
00303       ~atomic() = default;
00304       atomic(const atomic&) = delete;
00305       atomic& operator=(const atomic&) volatile = delete;
00306 
00307       atomic(__integral_type __i) : __base_type(__i) { }
00308 
00309       using __base_type::operator __integral_type;
00310       using __base_type::operator=;
00311     };
00312 
00313   /// Explicit specialization for unsigned short.
00314   template<>
00315     struct atomic<unsigned short> : public atomic_ushort
00316     {
00317       typedef unsigned short            __integral_type;
00318       typedef atomic_ushort         __base_type;
00319 
00320       atomic() = default;
00321       ~atomic() = default;
00322       atomic(const atomic&) = delete;
00323       atomic& operator=(const atomic&) volatile = delete;
00324 
00325       atomic(__integral_type __i) : __base_type(__i) { }
00326 
00327       using __base_type::operator __integral_type;
00328       using __base_type::operator=;
00329     };
00330 
00331   /// Explicit specialization for int.
00332   template<>
00333     struct atomic<int> : atomic_int
00334     {
00335       typedef int           __integral_type;
00336       typedef atomic_int        __base_type;
00337 
00338       atomic() = default;
00339       ~atomic() = default;
00340       atomic(const atomic&) = delete;
00341       atomic& operator=(const atomic&) volatile = delete;
00342 
00343       atomic(__integral_type __i) : __base_type(__i) { }
00344 
00345       using __base_type::operator __integral_type;
00346       using __base_type::operator=;
00347     };
00348 
00349   /// Explicit specialization for unsigned int.
00350   template<>
00351     struct atomic<unsigned int> : public atomic_uint
00352     {
00353       typedef unsigned int      __integral_type;
00354       typedef atomic_uint       __base_type;
00355 
00356       atomic() = default;
00357       ~atomic() = default;
00358       atomic(const atomic&) = delete;
00359       atomic& operator=(const atomic&) volatile = delete;
00360 
00361       atomic(__integral_type __i) : __base_type(__i) { }
00362 
00363       using __base_type::operator __integral_type;
00364       using __base_type::operator=;
00365     };
00366 
00367   /// Explicit specialization for long.
00368   template<>
00369     struct atomic<long> : public atomic_long
00370     {
00371       typedef long          __integral_type;
00372       typedef atomic_long       __base_type;
00373 
00374       atomic() = default;
00375       ~atomic() = default;
00376       atomic(const atomic&) = delete;
00377       atomic& operator=(const atomic&) volatile = delete;
00378 
00379       atomic(__integral_type __i) : __base_type(__i) { }
00380 
00381       using __base_type::operator __integral_type;
00382       using __base_type::operator=;
00383     };
00384 
00385   /// Explicit specialization for unsigned long.
00386   template<>
00387     struct atomic<unsigned long> : public atomic_ulong
00388     {
00389       typedef unsigned long         __integral_type;
00390       typedef atomic_ulong      __base_type;
00391 
00392       atomic() = default;
00393       ~atomic() = default;
00394       atomic(const atomic&) = delete;
00395       atomic& operator=(const atomic&) volatile = delete;
00396 
00397       atomic(__integral_type __i) : __base_type(__i) { }
00398 
00399       using __base_type::operator __integral_type;
00400       using __base_type::operator=;
00401     };
00402 
00403   /// Explicit specialization for long long.
00404   template<>
00405     struct atomic<long long> : public atomic_llong
00406     {
00407       typedef long long         __integral_type;
00408       typedef atomic_llong      __base_type;
00409 
00410       atomic() = default;
00411       ~atomic() = default;
00412       atomic(const atomic&) = delete;
00413       atomic& operator=(const atomic&) volatile = delete;
00414 
00415       atomic(__integral_type __i) : __base_type(__i) { }
00416 
00417       using __base_type::operator __integral_type;
00418       using __base_type::operator=;
00419     };
00420 
00421   /// Explicit specialization for unsigned long long.
00422   template<>
00423     struct atomic<unsigned long long> : public atomic_ullong
00424     {
00425       typedef unsigned long long        __integral_type;
00426       typedef atomic_ullong         __base_type;
00427 
00428       atomic() = default;
00429       ~atomic() = default;
00430       atomic(const atomic&) = delete;
00431       atomic& operator=(const atomic&) volatile = delete;
00432 
00433       atomic(__integral_type __i) : __base_type(__i) { }
00434 
00435       using __base_type::operator __integral_type;
00436       using __base_type::operator=;
00437     };
00438 
00439   /// Explicit specialization for wchar_t.
00440   template<>
00441     struct atomic<wchar_t> : public atomic_wchar_t
00442     {
00443       typedef wchar_t           __integral_type;
00444       typedef atomic_wchar_t        __base_type;
00445 
00446       atomic() = default;
00447       ~atomic() = default;
00448       atomic(const atomic&) = delete;
00449       atomic& operator=(const atomic&) volatile = delete;
00450 
00451       atomic(__integral_type __i) : __base_type(__i) { }
00452 
00453       using __base_type::operator __integral_type;
00454       using __base_type::operator=;
00455     };
00456 
00457   /// Explicit specialization for char16_t.
00458   template<>
00459     struct atomic<char16_t> : public atomic_char16_t
00460     {
00461       typedef char16_t          __integral_type;
00462       typedef atomic_char16_t       __base_type;
00463 
00464       atomic() = default;
00465       ~atomic() = default;
00466       atomic(const atomic&) = delete;
00467       atomic& operator=(const atomic&) volatile = delete;
00468 
00469       atomic(__integral_type __i) : __base_type(__i) { }
00470 
00471       using __base_type::operator __integral_type;
00472       using __base_type::operator=;
00473     };
00474 
00475   /// Explicit specialization for char32_t.
00476   template<>
00477     struct atomic<char32_t> : public atomic_char32_t
00478     {
00479       typedef char32_t          __integral_type;
00480       typedef atomic_char32_t       __base_type;
00481 
00482       atomic() = default;
00483       ~atomic() = default;
00484       atomic(const atomic&) = delete;
00485       atomic& operator=(const atomic&) volatile = delete;
00486 
00487       atomic(__integral_type __i) : __base_type(__i) { }
00488 
00489       using __base_type::operator __integral_type;
00490       using __base_type::operator=;
00491     };
00492 
00493   template<typename _Tp>
00494     bool
00495     atomic<_Tp*>::compare_exchange_weak(_Tp*& __r, _Tp* __v, memory_order __m1,
00496                     memory_order __m2)
00497     {
00498       void** __vr = reinterpret_cast<void**>(&__r);
00499       void* __vv = static_cast<void*>(__v);
00500       return atomic_address::compare_exchange_weak(*__vr, __vv, __m1, __m2);
00501     }
00502 
00503   template<typename _Tp>
00504     bool
00505     atomic<_Tp*>::compare_exchange_strong(_Tp*& __r, _Tp* __v,
00506                       memory_order __m1,
00507                       memory_order __m2)
00508     {
00509       void** __vr = reinterpret_cast<void**>(&__r);
00510       void* __vv = static_cast<void*>(__v);
00511       return atomic_address::compare_exchange_strong(*__vr, __vv, __m1, __m2);
00512     }
00513 
00514   template<typename _Tp>
00515     bool
00516     atomic<_Tp*>::compare_exchange_weak(_Tp*& __r, _Tp* __v,
00517                     memory_order __m)
00518     {
00519       return compare_exchange_weak(__r, __v, __m,
00520                    __calculate_memory_order(__m));
00521     }
00522 
00523   template<typename _Tp>
00524     bool
00525     atomic<_Tp*>::compare_exchange_strong(_Tp*& __r, _Tp* __v,
00526                     memory_order __m)
00527     {
00528       return compare_exchange_strong(__r, __v, __m,
00529                      __calculate_memory_order(__m));
00530     }
00531 
00532   template<typename _Tp>
00533     _Tp*
00534     atomic<_Tp*>::fetch_add(ptrdiff_t __d, memory_order __m)
00535     {
00536       void* __p = atomic_fetch_add_explicit(this, sizeof(_Tp) * __d, __m);
00537       return static_cast<_Tp*>(__p);
00538     }
00539 
00540   template<typename _Tp>
00541     _Tp*
00542     atomic<_Tp*>::fetch_sub(ptrdiff_t __d, memory_order __m)
00543     {
00544       void* __p = atomic_fetch_sub_explicit(this, sizeof(_Tp) * __d, __m);
00545       return static_cast<_Tp*>(__p);
00546     }
00547 
00548   // Convenience function definitions, atomic_flag.
00549   inline bool
00550   atomic_flag_test_and_set_explicit(atomic_flag* __a, memory_order __m)
00551   { return __a->test_and_set(__m); }
00552 
00553   inline void
00554   atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m)
00555   { return __a->clear(__m); }
00556 
00557 
00558   // Convenience function definitions, atomic_address.
00559   inline bool
00560   atomic_is_lock_free(const atomic_address* __a)
00561   { return __a->is_lock_free(); }
00562 
00563   inline void
00564   atomic_store(atomic_address* __a, void* __v)
00565   { __a->store(__v); }
00566 
00567   inline void
00568   atomic_store_explicit(atomic_address* __a, void* __v, memory_order __m)
00569   { __a->store(__v, __m); }
00570 
00571   inline void*
00572   atomic_load(const atomic_address* __a)
00573   { return __a->load(); }
00574 
00575   inline void*
00576   atomic_load_explicit(const atomic_address* __a, memory_order __m)
00577   { return __a->load(__m); }
00578 
00579   inline void*
00580   atomic_exchange(atomic_address* __a, void* __v)
00581   { return __a->exchange(__v); }
00582 
00583   inline void*
00584   atomic_exchange_explicit(atomic_address* __a, void* __v, memory_order __m)
00585   { return __a->exchange(__v, __m); }
00586 
00587   inline bool
00588   atomic_compare_exchange_weak(atomic_address* __a, void** __v1, void* __v2)
00589   {
00590     return __a->compare_exchange_weak(*__v1, __v2, memory_order_seq_cst,
00591                       memory_order_seq_cst);
00592   }
00593 
00594   inline bool
00595   atomic_compare_exchange_strong(atomic_address* __a,
00596                    void** __v1, void* __v2)
00597   {
00598     return __a->compare_exchange_strong(*__v1, __v2, memory_order_seq_cst,
00599                       memory_order_seq_cst);
00600   }
00601 
00602   inline bool
00603   atomic_compare_exchange_weak_explicit(atomic_address* __a,
00604                     void** __v1, void* __v2,
00605                     memory_order __m1, memory_order __m2)
00606   { return __a->compare_exchange_weak(*__v1, __v2, __m1, __m2); }
00607 
00608   inline bool
00609   atomic_compare_exchange_strong_explicit(atomic_address* __a,
00610                       void** __v1, void* __v2,
00611                       memory_order __m1, memory_order __m2)
00612   { return __a->compare_exchange_strong(*__v1, __v2, __m1, __m2); }
00613 
00614   inline void*
00615   atomic_fetch_add_explicit(atomic_address* __a, ptrdiff_t __d,
00616                 memory_order __m)
00617   { return __a->fetch_add(__d, __m); }
00618 
00619   inline void*
00620   atomic_fetch_add(atomic_address* __a, ptrdiff_t __d)
00621   { return __a->fetch_add(__d); }
00622 
00623   inline void*
00624   atomic_fetch_sub_explicit(atomic_address* __a, ptrdiff_t __d,
00625                 memory_order __m)
00626   { return __a->fetch_sub(__d, __m); }
00627 
00628   inline void*
00629   atomic_fetch_sub(atomic_address* __a, ptrdiff_t __d)
00630   { return __a->fetch_sub(__d); }
00631 
00632 
00633   // Convenience function definitions, atomic_bool.
00634   inline bool
00635   atomic_is_lock_free(const atomic_bool* __a)
00636   { return __a->is_lock_free(); }
00637 
00638   inline void
00639   atomic_store(atomic_bool* __a, bool __i)
00640   { __a->store(__i); }
00641 
00642   inline void
00643   atomic_store_explicit(atomic_bool* __a, bool __i, memory_order __m)
00644   { __a->store(__i, __m); }
00645 
00646   inline bool
00647   atomic_load(const atomic_bool* __a)
00648   { return __a->load(); }
00649 
00650   inline bool
00651   atomic_load_explicit(const atomic_bool* __a, memory_order __m)
00652   { return __a->load(__m); }
00653 
00654   inline bool
00655   atomic_exchange(atomic_bool* __a, bool __i)
00656   { return __a->exchange(__i); }
00657 
00658   inline bool
00659   atomic_exchange_explicit(atomic_bool* __a, bool __i, memory_order __m)
00660   { return __a->exchange(__i, __m); }
00661 
00662   inline bool
00663   atomic_compare_exchange_weak(atomic_bool* __a, bool* __i1, bool __i2)
00664   {
00665     return __a->compare_exchange_weak(*__i1, __i2, memory_order_seq_cst,
00666                       memory_order_seq_cst);
00667   }
00668 
00669   inline bool
00670   atomic_compare_exchange_strong(atomic_bool* __a, bool* __i1, bool __i2)
00671   {
00672     return __a->compare_exchange_strong(*__i1, __i2, memory_order_seq_cst,
00673                     memory_order_seq_cst);
00674   }
00675 
00676   inline bool
00677   atomic_compare_exchange_weak_explicit(atomic_bool* __a, bool* __i1,
00678                     bool __i2, memory_order __m1,
00679                     memory_order __m2)
00680   { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
00681 
00682   inline bool
00683   atomic_compare_exchange_strong_explicit(atomic_bool* __a,
00684                       bool* __i1, bool __i2,
00685                       memory_order __m1, memory_order __m2)
00686   { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
00687 
00688 
00689 
00690   // Free standing functions. Template argument should be constricted
00691   // to intergral types as specified in the standard.
00692   template<typename _ITp>
00693     inline void
00694     atomic_store_explicit(__atomic_base<_ITp>* __a, _ITp __i, memory_order __m)
00695     { __a->store(__i, __m); }
00696 
00697   template<typename _ITp>
00698     inline _ITp
00699     atomic_load_explicit(const __atomic_base<_ITp>* __a, memory_order __m)
00700     { return __a->load(__m); }
00701 
00702   template<typename _ITp>
00703     inline _ITp
00704     atomic_exchange_explicit(__atomic_base<_ITp>* __a, _ITp __i,
00705                  memory_order __m)
00706     { return __a->exchange(__i, __m); }
00707 
00708   template<typename _ITp>
00709     inline bool
00710     atomic_compare_exchange_weak_explicit(__atomic_base<_ITp>* __a,
00711                       _ITp* __i1, _ITp __i2,
00712                       memory_order __m1, memory_order __m2)
00713     { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
00714 
00715   template<typename _ITp>
00716     inline bool
00717     atomic_compare_exchange_strong_explicit(__atomic_base<_ITp>* __a,
00718                         _ITp* __i1, _ITp __i2,
00719                         memory_order __m1,
00720                         memory_order __m2)
00721     { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
00722 
00723   template<typename _ITp>
00724     inline _ITp
00725     atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i,
00726                   memory_order __m)
00727     { return __a->fetch_add(__i, __m); }
00728 
00729   template<typename _ITp>
00730     inline _ITp
00731     atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i,
00732                   memory_order __m)
00733     { return __a->fetch_sub(__i, __m); }
00734 
00735   template<typename _ITp>
00736     inline _ITp
00737     atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i,
00738                   memory_order __m)
00739     { return __a->fetch_and(__i, __m); }
00740 
00741   template<typename _ITp>
00742     inline _ITp
00743     atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i,
00744                  memory_order __m)
00745     { return __a->fetch_or(__i, __m); }
00746 
00747   template<typename _ITp>
00748     inline _ITp
00749     atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i,
00750                   memory_order __m)
00751     { return __a->fetch_xor(__i, __m); }
00752 
00753   template<typename _ITp>
00754     inline bool
00755     atomic_is_lock_free(const __atomic_base<_ITp>* __a)
00756     { return __a->is_lock_free(); }
00757 
00758   template<typename _ITp>
00759     inline void
00760     atomic_store(__atomic_base<_ITp>* __a, _ITp __i)
00761     { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
00762 
00763   template<typename _ITp>
00764     inline _ITp
00765     atomic_load(const __atomic_base<_ITp>* __a)
00766     { return atomic_load_explicit(__a, memory_order_seq_cst); }
00767 
00768   template<typename _ITp>
00769     inline _ITp
00770     atomic_exchange(__atomic_base<_ITp>* __a, _ITp __i)
00771     { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
00772 
00773   template<typename _ITp>
00774     inline bool
00775     atomic_compare_exchange_weak(__atomic_base<_ITp>* __a,
00776                  _ITp* __i1, _ITp __i2)
00777     {
00778       return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
00779                            memory_order_seq_cst,
00780                            memory_order_seq_cst);
00781     }
00782 
00783   template<typename _ITp>
00784     inline bool
00785     atomic_compare_exchange_strong(__atomic_base<_ITp>* __a,
00786                    _ITp* __i1, _ITp __i2)
00787     {
00788       return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
00789                              memory_order_seq_cst,
00790                              memory_order_seq_cst);
00791     }
00792 
00793   template<typename _ITp>
00794     inline _ITp
00795     atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i)
00796     { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
00797 
00798   template<typename _ITp>
00799     inline _ITp
00800     atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i)
00801     { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
00802 
00803   template<typename _ITp>
00804     inline _ITp
00805     atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i)
00806     { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
00807 
00808   template<typename _ITp>
00809     inline _ITp
00810     atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i)
00811     { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
00812 
00813   template<typename _ITp>
00814     inline _ITp
00815     atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i)
00816     { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
00817 
00818   // @} group atomics
00819 
00820 _GLIBCXX_END_NAMESPACE
00821 
00822 #endif