# atomic

Go to the documentation of this file.

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