stdatomic.h

Go to the documentation of this file.
00001 // -*- C++ -*- compatibility header.
00002 
00003 // Copyright (C) 2008, 2009 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 stdatomic.h
00026  *  This is a Standard C++ Library header.
00027  */
00028 
00029 #include <bits/c++config.h>
00030 #include <stddef.h>
00031 #include <stdbool.h> // XXX need to define bool w/o stdbool.h in tr1/cstdbool
00032 
00033 #ifndef _GLIBCXX_STDATOMIC_H
00034 #define _GLIBCXX_STDATOMIC_H 1
00035 
00036 _GLIBCXX_BEGIN_NAMESPACE(std)
00037 _GLIBCXX_BEGIN_EXTERN_C
00038 
00039   /**
00040    * @defgroup atomics Atomics
00041    *
00042    * Components for performing atomic operations.
00043    * @{
00044    */
00045 
00046   /// Enumeration for memory_order
00047   typedef enum memory_order 
00048     {
00049       memory_order_relaxed, 
00050       memory_order_consume, 
00051       memory_order_acquire, 
00052       memory_order_release,
00053       memory_order_acq_rel, 
00054       memory_order_seq_cst
00055     } memory_order;
00056 
00057   // Base for atomic_flag.
00058   typedef struct __atomic_flag_base
00059   {
00060     bool _M_i;
00061   } __atomic_flag_base;
00062 
00063 #define ATOMIC_FLAG_INIT { false } 
00064 
00065   /// 29.2 Lock-free Property
00066 #if defined(_GLIBCXX_ATOMIC_BUILTINS_1) && defined(_GLIBCXX_ATOMIC_BUILTINS_2) \
00067   && defined(_GLIBCXX_ATOMIC_BUILTINS_4) && defined(_GLIBCXX_ATOMIC_BUILTINS_8)
00068 # define _GLIBCXX_ATOMIC_PROPERTY 2
00069 # define _GLIBCXX_ATOMIC_NAMESPACE __atomic2
00070 #elif defined(_GLIBCXX_ATOMIC_BUILTINS_1)
00071 # define _GLIBCXX_ATOMIC_PROPERTY 1
00072 # define _GLIBCXX_ATOMIC_NAMESPACE __atomic1
00073 #else
00074 # define _GLIBCXX_ATOMIC_PROPERTY 0
00075 # define _GLIBCXX_ATOMIC_NAMESPACE __atomic0
00076 #endif
00077 
00078 #define ATOMIC_INTEGRAL_LOCK_FREE _GLIBCXX_ATOMIC_PROPERTY
00079 #define ATOMIC_ADDRESS_LOCK_FREE _GLIBCXX_ATOMIC_PROPERTY
00080 
00081   // Switch atomic integral base types based on C or C++.  In
00082   // addition, for "C" only provide type-generic macros for atomic
00083   // operations. (As C++ accomplishes the same thing with sets of
00084   // overloaded functions.
00085 #ifdef __cplusplus
00086   inline namespace _GLIBCXX_ATOMIC_NAMESPACE { }
00087 # include <bits/atomicfwd_cxx.h>
00088 #else
00089 # include <bits/atomicfwd_c.h>
00090 #endif
00091   
00092   // Typedefs for other atomic integral types.
00093   typedef atomic_schar      atomic_int_least8_t;
00094   typedef atomic_uchar      atomic_uint_least8_t;
00095   typedef atomic_short      atomic_int_least16_t;
00096   typedef atomic_ushort     atomic_uint_least16_t;
00097   typedef atomic_int        atomic_int_least32_t;
00098   typedef atomic_uint       atomic_uint_least32_t;
00099   typedef atomic_llong      atomic_int_least64_t;
00100   typedef atomic_ullong     atomic_uint_least64_t;
00101 
00102   typedef atomic_schar      atomic_int_fast8_t;
00103   typedef atomic_uchar      atomic_uint_fast8_t;
00104   typedef atomic_short      atomic_int_fast16_t;
00105   typedef atomic_ushort     atomic_uint_fast16_t;
00106   typedef atomic_int        atomic_int_fast32_t;
00107   typedef atomic_uint       atomic_uint_fast32_t;
00108   typedef atomic_llong      atomic_int_fast64_t;
00109   typedef atomic_ullong     atomic_uint_fast64_t;
00110 
00111   typedef atomic_long       atomic_intptr_t;
00112   typedef atomic_ulong      atomic_uintptr_t;
00113 
00114   typedef atomic_long       atomic_ssize_t;
00115   typedef atomic_ulong      atomic_size_t;
00116 
00117   typedef atomic_llong      atomic_intmax_t;
00118   typedef atomic_ullong     atomic_uintmax_t;
00119 
00120   typedef atomic_long       atomic_ptrdiff_t;
00121 
00122   // Accessor functions for base atomic_flag type.
00123   bool 
00124   atomic_flag_test_and_set_explicit(volatile __atomic_flag_base*, memory_order);
00125 
00126   inline bool 
00127   atomic_flag_test_and_set(volatile __atomic_flag_base* __a)
00128   { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
00129   
00130   void 
00131   atomic_flag_clear_explicit(volatile __atomic_flag_base*, memory_order);
00132 
00133   inline void 
00134   atomic_flag_clear(volatile __atomic_flag_base* __a)
00135   { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
00136 
00137   void 
00138   __atomic_flag_wait_explicit(volatile __atomic_flag_base*, memory_order);
00139   
00140   volatile __atomic_flag_base* 
00141   __atomic_flag_for_address(const volatile void* __z) __attribute__((const));
00142 
00143   // Implementation specific defines.
00144 #define _ATOMIC_LOAD_(__a, __x)                     \
00145   ({ volatile __typeof__ _ATOMIC_MEMBER_* __p = &_ATOMIC_MEMBER_;   \
00146      volatile atomic_flag* __g = __atomic_flag_for_address(__p);    \
00147     __atomic_flag_wait_explicit(__g, __x);              \
00148     __typeof__ _ATOMIC_MEMBER_ __r = *__p;              \
00149     atomic_flag_clear_explicit(__g, __x);                   \
00150     __r; })
00151 
00152 #define _ATOMIC_STORE_(__a, __m, __x)                   \
00153   ({ volatile __typeof__ _ATOMIC_MEMBER_* __p = &_ATOMIC_MEMBER_;   \
00154     __typeof__(__m) __v = (__m);                        \
00155     volatile atomic_flag* __g = __atomic_flag_for_address(__p);     \
00156     __atomic_flag_wait_explicit(__g, __x);              \
00157     *__p = __v;                             \
00158     atomic_flag_clear_explicit(__g, __x);                   \
00159     __v; })
00160 
00161 #define _ATOMIC_MODIFY_(__a, __o, __m, __x)             \
00162   ({ volatile __typeof__ _ATOMIC_MEMBER_* __p = &_ATOMIC_MEMBER_;   \
00163     __typeof__(__m) __v = (__m);                        \
00164     volatile atomic_flag* __g = __atomic_flag_for_address(__p);     \
00165     __atomic_flag_wait_explicit(__g, __x);              \
00166     __typeof__ _ATOMIC_MEMBER_ __r = *__p;              \
00167     *__p __o __v;                               \
00168     atomic_flag_clear_explicit(__g, __x);                   \
00169     __r; })
00170 
00171 #define _ATOMIC_CMPEXCHNG_(__a, __e, __m, __x)              \
00172   ({ volatile __typeof__ _ATOMIC_MEMBER_* __p = &_ATOMIC_MEMBER_;   \
00173     __typeof__(__e) __q = (__e);                        \
00174     __typeof__(__m) __v = (__m);                        \
00175     bool __r;                                   \
00176     volatile atomic_flag* __g = __atomic_flag_for_address(__p);     \
00177     __atomic_flag_wait_explicit(__g, __x);              \
00178     __typeof__ _ATOMIC_MEMBER_ __t__ = *__p;                    \
00179     if (__t__ == *__q) { *__p = __v; __r = true; }          \
00180     else { *__q = __t__; __r = false; }                     \
00181     atomic_flag_clear_explicit(__g, __x);                   \
00182     __r; })
00183 
00184   // @} group atomics
00185 
00186 _GLIBCXX_END_EXTERN_C
00187 _GLIBCXX_END_NAMESPACE
00188 
00189 // Inject into global namespace. XXX
00190 #if defined(__cplusplus) && !defined(_GLIBCXX_STDATOMIC)
00191 using std::memory_order;
00192 using std::memory_order_relaxed;
00193 using std::memory_order_consume;
00194 using std::memory_order_acquire;
00195 using std::memory_order_release;
00196 using std::memory_order_acq_rel;
00197 using std::memory_order_seq_cst;
00198 using std::atomic_flag;
00199 using std::atomic_bool;
00200 using std::atomic_char;
00201 using std::atomic_schar;
00202 using std::atomic_uchar;
00203 using std::atomic_short;
00204 using std::atomic_ushort;
00205 using std::atomic_int;
00206 using std::atomic_uint;
00207 using std::atomic_long;
00208 using std::atomic_ulong;
00209 using std::atomic_llong;
00210 using std::atomic_ullong;
00211 using std::atomic_wchar_t;
00212 using std::atomic_char16_t;
00213 using std::atomic_char32_t;
00214 using std::atomic_address;
00215 using std::atomic;
00216 #endif
00217 
00218 #endif

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