cstdatomic

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

Generated on Thu Jul 23 21:16:02 2009 for libstdc++ by  doxygen 1.5.8