$search
00001 #ifndef BOOST_DETAIL_ATOMIC_CAS64STRONG_HPP 00002 #define BOOST_DETAIL_ATOMIC_CAS64STRONG_HPP 00003 00004 // Distributed under the Boost Software License, Version 1.0. 00005 // See accompanying file LICENSE_1_0.txt or copy at 00006 // http://www.boost.org/LICENSE_1_0.txt) 00007 // 00008 // Copyright (c) 2011 Helge Bahmann 00009 00010 // Build 64-bit atomic operation from platform_cmpxchg64_strong 00011 // primitive. It is assumed that 64-bit loads/stores are not 00012 // atomic, so they are funnelled through cmpxchg as well. 00013 00014 #include <boost/memory_order.hpp> 00015 #include <boost/atomic/detail/base.hpp> 00016 00017 namespace boost { 00018 namespace detail { 00019 namespace atomic { 00020 00021 /* integral types */ 00022 00023 template<typename T, bool Sign> 00024 class base_atomic<T, int, 8, Sign> { 00025 typedef base_atomic this_type; 00026 typedef T value_type; 00027 typedef T difference_type; 00028 public: 00029 explicit base_atomic(value_type v) : v_(v) {} 00030 base_atomic(void) {} 00031 00032 void 00033 store(value_type v, memory_order order = memory_order_seq_cst) volatile 00034 { 00035 value_type expected = v_; 00036 do { 00037 } while (!compare_exchange_strong(expected, v, order, memory_order_relaxed)); 00038 } 00039 00040 value_type 00041 load(memory_order order = memory_order_seq_cst) const volatile 00042 { 00043 value_type v = const_cast<const volatile value_type &>(v_); 00044 do { 00045 } while (!const_cast<base_atomic *>(this)->compare_exchange_strong(v, v, order, memory_order_relaxed)); 00046 return v; 00047 } 00048 00049 value_type 00050 exchange(value_type v, memory_order order = memory_order_seq_cst) volatile 00051 { 00052 value_type original = load(memory_order_relaxed); 00053 do { 00054 } while (!compare_exchange_weak(original, v, order, memory_order_relaxed)); 00055 return original; 00056 } 00057 00058 bool 00059 compare_exchange_weak( 00060 value_type & expected, 00061 value_type desired, 00062 memory_order success_order, 00063 memory_order failure_order) volatile 00064 { 00065 return compare_exchange_strong(expected, desired, success_order, failure_order); 00066 } 00067 00068 bool 00069 compare_exchange_strong( 00070 value_type & expected, 00071 value_type desired, 00072 memory_order success_order, 00073 memory_order failure_order) volatile 00074 { 00075 platform_fence_before(success_order); 00076 00077 bool success = platform_cmpxchg64_strong(expected, desired, &v_); 00078 00079 if (success) { 00080 platform_fence_after(success_order); 00081 } else { 00082 platform_fence_after(failure_order); 00083 } 00084 00085 return success; 00086 } 00087 00088 value_type 00089 fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile 00090 { 00091 value_type original = load(memory_order_relaxed); 00092 do { 00093 } while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed)); 00094 return original; 00095 } 00096 00097 value_type 00098 fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile 00099 { 00100 value_type original = load(memory_order_relaxed); 00101 do { 00102 } while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed)); 00103 return original; 00104 } 00105 00106 value_type 00107 fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile 00108 { 00109 value_type original = load(memory_order_relaxed); 00110 do { 00111 } while (!compare_exchange_weak(original, original & v, order, memory_order_relaxed)); 00112 return original; 00113 } 00114 00115 value_type 00116 fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile 00117 { 00118 value_type original = load(memory_order_relaxed); 00119 do { 00120 } while (!compare_exchange_weak(original, original | v, order, memory_order_relaxed)); 00121 return original; 00122 } 00123 00124 value_type 00125 fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile 00126 { 00127 value_type original = load(memory_order_relaxed); 00128 do { 00129 } while (!compare_exchange_weak(original, original ^ v, order, memory_order_relaxed)); 00130 return original; 00131 } 00132 00133 bool 00134 is_lock_free(void) const volatile 00135 { 00136 return true; 00137 } 00138 00139 BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS 00140 private: 00141 base_atomic(const base_atomic &) /* = delete */ ; 00142 void operator=(const base_atomic &) /* = delete */ ; 00143 value_type v_; 00144 }; 00145 00146 /* pointer types */ 00147 00148 template<bool Sign> 00149 class base_atomic<void *, void *, 8, Sign> { 00150 typedef base_atomic this_type; 00151 typedef void * value_type; 00152 typedef ptrdiff_t difference_type; 00153 public: 00154 explicit base_atomic(value_type v) : v_(v) {} 00155 base_atomic(void) {} 00156 00157 void 00158 store(value_type v, memory_order order = memory_order_seq_cst) volatile 00159 { 00160 value_type expected = v_; 00161 do { 00162 } while (!compare_exchange_strong(expected, v, order, memory_order_relaxed)); 00163 } 00164 00165 value_type 00166 load(memory_order order = memory_order_seq_cst) const volatile 00167 { 00168 value_type v = const_cast<const volatile value_type &>(v_); 00169 do { 00170 } while (!const_cast<base_atomic *>(this)->compare_exchange_strong(v, v, order, memory_order_relaxed)); 00171 return v; 00172 } 00173 00174 value_type 00175 exchange(value_type v, memory_order order = memory_order_seq_cst) volatile 00176 { 00177 value_type original = load(memory_order_relaxed); 00178 do { 00179 } while (!compare_exchange_weak(original, v, order, memory_order_relaxed)); 00180 return original; 00181 } 00182 00183 bool 00184 compare_exchange_weak( 00185 value_type & expected, 00186 value_type desired, 00187 memory_order success_order, 00188 memory_order failure_order) volatile 00189 { 00190 return compare_exchange_strong(expected, desired, success_order, failure_order); 00191 } 00192 00193 bool 00194 compare_exchange_strong( 00195 value_type & expected, 00196 value_type desired, 00197 memory_order success_order, 00198 memory_order failure_order) volatile 00199 { 00200 platform_fence_before(success_order); 00201 00202 bool success = platform_cmpxchg64_strong(expected, desired, &v_); 00203 00204 if (success) { 00205 platform_fence_after(success_order); 00206 } else { 00207 platform_fence_after(failure_order); 00208 } 00209 00210 return success; 00211 } 00212 00213 value_type 00214 fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile 00215 { 00216 value_type original = load(memory_order_relaxed); 00217 do { 00218 } while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed)); 00219 return original; 00220 } 00221 00222 value_type 00223 fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile 00224 { 00225 value_type original = load(memory_order_relaxed); 00226 do { 00227 } while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed)); 00228 return original; 00229 } 00230 00231 bool 00232 is_lock_free(void) const volatile 00233 { 00234 return true; 00235 } 00236 00237 BOOST_ATOMIC_DECLARE_BASE_OPERATORS 00238 private: 00239 base_atomic(const base_atomic &) /* = delete */ ; 00240 void operator=(const base_atomic &) /* = delete */ ; 00241 value_type v_; 00242 }; 00243 00244 template<typename T, bool Sign> 00245 class base_atomic<T *, void *, 8, Sign> { 00246 typedef base_atomic this_type; 00247 typedef T * value_type; 00248 typedef ptrdiff_t difference_type; 00249 public: 00250 explicit base_atomic(value_type v) : v_(v) {} 00251 base_atomic(void) {} 00252 00253 void 00254 store(value_type v, memory_order order = memory_order_seq_cst) volatile 00255 { 00256 value_type expected = v_; 00257 do { 00258 } while (!compare_exchange_strong(expected, v, order, memory_order_relaxed)); 00259 } 00260 00261 value_type 00262 load(memory_order order = memory_order_seq_cst) const volatile 00263 { 00264 value_type v = const_cast<const volatile value_type &>(v_); 00265 do { 00266 } while (!const_cast<base_atomic *>(this)->compare_exchange_strong(v, v, order, memory_order_relaxed)); 00267 return v; 00268 } 00269 00270 value_type 00271 exchange(value_type v, memory_order order = memory_order_seq_cst) volatile 00272 { 00273 value_type original = load(memory_order_relaxed); 00274 do { 00275 } while (!compare_exchange_weak(original, v, order, memory_order_relaxed)); 00276 return original; 00277 } 00278 00279 bool 00280 compare_exchange_weak( 00281 value_type & expected, 00282 value_type desired, 00283 memory_order success_order, 00284 memory_order failure_order) volatile 00285 { 00286 return compare_exchange_strong(expected, desired, success_order, failure_order); 00287 } 00288 00289 bool 00290 compare_exchange_strong( 00291 value_type & expected, 00292 value_type desired, 00293 memory_order success_order, 00294 memory_order failure_order) volatile 00295 { 00296 platform_fence_before(success_order); 00297 00298 bool success = platform_cmpxchg64_strong(expected, desired, &v_); 00299 00300 if (success) { 00301 platform_fence_after(success_order); 00302 } else { 00303 platform_fence_after(failure_order); 00304 } 00305 00306 return success; 00307 } 00308 00309 value_type 00310 fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile 00311 { 00312 value_type original = load(memory_order_relaxed); 00313 do { 00314 } while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed)); 00315 return original; 00316 } 00317 00318 value_type 00319 fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile 00320 { 00321 value_type original = load(memory_order_relaxed); 00322 do { 00323 } while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed)); 00324 return original; 00325 } 00326 00327 bool 00328 is_lock_free(void) const volatile 00329 { 00330 return true; 00331 } 00332 00333 BOOST_ATOMIC_DECLARE_POINTER_OPERATORS 00334 private: 00335 base_atomic(const base_atomic &) /* = delete */ ; 00336 void operator=(const base_atomic &) /* = delete */ ; 00337 value_type v_; 00338 }; 00339 00340 /* generic types */ 00341 00342 template<typename T, bool Sign> 00343 class base_atomic<T, void, 8, Sign> { 00344 typedef base_atomic this_type; 00345 typedef T value_type; 00346 typedef uint64_t storage_type; 00347 public: 00348 explicit base_atomic(value_type v) : v_(0) 00349 { 00350 memcpy(&v_, &v, sizeof(value_type)); 00351 } 00352 base_atomic(void) : v_(0) {} 00353 00354 void 00355 store(value_type v, memory_order order = memory_order_seq_cst) volatile 00356 { 00357 value_type expected; 00358 memcpy(&expected, const_cast<storage_type *>(&v_), sizeof(value_type)); 00359 do { 00360 } while (!compare_exchange_strong(expected, v, order, memory_order_relaxed)); 00361 } 00362 00363 value_type 00364 load(memory_order order = memory_order_seq_cst) const volatile 00365 { 00366 value_type v; 00367 memcpy(&v, const_cast<storage_type *>(&v_), sizeof(value_type)); 00368 do { 00369 } while (!const_cast<base_atomic *>(this)->compare_exchange_strong(v, v, order, memory_order_relaxed)); 00370 return v; 00371 } 00372 00373 value_type 00374 exchange(value_type v, memory_order order = memory_order_seq_cst) volatile 00375 { 00376 value_type original = load(memory_order_relaxed); 00377 do { 00378 } while (!compare_exchange_weak(original, v, order, memory_order_relaxed)); 00379 return original; 00380 } 00381 00382 bool 00383 compare_exchange_weak( 00384 value_type & expected, 00385 value_type desired, 00386 memory_order success_order, 00387 memory_order failure_order) volatile 00388 { 00389 return compare_exchange_strong(expected, desired, success_order, failure_order); 00390 } 00391 00392 bool 00393 compare_exchange_strong( 00394 value_type & expected, 00395 value_type desired, 00396 memory_order success_order, 00397 memory_order failure_order) volatile 00398 { 00399 00400 storage_type expected_s = 0, desired_s = 0; 00401 memcpy(&expected_s, &expected, sizeof(value_type)); 00402 memcpy(&desired_s, &desired, sizeof(value_type)); 00403 00404 platform_fence_before(success_order); 00405 bool success = platform_cmpxchg64_strong(expected_s, desired_s, &v_); 00406 00407 if (success) { 00408 platform_fence_after(success_order); 00409 } else { 00410 platform_fence_after(failure_order); 00411 memcpy(&expected, &expected_s, sizeof(value_type)); 00412 } 00413 00414 return success; 00415 } 00416 00417 bool 00418 is_lock_free(void) const volatile 00419 { 00420 return true; 00421 } 00422 00423 BOOST_ATOMIC_DECLARE_BASE_OPERATORS 00424 private: 00425 base_atomic(const base_atomic &) /* = delete */ ; 00426 void operator=(const base_atomic &) /* = delete */ ; 00427 storage_type v_; 00428 }; 00429 00430 } 00431 } 00432 } 00433 00434 #endif