$search
00001 #ifndef BOOST_DETAIL_ATOMIC_CAS32WEAK_HPP 00002 #define BOOST_DETAIL_ATOMIC_CAS32WEAK_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 #include <boost/memory_order.hpp> 00011 #include <boost/atomic/detail/base.hpp> 00012 00013 namespace boost { 00014 namespace detail { 00015 namespace atomic { 00016 00017 /* integral types */ 00018 00019 template<typename T, bool Sign> 00020 class base_atomic<T, int, 1, Sign> { 00021 typedef base_atomic this_type; 00022 typedef T value_type; 00023 typedef T difference_type; 00024 typedef uint32_t storage_type; 00025 public: 00026 explicit base_atomic(value_type v) : v_(v) {} 00027 base_atomic(void) {} 00028 00029 void 00030 store(value_type v, memory_order order = memory_order_seq_cst) volatile 00031 { 00032 platform_fence_before_store(order); 00033 const_cast<volatile storage_type &>(v_) = v; 00034 platform_fence_after_store(order); 00035 } 00036 00037 value_type 00038 load(memory_order order = memory_order_seq_cst) const volatile 00039 { 00040 value_type v = const_cast<const volatile storage_type &>(v_); 00041 platform_fence_after_load(order); 00042 return v; 00043 } 00044 00045 value_type 00046 exchange(value_type v, memory_order order = memory_order_seq_cst) volatile 00047 { 00048 value_type original = load(memory_order_relaxed); 00049 do { 00050 } while (!compare_exchange_weak(original, v, order, memory_order_relaxed)); 00051 return original; 00052 } 00053 00054 bool 00055 compare_exchange_weak( 00056 value_type & expected, 00057 value_type desired, 00058 memory_order success_order, 00059 memory_order failure_order) volatile 00060 { 00061 platform_fence_before(success_order); 00062 00063 storage_type expected_s = (storage_type) expected; 00064 storage_type desired_s = (storage_type) desired; 00065 00066 bool success = platform_cmpxchg32(expected_s, desired_s, &v_); 00067 00068 if (success) { 00069 platform_fence_after(success_order); 00070 } else { 00071 platform_fence_after(failure_order); 00072 expected = (value_type) expected_s; 00073 } 00074 00075 return success; 00076 } 00077 00078 bool 00079 compare_exchange_strong( 00080 value_type & expected, 00081 value_type desired, 00082 memory_order success_order, 00083 memory_order failure_order) volatile 00084 { 00085 for(;;) { 00086 value_type tmp = expected; 00087 if (compare_exchange_weak(tmp, desired, success_order, failure_order)) 00088 return true; 00089 if (tmp != expected) { 00090 expected = tmp; 00091 return false; 00092 } 00093 } 00094 } 00095 00096 value_type 00097 fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile 00098 { 00099 value_type original = load(memory_order_relaxed); 00100 do { 00101 } while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed)); 00102 return original; 00103 } 00104 00105 value_type 00106 fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile 00107 { 00108 value_type original = load(memory_order_relaxed); 00109 do { 00110 } while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed)); 00111 return original; 00112 } 00113 00114 value_type 00115 fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile 00116 { 00117 value_type original = load(memory_order_relaxed); 00118 do { 00119 } while (!compare_exchange_weak(original, original & v, order, memory_order_relaxed)); 00120 return original; 00121 } 00122 00123 value_type 00124 fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile 00125 { 00126 value_type original = load(memory_order_relaxed); 00127 do { 00128 } while (!compare_exchange_weak(original, original | v, order, memory_order_relaxed)); 00129 return original; 00130 } 00131 00132 value_type 00133 fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile 00134 { 00135 value_type original = load(memory_order_relaxed); 00136 do { 00137 } while (!compare_exchange_weak(original, original ^ v, order, memory_order_relaxed)); 00138 return original; 00139 } 00140 00141 bool 00142 is_lock_free(void) const volatile 00143 { 00144 return true; 00145 } 00146 00147 BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS 00148 private: 00149 base_atomic(const base_atomic &) /* = delete */ ; 00150 void operator=(const base_atomic &) /* = delete */ ; 00151 storage_type v_; 00152 }; 00153 00154 template<typename T, bool Sign> 00155 class base_atomic<T, int, 2, Sign> { 00156 typedef base_atomic this_type; 00157 typedef T value_type; 00158 typedef T difference_type; 00159 typedef uint32_t storage_type; 00160 public: 00161 explicit base_atomic(value_type v) : v_(v) {} 00162 base_atomic(void) {} 00163 00164 void 00165 store(value_type v, memory_order order = memory_order_seq_cst) volatile 00166 { 00167 platform_fence_before_store(order); 00168 const_cast<volatile storage_type &>(v_) = v; 00169 platform_fence_after_store(order); 00170 } 00171 00172 value_type 00173 load(memory_order order = memory_order_seq_cst) const volatile 00174 { 00175 value_type v = const_cast<const volatile storage_type &>(v_); 00176 platform_fence_after_load(order); 00177 return v; 00178 } 00179 00180 value_type 00181 exchange(value_type v, memory_order order = memory_order_seq_cst) volatile 00182 { 00183 value_type original = load(memory_order_relaxed); 00184 do { 00185 } while (!compare_exchange_weak(original, v, order, memory_order_relaxed)); 00186 return original; 00187 } 00188 00189 bool 00190 compare_exchange_weak( 00191 value_type & expected, 00192 value_type desired, 00193 memory_order success_order, 00194 memory_order failure_order) volatile 00195 { 00196 platform_fence_before(success_order); 00197 00198 storage_type expected_s = (storage_type) expected; 00199 storage_type desired_s = (storage_type) desired; 00200 00201 bool success = platform_cmpxchg32(expected_s, desired_s, &v_); 00202 00203 if (success) { 00204 platform_fence_after(success_order); 00205 } else { 00206 platform_fence_after(failure_order); 00207 expected = (value_type) expected_s; 00208 } 00209 00210 return success; 00211 } 00212 00213 bool 00214 compare_exchange_strong( 00215 value_type & expected, 00216 value_type desired, 00217 memory_order success_order, 00218 memory_order failure_order) volatile 00219 { 00220 for(;;) { 00221 value_type tmp = expected; 00222 if (compare_exchange_weak(tmp, desired, success_order, failure_order)) 00223 return true; 00224 if (tmp != expected) { 00225 expected = tmp; 00226 return false; 00227 } 00228 } 00229 } 00230 00231 value_type 00232 fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile 00233 { 00234 value_type original = load(memory_order_relaxed); 00235 do { 00236 } while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed)); 00237 return original; 00238 } 00239 00240 value_type 00241 fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile 00242 { 00243 value_type original = load(memory_order_relaxed); 00244 do { 00245 } while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed)); 00246 return original; 00247 } 00248 00249 value_type 00250 fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile 00251 { 00252 value_type original = load(memory_order_relaxed); 00253 do { 00254 } while (!compare_exchange_weak(original, original & v, order, memory_order_relaxed)); 00255 return original; 00256 } 00257 00258 value_type 00259 fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile 00260 { 00261 value_type original = load(memory_order_relaxed); 00262 do { 00263 } while (!compare_exchange_weak(original, original | v, order, memory_order_relaxed)); 00264 return original; 00265 } 00266 00267 value_type 00268 fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile 00269 { 00270 value_type original = load(memory_order_relaxed); 00271 do { 00272 } while (!compare_exchange_weak(original, original ^ v, order, memory_order_relaxed)); 00273 return original; 00274 } 00275 00276 bool 00277 is_lock_free(void) const volatile 00278 { 00279 return true; 00280 } 00281 00282 BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS 00283 private: 00284 base_atomic(const base_atomic &) /* = delete */ ; 00285 void operator=(const base_atomic &) /* = delete */ ; 00286 storage_type v_; 00287 }; 00288 00289 template<typename T, bool Sign> 00290 class base_atomic<T, int, 4, Sign> { 00291 typedef base_atomic this_type; 00292 typedef T value_type; 00293 typedef T difference_type; 00294 public: 00295 explicit base_atomic(value_type v) : v_(v) {} 00296 base_atomic(void) {} 00297 00298 void 00299 store(value_type v, memory_order order = memory_order_seq_cst) volatile 00300 { 00301 platform_fence_before_store(order); 00302 const_cast<volatile value_type &>(v_) = v; 00303 platform_fence_after_store(order); 00304 } 00305 00306 value_type 00307 load(memory_order order = memory_order_seq_cst) const volatile 00308 { 00309 value_type v = const_cast<const volatile value_type &>(v_); 00310 platform_fence_after_load(order); 00311 return v; 00312 } 00313 00314 value_type 00315 exchange(value_type v, memory_order order = memory_order_seq_cst) volatile 00316 { 00317 value_type original = load(memory_order_relaxed); 00318 do { 00319 } while (!compare_exchange_weak(original, v, order, memory_order_relaxed)); 00320 return original; 00321 } 00322 00323 bool 00324 compare_exchange_weak( 00325 value_type & expected, 00326 value_type desired, 00327 memory_order success_order, 00328 memory_order failure_order) volatile 00329 { 00330 platform_fence_before(success_order); 00331 00332 bool success = platform_cmpxchg32(expected, desired, &v_); 00333 00334 if (success) { 00335 platform_fence_after(success_order); 00336 } else { 00337 platform_fence_after(failure_order); 00338 } 00339 00340 return success; 00341 } 00342 00343 bool 00344 compare_exchange_strong( 00345 value_type & expected, 00346 value_type desired, 00347 memory_order success_order, 00348 memory_order failure_order) volatile 00349 { 00350 for(;;) { 00351 value_type tmp = expected; 00352 if (compare_exchange_weak(tmp, desired, success_order, failure_order)) 00353 return true; 00354 if (tmp != expected) { 00355 expected = tmp; 00356 return false; 00357 } 00358 } 00359 } 00360 00361 value_type 00362 fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile 00363 { 00364 value_type original = load(memory_order_relaxed); 00365 do { 00366 } while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed)); 00367 return original; 00368 } 00369 00370 value_type 00371 fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile 00372 { 00373 value_type original = load(memory_order_relaxed); 00374 do { 00375 } while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed)); 00376 return original; 00377 } 00378 00379 value_type 00380 fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile 00381 { 00382 value_type original = load(memory_order_relaxed); 00383 do { 00384 } while (!compare_exchange_weak(original, original & v, order, memory_order_relaxed)); 00385 return original; 00386 } 00387 00388 value_type 00389 fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile 00390 { 00391 value_type original = load(memory_order_relaxed); 00392 do { 00393 } while (!compare_exchange_weak(original, original | v, order, memory_order_relaxed)); 00394 return original; 00395 } 00396 00397 value_type 00398 fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile 00399 { 00400 value_type original = load(memory_order_relaxed); 00401 do { 00402 } while (!compare_exchange_weak(original, original ^ v, order, memory_order_relaxed)); 00403 return original; 00404 } 00405 00406 bool 00407 is_lock_free(void) const volatile 00408 { 00409 return true; 00410 } 00411 00412 BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS 00413 private: 00414 base_atomic(const base_atomic &) /* = delete */ ; 00415 void operator=(const base_atomic &) /* = delete */ ; 00416 value_type v_; 00417 }; 00418 00419 /* pointer types */ 00420 00421 template<bool Sign> 00422 class base_atomic<void *, void *, 4, Sign> { 00423 typedef base_atomic this_type; 00424 typedef void * value_type; 00425 typedef ptrdiff_t difference_type; 00426 public: 00427 explicit base_atomic(value_type v) : v_(v) {} 00428 base_atomic(void) {} 00429 00430 void 00431 store(value_type v, memory_order order = memory_order_seq_cst) volatile 00432 { 00433 platform_fence_before_store(order); 00434 const_cast<volatile value_type &>(v_) = v; 00435 platform_fence_after_store(order); 00436 } 00437 00438 value_type 00439 load(memory_order order = memory_order_seq_cst) const volatile 00440 { 00441 value_type v = const_cast<const volatile value_type &>(v_); 00442 platform_fence_after_load(order); 00443 return v; 00444 } 00445 00446 value_type 00447 exchange(value_type v, memory_order order = memory_order_seq_cst) volatile 00448 { 00449 value_type original = load(memory_order_relaxed); 00450 do { 00451 } while (!compare_exchange_weak(original, v, order, memory_order_relaxed)); 00452 return original; 00453 } 00454 00455 bool 00456 compare_exchange_weak( 00457 value_type & expected, 00458 value_type desired, 00459 memory_order success_order, 00460 memory_order failure_order) volatile 00461 { 00462 platform_fence_before(success_order); 00463 00464 bool success = platform_cmpxchg32(expected, desired, &v_); 00465 00466 if (success) { 00467 platform_fence_after(success_order); 00468 } else { 00469 platform_fence_after(failure_order); 00470 } 00471 00472 return success; 00473 } 00474 00475 bool 00476 compare_exchange_strong( 00477 value_type & expected, 00478 value_type desired, 00479 memory_order success_order, 00480 memory_order failure_order) volatile 00481 { 00482 for(;;) { 00483 value_type tmp = expected; 00484 if (compare_exchange_weak(tmp, desired, success_order, failure_order)) 00485 return true; 00486 if (tmp != expected) { 00487 expected = tmp; 00488 return false; 00489 } 00490 } 00491 } 00492 00493 value_type 00494 fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile 00495 { 00496 value_type original = load(memory_order_relaxed); 00497 do { 00498 } while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed)); 00499 return original; 00500 } 00501 00502 value_type 00503 fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile 00504 { 00505 value_type original = load(memory_order_relaxed); 00506 do { 00507 } while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed)); 00508 return original; 00509 } 00510 00511 bool 00512 is_lock_free(void) const volatile 00513 { 00514 return true; 00515 } 00516 00517 BOOST_ATOMIC_DECLARE_BASE_OPERATORS 00518 private: 00519 base_atomic(const base_atomic &) /* = delete */ ; 00520 void operator=(const base_atomic &) /* = delete */ ; 00521 value_type v_; 00522 }; 00523 00524 template<typename T, bool Sign> 00525 class base_atomic<T *, void *, 4, Sign> { 00526 typedef base_atomic this_type; 00527 typedef T * value_type; 00528 typedef ptrdiff_t difference_type; 00529 public: 00530 explicit base_atomic(value_type v) : v_(v) {} 00531 base_atomic(void) {} 00532 00533 void 00534 store(value_type v, memory_order order = memory_order_seq_cst) volatile 00535 { 00536 platform_fence_before_store(order); 00537 const_cast<volatile value_type &>(v_) = v; 00538 platform_fence_after_store(order); 00539 } 00540 00541 value_type 00542 load(memory_order order = memory_order_seq_cst) const volatile 00543 { 00544 value_type v = const_cast<const volatile value_type &>(v_); 00545 platform_fence_after_load(order); 00546 return v; 00547 } 00548 00549 value_type 00550 exchange(value_type v, memory_order order = memory_order_seq_cst) volatile 00551 { 00552 value_type original = load(memory_order_relaxed); 00553 do { 00554 } while (!compare_exchange_weak(original, v, order, memory_order_relaxed)); 00555 return original; 00556 } 00557 00558 bool 00559 compare_exchange_weak( 00560 value_type & expected, 00561 value_type desired, 00562 memory_order success_order, 00563 memory_order failure_order) volatile 00564 { 00565 platform_fence_before(success_order); 00566 00567 bool success = platform_cmpxchg32(expected, desired, &v_); 00568 00569 if (success) { 00570 platform_fence_after(success_order); 00571 } else { 00572 platform_fence_after(failure_order); 00573 } 00574 00575 return success; 00576 } 00577 00578 bool 00579 compare_exchange_strong( 00580 value_type & expected, 00581 value_type desired, 00582 memory_order success_order, 00583 memory_order failure_order) volatile 00584 { 00585 for(;;) { 00586 value_type tmp = expected; 00587 if (compare_exchange_weak(tmp, desired, success_order, failure_order)) 00588 return true; 00589 if (tmp != expected) { 00590 expected = tmp; 00591 return false; 00592 } 00593 } 00594 } 00595 00596 value_type 00597 fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile 00598 { 00599 value_type original = load(memory_order_relaxed); 00600 do { 00601 } while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed)); 00602 return original; 00603 } 00604 00605 value_type 00606 fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile 00607 { 00608 value_type original = load(memory_order_relaxed); 00609 do { 00610 } while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed)); 00611 return original; 00612 } 00613 00614 bool 00615 is_lock_free(void) const volatile 00616 { 00617 return true; 00618 } 00619 00620 BOOST_ATOMIC_DECLARE_POINTER_OPERATORS 00621 private: 00622 base_atomic(const base_atomic &) /* = delete */ ; 00623 void operator=(const base_atomic &) /* = delete */ ; 00624 value_type v_; 00625 }; 00626 00627 /* generic types */ 00628 00629 template<typename T, bool Sign> 00630 class base_atomic<T, void, 1, Sign> { 00631 typedef base_atomic this_type; 00632 typedef T value_type; 00633 typedef uint32_t storage_type; 00634 public: 00635 explicit base_atomic(value_type v) : v_(0) 00636 { 00637 memcpy(&v_, &v, sizeof(value_type)); 00638 } 00639 base_atomic(void) : v_(0) {} 00640 00641 void 00642 store(value_type v, memory_order order = memory_order_seq_cst) volatile 00643 { 00644 storage_type tmp = 0; 00645 memcpy(&tmp, &v, sizeof(value_type)); 00646 platform_fence_before_store(order); 00647 const_cast<volatile storage_type &>(v_) = tmp; 00648 platform_fence_after_store(order); 00649 } 00650 00651 value_type 00652 load(memory_order order = memory_order_seq_cst) const volatile 00653 { 00654 storage_type tmp = const_cast<const volatile storage_type &>(v_); 00655 platform_fence_after_load(order); 00656 00657 value_type v; 00658 memcpy(&v, &tmp, sizeof(value_type)); 00659 return v; 00660 } 00661 00662 value_type 00663 exchange(value_type v, memory_order order = memory_order_seq_cst) volatile 00664 { 00665 value_type original = load(memory_order_relaxed); 00666 do { 00667 } while (!compare_exchange_weak(original, v, order, memory_order_relaxed)); 00668 return original; 00669 } 00670 00671 bool 00672 compare_exchange_weak( 00673 value_type & expected, 00674 value_type desired, 00675 memory_order success_order, 00676 memory_order failure_order) volatile 00677 { 00678 storage_type expected_s = 0, desired_s = 0; 00679 memcpy(&expected_s, &expected, sizeof(value_type)); 00680 memcpy(&desired_s, &desired, sizeof(value_type)); 00681 00682 platform_fence_before(success_order); 00683 00684 bool success = platform_cmpxchg32(expected_s, desired_s, &v_); 00685 00686 if (success) { 00687 platform_fence_after(success_order); 00688 } else { 00689 platform_fence_after(failure_order); 00690 memcpy(&expected, &expected_s, sizeof(value_type)); 00691 } 00692 00693 return success; 00694 } 00695 00696 bool 00697 compare_exchange_strong( 00698 value_type & expected, 00699 value_type desired, 00700 memory_order success_order, 00701 memory_order failure_order) volatile 00702 { 00703 for(;;) { 00704 value_type tmp = expected; 00705 if (compare_exchange_weak(tmp, desired, success_order, failure_order)) 00706 return true; 00707 if (tmp != expected) { 00708 expected = tmp; 00709 return false; 00710 } 00711 } 00712 } 00713 00714 bool 00715 is_lock_free(void) const volatile 00716 { 00717 return true; 00718 } 00719 00720 BOOST_ATOMIC_DECLARE_BASE_OPERATORS 00721 private: 00722 base_atomic(const base_atomic &) /* = delete */ ; 00723 void operator=(const base_atomic &) /* = delete */ ; 00724 storage_type v_; 00725 }; 00726 00727 template<typename T, bool Sign> 00728 class base_atomic<T, void, 2, Sign> { 00729 typedef base_atomic this_type; 00730 typedef T value_type; 00731 typedef uint32_t storage_type; 00732 public: 00733 explicit base_atomic(value_type v) : v_(0) 00734 { 00735 memcpy(&v_, &v, sizeof(value_type)); 00736 } 00737 base_atomic(void) : v_(0) {} 00738 00739 void 00740 store(value_type v, memory_order order = memory_order_seq_cst) volatile 00741 { 00742 storage_type tmp = 0; 00743 memcpy(&tmp, &v, sizeof(value_type)); 00744 platform_fence_before_store(order); 00745 const_cast<volatile storage_type &>(v_) = tmp; 00746 platform_fence_after_store(order); 00747 } 00748 00749 value_type 00750 load(memory_order order = memory_order_seq_cst) const volatile 00751 { 00752 storage_type tmp = const_cast<const volatile storage_type &>(v_); 00753 platform_fence_after_load(order); 00754 00755 value_type v; 00756 memcpy(&v, &tmp, sizeof(value_type)); 00757 return v; 00758 } 00759 00760 value_type 00761 exchange(value_type v, memory_order order = memory_order_seq_cst) volatile 00762 { 00763 value_type original = load(memory_order_relaxed); 00764 do { 00765 } while (!compare_exchange_weak(original, v, order, memory_order_relaxed)); 00766 return original; 00767 } 00768 00769 bool 00770 compare_exchange_weak( 00771 value_type & expected, 00772 value_type desired, 00773 memory_order success_order, 00774 memory_order failure_order) volatile 00775 { 00776 storage_type expected_s = 0, desired_s = 0; 00777 memcpy(&expected_s, &expected, sizeof(value_type)); 00778 memcpy(&desired_s, &desired, sizeof(value_type)); 00779 00780 platform_fence_before(success_order); 00781 00782 bool success = platform_cmpxchg32(expected_s, desired_s, &v_); 00783 00784 if (success) { 00785 platform_fence_after(success_order); 00786 } else { 00787 platform_fence_after(failure_order); 00788 memcpy(&expected, &expected_s, sizeof(value_type)); 00789 } 00790 00791 return success; 00792 } 00793 00794 bool 00795 compare_exchange_strong( 00796 value_type & expected, 00797 value_type desired, 00798 memory_order success_order, 00799 memory_order failure_order) volatile 00800 { 00801 for(;;) { 00802 value_type tmp = expected; 00803 if (compare_exchange_weak(tmp, desired, success_order, failure_order)) 00804 return true; 00805 if (tmp != expected) { 00806 expected = tmp; 00807 return false; 00808 } 00809 } 00810 } 00811 00812 bool 00813 is_lock_free(void) const volatile 00814 { 00815 return true; 00816 } 00817 00818 BOOST_ATOMIC_DECLARE_BASE_OPERATORS 00819 private: 00820 base_atomic(const base_atomic &) /* = delete */ ; 00821 void operator=(const base_atomic &) /* = delete */ ; 00822 storage_type v_; 00823 }; 00824 00825 template<typename T, bool Sign> 00826 class base_atomic<T, void, 4, Sign> { 00827 typedef base_atomic this_type; 00828 typedef T value_type; 00829 typedef uint32_t storage_type; 00830 public: 00831 explicit base_atomic(value_type v) : v_(0) 00832 { 00833 memcpy(&v_, &v, sizeof(value_type)); 00834 } 00835 base_atomic(void) : v_(0) {} 00836 00837 void 00838 store(value_type v, memory_order order = memory_order_seq_cst) volatile 00839 { 00840 storage_type tmp = 0; 00841 memcpy(&tmp, &v, sizeof(value_type)); 00842 platform_fence_before_store(order); 00843 const_cast<volatile storage_type &>(v_) = tmp; 00844 platform_fence_after_store(order); 00845 } 00846 00847 value_type 00848 load(memory_order order = memory_order_seq_cst) const volatile 00849 { 00850 storage_type tmp = const_cast<const volatile storage_type &>(v_); 00851 platform_fence_after_load(order); 00852 00853 value_type v; 00854 memcpy(&v, &tmp, sizeof(value_type)); 00855 return v; 00856 } 00857 00858 value_type 00859 exchange(value_type v, memory_order order = memory_order_seq_cst) volatile 00860 { 00861 value_type original = load(memory_order_relaxed); 00862 do { 00863 } while (!compare_exchange_weak(original, v, order, memory_order_relaxed)); 00864 return original; 00865 } 00866 00867 bool 00868 compare_exchange_weak( 00869 value_type & expected, 00870 value_type desired, 00871 memory_order success_order, 00872 memory_order failure_order) volatile 00873 { 00874 storage_type expected_s = 0, desired_s = 0; 00875 memcpy(&expected_s, &expected, sizeof(value_type)); 00876 memcpy(&desired_s, &desired, sizeof(value_type)); 00877 00878 platform_fence_before(success_order); 00879 00880 bool success = platform_cmpxchg32(expected_s, desired_s, &v_); 00881 00882 if (success) { 00883 platform_fence_after(success_order); 00884 } else { 00885 platform_fence_after(failure_order); 00886 memcpy(&expected, &expected_s, sizeof(value_type)); 00887 } 00888 00889 return success; 00890 } 00891 00892 bool 00893 compare_exchange_strong( 00894 value_type & expected, 00895 value_type desired, 00896 memory_order success_order, 00897 memory_order failure_order) volatile 00898 { 00899 for(;;) { 00900 value_type tmp = expected; 00901 if (compare_exchange_weak(tmp, desired, success_order, failure_order)) 00902 return true; 00903 if (tmp != expected) { 00904 expected = tmp; 00905 return false; 00906 } 00907 } 00908 } 00909 00910 bool 00911 is_lock_free(void) const volatile 00912 { 00913 return true; 00914 } 00915 00916 BOOST_ATOMIC_DECLARE_BASE_OPERATORS 00917 private: 00918 base_atomic(const base_atomic &) /* = delete */ ; 00919 void operator=(const base_atomic &) /* = delete */ ; 00920 storage_type v_; 00921 }; 00922 00923 } 00924 } 00925 } 00926 00927 #endif