1 // -*- C++ -*- header. 2 3 // Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 /** @file bits/atomic_base.h 26 * This is an internal header file, included by other library headers. 27 * Do not attempt to use it directly. @headername{atomic} 28 */ 29 30 #ifndef _GLIBCXX_ATOMIC_BASE_H 31 #define _GLIBCXX_ATOMIC_BASE_H 1 32 33 #pragma GCC system_header 34 35 #include <bits/c++config.h> 36 #include <stdbool.h> 37 #include <stdint.h> 38 39 namespace std _GLIBCXX_VISIBILITY(default) 40 { 41 _GLIBCXX_BEGIN_NAMESPACE_VERSION 42 43 /** 44 * @defgroup atomics Atomics 45 * 46 * Components for performing atomic operations. 47 * @{ 48 */ 49 50 /// Enumeration for memory_order 51 typedef enum memory_order 52 { 53 memory_order_relaxed, 54 memory_order_consume, 55 memory_order_acquire, 56 memory_order_release, 57 memory_order_acq_rel, 58 memory_order_seq_cst 59 } memory_order; 60 61 inline memory_order 62 __calculate_memory_order(memory_order __m) 63 { 64 const bool __cond1 = __m == memory_order_release; 65 const bool __cond2 = __m == memory_order_acq_rel; 66 memory_order __mo1(__cond1 ? memory_order_relaxed : __m); 67 memory_order __mo2(__cond2 ? memory_order_acquire : __mo1); 68 return __mo2; 69 } 70 71 void 72 atomic_thread_fence(memory_order); 73 74 void 75 atomic_signal_fence(memory_order); 76 77 /// kill_dependency 78 template<typename _Tp> 79 inline _Tp 80 kill_dependency(_Tp __y) 81 { 82 _Tp __ret(__y); 83 return __ret; 84 } 85 86 /** 87 * @brief Base type for atomic_flag. 88 * 89 * Base type is POD with data, allowing atomic_flag to derive from 90 * it and meet the standard layout type requirement. In addition to 91 * compatibilty with a C interface, this allows different 92 * implementations of atomic_flag to use the same atomic operation 93 * functions, via a standard conversion to the __atomic_flag_base 94 * argument. 95 */ 96 _GLIBCXX_BEGIN_EXTERN_C 97 98 struct __atomic_flag_base 99 { 100 bool _M_i; 101 }; 102 103 _GLIBCXX_END_EXTERN_C 104 105 #define ATOMIC_FLAG_INIT { false } 106 107 108 // Base types for atomics. 109 // 110 // Three nested namespaces for atomic implementation details. 111 // 112 // The nested namespace inlined into std:: is determined by the value 113 // of the _GLIBCXX_ATOMIC_PROPERTY macro and the resulting 114 // ATOMIC_*_LOCK_FREE macros. 115 // 116 // 0 == __atomic0 == Never lock-free 117 // 1 == __atomic1 == Best available, sometimes lock-free 118 // 2 == __atomic2 == Always lock-free 119 120 namespace __atomic0 121 { 122 struct atomic_flag; 123 124 template<typename _IntTp> 125 struct __atomic_base; 126 } 127 128 namespace __atomic2 129 { 130 struct atomic_flag; 131 132 template<typename _IntTp> 133 struct __atomic_base; 134 } 135 136 namespace __atomic1 137 { 138 using __atomic2::atomic_flag; 139 using __atomic0::__atomic_base; 140 } 141 142 /// Lock-free Property 143 #if defined(_GLIBCXX_ATOMIC_BUILTINS_1) && defined(_GLIBCXX_ATOMIC_BUILTINS_2) \ 144 && defined(_GLIBCXX_ATOMIC_BUILTINS_4) && defined(_GLIBCXX_ATOMIC_BUILTINS_8) 145 # define _GLIBCXX_ATOMIC_PROPERTY 2 146 # define _GLIBCXX_ATOMIC_NAMESPACE __atomic2 147 #elif defined(_GLIBCXX_ATOMIC_BUILTINS_1) 148 # define _GLIBCXX_ATOMIC_PROPERTY 1 149 # define _GLIBCXX_ATOMIC_NAMESPACE __atomic1 150 #else 151 # define _GLIBCXX_ATOMIC_PROPERTY 0 152 # define _GLIBCXX_ATOMIC_NAMESPACE __atomic0 153 #endif 154 155 #define ATOMIC_CHAR_LOCK_FREE _GLIBCXX_ATOMIC_PROPERTY 156 #define ATOMIC_CHAR16_T_LOCK_FREE _GLIBCXX_ATOMIC_PROPERTY 157 #define ATOMIC_CHAR32_T_LOCK_FREE _GLIBCXX_ATOMIC_PROPERTY 158 #define ATOMIC_WCHAR_T_LOCK_FREE _GLIBCXX_ATOMIC_PROPERTY 159 #define ATOMIC_SHORT_LOCK_FREE _GLIBCXX_ATOMIC_PROPERTY 160 #define ATOMIC_INT_LOCK_FREE _GLIBCXX_ATOMIC_PROPERTY 161 #define ATOMIC_LONG_LOCK_FREE _GLIBCXX_ATOMIC_PROPERTY 162 #define ATOMIC_LLONG_LOCK_FREE _GLIBCXX_ATOMIC_PROPERTY 163 164 inline namespace _GLIBCXX_ATOMIC_NAMESPACE { } 165 166 167 /// atomic_char 168 typedef __atomic_base<char> atomic_char; 169 170 /// atomic_schar 171 typedef __atomic_base<signed char> atomic_schar; 172 173 /// atomic_uchar 174 typedef __atomic_base<unsigned char> atomic_uchar; 175 176 /// atomic_short 177 typedef __atomic_base<short> atomic_short; 178 179 /// atomic_ushort 180 typedef __atomic_base<unsigned short> atomic_ushort; 181 182 /// atomic_int 183 typedef __atomic_base<int> atomic_int; 184 185 /// atomic_uint 186 typedef __atomic_base<unsigned int> atomic_uint; 187 188 /// atomic_long 189 typedef __atomic_base<long> atomic_long; 190 191 /// atomic_ulong 192 typedef __atomic_base<unsigned long> atomic_ulong; 193 194 /// atomic_llong 195 typedef __atomic_base<long long> atomic_llong; 196 197 /// atomic_ullong 198 typedef __atomic_base<unsigned long long> atomic_ullong; 199 200 /// atomic_wchar_t 201 typedef __atomic_base<wchar_t> atomic_wchar_t; 202 203 /// atomic_char16_t 204 typedef __atomic_base<char16_t> atomic_char16_t; 205 206 /// atomic_char32_t 207 typedef __atomic_base<char32_t> atomic_char32_t; 208 209 /// atomic_char32_t 210 typedef __atomic_base<char32_t> atomic_char32_t; 211 212 213 /// atomic_int_least8_t 214 typedef __atomic_base<int_least8_t> atomic_int_least8_t; 215 216 /// atomic_uint_least8_t 217 typedef __atomic_base<uint_least8_t> atomic_uint_least8_t; 218 219 /// atomic_int_least16_t 220 typedef __atomic_base<int_least16_t> atomic_int_least16_t; 221 222 /// atomic_uint_least16_t 223 typedef __atomic_base<uint_least16_t> atomic_uint_least16_t; 224 225 /// atomic_int_least32_t 226 typedef __atomic_base<int_least32_t> atomic_int_least32_t; 227 228 /// atomic_uint_least32_t 229 typedef __atomic_base<uint_least32_t> atomic_uint_least32_t; 230 231 /// atomic_int_least64_t 232 typedef __atomic_base<int_least64_t> atomic_int_least64_t; 233 234 /// atomic_uint_least64_t 235 typedef __atomic_base<uint_least64_t> atomic_uint_least64_t; 236 237 238 /// atomic_int_fast8_t 239 typedef __atomic_base<int_fast8_t> atomic_int_fast8_t; 240 241 /// atomic_uint_fast8_t 242 typedef __atomic_base<uint_fast8_t> atomic_uint_fast8_t; 243 244 /// atomic_int_fast16_t 245 typedef __atomic_base<int_fast16_t> atomic_int_fast16_t; 246 247 /// atomic_uint_fast16_t 248 typedef __atomic_base<uint_fast16_t> atomic_uint_fast16_t; 249 250 /// atomic_int_fast32_t 251 typedef __atomic_base<int_fast32_t> atomic_int_fast32_t; 252 253 /// atomic_uint_fast32_t 254 typedef __atomic_base<uint_fast32_t> atomic_uint_fast32_t; 255 256 /// atomic_int_fast64_t 257 typedef __atomic_base<int_fast64_t> atomic_int_fast64_t; 258 259 /// atomic_uint_fast64_t 260 typedef __atomic_base<uint_fast64_t> atomic_uint_fast64_t; 261 262 263 /// atomic_intptr_t 264 typedef __atomic_base<intptr_t> atomic_intptr_t; 265 266 /// atomic_uintptr_t 267 typedef __atomic_base<uintptr_t> atomic_uintptr_t; 268 269 /// atomic_size_t 270 typedef __atomic_base<size_t> atomic_size_t; 271 272 /// atomic_intmax_t 273 typedef __atomic_base<intmax_t> atomic_intmax_t; 274 275 /// atomic_uintmax_t 276 typedef __atomic_base<uintmax_t> atomic_uintmax_t; 277 278 /// atomic_ptrdiff_t 279 typedef __atomic_base<ptrdiff_t> atomic_ptrdiff_t; 280 281 282 #define ATOMIC_VAR_INIT(_VI) { _VI } 283 284 template<typename _Tp> 285 struct atomic; 286 287 template<typename _Tp> 288 struct atomic<_Tp*>; 289 290 // @} group atomics 291 292 _GLIBCXX_END_NAMESPACE_VERSION 293 } // namespace std 294 295 #endif 296