00001 #ifndef BOOST_DETAIL_ATOMIC_CAS64STRONG_HPP
00002 #define BOOST_DETAIL_ATOMIC_CAS64STRONG_HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
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 &) ;
00142 void operator=(const base_atomic &) ;
00143 value_type v_;
00144 };
00145
00146
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 &) ;
00240 void operator=(const base_atomic &) ;
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 &) ;
00336 void operator=(const base_atomic &) ;
00337 value_type v_;
00338 };
00339
00340
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 &) ;
00426 void operator=(const base_atomic &) ;
00427 storage_type v_;
00428 };
00429
00430 }
00431 }
00432 }
00433
00434 #endif