# 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