atomic

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

Generated on 11 Jan 2010 for libstdc++ by  doxygen 1.6.1