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

Generated on 12 Mar 2010 for libstdc++ by  doxygen 1.6.1