libstdc++
atomic_base.h
Go to the documentation of this file.
00001 // -*- C++ -*- header.
00002 
00003 // Copyright (C) 2008, 2009, 2010, 2011 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 bits/atomic_base.h
00026  *  This is an internal header file, included by other library headers.
00027  *  Do not attempt to use it directly. @headername{atomic}
00028  */
00029 
00030 #ifndef _GLIBCXX_ATOMIC_BASE_H
00031 #define _GLIBCXX_ATOMIC_BASE_H 1
00032 
00033 #pragma GCC system_header
00034 
00035 #include <bits/c++config.h>
00036 #include <stdbool.h>
00037 #include <stdint.h>
00038 
00039 namespace std _GLIBCXX_VISIBILITY(default)
00040 {
00041 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00042 
00043   /**
00044    * @defgroup atomics Atomics
00045    *
00046    * Components for performing atomic operations.
00047    * @{
00048    */
00049 
00050   /// Enumeration for memory_order
00051   typedef enum memory_order
00052     {
00053       memory_order_relaxed,
00054       memory_order_consume,
00055       memory_order_acquire,
00056       memory_order_release,
00057       memory_order_acq_rel,
00058       memory_order_seq_cst
00059     } memory_order;
00060 
00061   inline memory_order
00062   __calculate_memory_order(memory_order __m)
00063   {
00064     const bool __cond1 = __m == memory_order_release;
00065     const bool __cond2 = __m == memory_order_acq_rel;
00066     memory_order __mo1(__cond1 ? memory_order_relaxed : __m);
00067     memory_order __mo2(__cond2 ? memory_order_acquire : __mo1);
00068     return __mo2;
00069   }
00070 
00071   void
00072   atomic_thread_fence(memory_order);
00073 
00074   void
00075   atomic_signal_fence(memory_order);
00076 
00077   /// kill_dependency
00078   template<typename _Tp>
00079     inline _Tp
00080     kill_dependency(_Tp __y)
00081     {
00082       _Tp __ret(__y);
00083       return __ret;
00084     }
00085 
00086   /**
00087    *  @brief Base type for atomic_flag.
00088    *
00089    *  Base type is POD with data, allowing atomic_flag to derive from
00090    *  it and meet the standard layout type requirement. In addition to
00091    *  compatibilty with a C interface, this allows different
00092    *  implementations of atomic_flag to use the same atomic operation
00093    *  functions, via a standard conversion to the __atomic_flag_base
00094    *  argument.
00095   */
00096   _GLIBCXX_BEGIN_EXTERN_C
00097 
00098   struct __atomic_flag_base
00099   {
00100     bool _M_i;
00101   };
00102 
00103   _GLIBCXX_END_EXTERN_C
00104 
00105 #define ATOMIC_FLAG_INIT { false }
00106 
00107 
00108   // Base types for atomics.
00109   //
00110   // Three nested namespaces for atomic implementation details.
00111   //
00112   // The nested namespace inlined into std:: is determined by the value
00113   // of the _GLIBCXX_ATOMIC_PROPERTY macro and the resulting
00114   // ATOMIC_*_LOCK_FREE macros.
00115   //
00116   // 0 == __atomic0 == Never lock-free
00117   // 1 == __atomic1 == Best available, sometimes lock-free
00118   // 2 == __atomic2 == Always lock-free
00119 
00120   namespace __atomic0
00121   {
00122     struct atomic_flag;
00123 
00124     template<typename _IntTp>
00125       struct __atomic_base;
00126   }
00127 
00128   namespace __atomic2
00129   {
00130     struct atomic_flag;
00131 
00132     template<typename _IntTp>
00133       struct __atomic_base;
00134   }
00135 
00136   namespace __atomic1
00137   {
00138     using __atomic2::atomic_flag;
00139     using __atomic0::__atomic_base;
00140   }
00141 
00142   /// Lock-free Property
00143 #if defined(_GLIBCXX_ATOMIC_BUILTINS_1) && defined(_GLIBCXX_ATOMIC_BUILTINS_2) \
00144   && defined(_GLIBCXX_ATOMIC_BUILTINS_4) && defined(_GLIBCXX_ATOMIC_BUILTINS_8)
00145 # define _GLIBCXX_ATOMIC_PROPERTY 2
00146 # define _GLIBCXX_ATOMIC_NAMESPACE __atomic2
00147 #elif defined(_GLIBCXX_ATOMIC_BUILTINS_1)
00148 # define _GLIBCXX_ATOMIC_PROPERTY 1
00149 # define _GLIBCXX_ATOMIC_NAMESPACE __atomic1
00150 #else
00151 # define _GLIBCXX_ATOMIC_PROPERTY 0
00152 # define _GLIBCXX_ATOMIC_NAMESPACE __atomic0
00153 #endif
00154 
00155 #define ATOMIC_CHAR_LOCK_FREE _GLIBCXX_ATOMIC_PROPERTY
00156 #define ATOMIC_CHAR16_T_LOCK_FREE _GLIBCXX_ATOMIC_PROPERTY
00157 #define ATOMIC_CHAR32_T_LOCK_FREE _GLIBCXX_ATOMIC_PROPERTY
00158 #define ATOMIC_WCHAR_T_LOCK_FREE _GLIBCXX_ATOMIC_PROPERTY
00159 #define ATOMIC_SHORT_LOCK_FREE _GLIBCXX_ATOMIC_PROPERTY
00160 #define ATOMIC_INT_LOCK_FREE _GLIBCXX_ATOMIC_PROPERTY
00161 #define ATOMIC_LONG_LOCK_FREE _GLIBCXX_ATOMIC_PROPERTY
00162 #define ATOMIC_LLONG_LOCK_FREE _GLIBCXX_ATOMIC_PROPERTY
00163 
00164   inline namespace _GLIBCXX_ATOMIC_NAMESPACE { }
00165 
00166 
00167   /// atomic_char
00168   typedef __atomic_base<char>               atomic_char;
00169 
00170   /// atomic_schar
00171   typedef __atomic_base<signed char>            atomic_schar;
00172 
00173   /// atomic_uchar
00174   typedef __atomic_base<unsigned char>      atomic_uchar;
00175 
00176   /// atomic_short
00177   typedef __atomic_base<short>          atomic_short;
00178 
00179   /// atomic_ushort
00180   typedef __atomic_base<unsigned short>     atomic_ushort;
00181 
00182   /// atomic_int
00183   typedef __atomic_base<int>                atomic_int;
00184 
00185   /// atomic_uint
00186   typedef __atomic_base<unsigned int>           atomic_uint;
00187 
00188   /// atomic_long
00189   typedef __atomic_base<long>               atomic_long;
00190 
00191   /// atomic_ulong
00192   typedef __atomic_base<unsigned long>      atomic_ulong;
00193 
00194   /// atomic_llong
00195   typedef __atomic_base<long long>          atomic_llong;
00196 
00197   /// atomic_ullong
00198   typedef __atomic_base<unsigned long long>     atomic_ullong;
00199 
00200   /// atomic_wchar_t
00201   typedef __atomic_base<wchar_t>        atomic_wchar_t;
00202 
00203   /// atomic_char16_t
00204   typedef __atomic_base<char16_t>       atomic_char16_t;
00205 
00206   /// atomic_char32_t
00207   typedef __atomic_base<char32_t>       atomic_char32_t;
00208 
00209   /// atomic_char32_t
00210   typedef __atomic_base<char32_t>       atomic_char32_t;
00211 
00212 
00213   /// atomic_int_least8_t
00214   typedef __atomic_base<int_least8_t>       atomic_int_least8_t;
00215 
00216   /// atomic_uint_least8_t
00217   typedef __atomic_base<uint_least8_t>          atomic_uint_least8_t;
00218 
00219   /// atomic_int_least16_t
00220   typedef __atomic_base<int_least16_t>          atomic_int_least16_t;
00221 
00222   /// atomic_uint_least16_t
00223   typedef __atomic_base<uint_least16_t>         atomic_uint_least16_t;
00224 
00225   /// atomic_int_least32_t
00226   typedef __atomic_base<int_least32_t>          atomic_int_least32_t;
00227 
00228   /// atomic_uint_least32_t
00229   typedef __atomic_base<uint_least32_t>         atomic_uint_least32_t;
00230 
00231   /// atomic_int_least64_t
00232   typedef __atomic_base<int_least64_t>          atomic_int_least64_t;
00233 
00234   /// atomic_uint_least64_t
00235   typedef __atomic_base<uint_least64_t>         atomic_uint_least64_t;
00236 
00237 
00238   /// atomic_int_fast8_t
00239   typedef __atomic_base<int_fast8_t>        atomic_int_fast8_t;
00240 
00241   /// atomic_uint_fast8_t
00242   typedef __atomic_base<uint_fast8_t>           atomic_uint_fast8_t;
00243 
00244   /// atomic_int_fast16_t
00245   typedef __atomic_base<int_fast16_t>           atomic_int_fast16_t;
00246 
00247   /// atomic_uint_fast16_t
00248   typedef __atomic_base<uint_fast16_t>          atomic_uint_fast16_t;
00249 
00250   /// atomic_int_fast32_t
00251   typedef __atomic_base<int_fast32_t>           atomic_int_fast32_t;
00252 
00253   /// atomic_uint_fast32_t
00254   typedef __atomic_base<uint_fast32_t>          atomic_uint_fast32_t;
00255 
00256   /// atomic_int_fast64_t
00257   typedef __atomic_base<int_fast64_t>           atomic_int_fast64_t;
00258 
00259   /// atomic_uint_fast64_t
00260   typedef __atomic_base<uint_fast64_t>          atomic_uint_fast64_t;
00261 
00262 
00263   /// atomic_intptr_t
00264   typedef __atomic_base<intptr_t>           atomic_intptr_t;
00265 
00266   /// atomic_uintptr_t
00267   typedef __atomic_base<uintptr_t>              atomic_uintptr_t;
00268 
00269   /// atomic_size_t
00270   typedef __atomic_base<size_t>             atomic_size_t;
00271 
00272   /// atomic_intmax_t
00273   typedef __atomic_base<intmax_t>           atomic_intmax_t;
00274 
00275   /// atomic_uintmax_t
00276   typedef __atomic_base<uintmax_t>              atomic_uintmax_t;
00277 
00278   /// atomic_ptrdiff_t
00279   typedef __atomic_base<ptrdiff_t>              atomic_ptrdiff_t;
00280 
00281 
00282 #define ATOMIC_VAR_INIT(_VI) { _VI }
00283 
00284   template<typename _Tp>
00285     struct atomic;
00286 
00287   template<typename _Tp>
00288     struct atomic<_Tp*>;
00289 
00290   // @} group atomics
00291 
00292 _GLIBCXX_END_NAMESPACE_VERSION
00293 } // namespace std
00294 
00295 #endif