cas64strong.hpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. #ifndef BOOST_ATOMIC_DETAIL_CAS64STRONG_HPP
  2. #define BOOST_ATOMIC_DETAIL_CAS64STRONG_HPP
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // Copyright (c) 2011 Helge Bahmann
  8. // Copyright (c) 2013 Tim Blechmann
  9. // Build 64-bit atomic operation on integers/UDTs from platform_cmpxchg64_strong
  10. // primitive. It is assumed that 64-bit loads/stores are not
  11. // atomic, so they are implemented through platform_load64/platform_store64.
  12. #include <string.h>
  13. #include <cstddef>
  14. #include <boost/cstdint.hpp>
  15. #include <boost/memory_order.hpp>
  16. #include <boost/atomic/detail/config.hpp>
  17. #include <boost/atomic/detail/base.hpp>
  18. #ifdef BOOST_HAS_PRAGMA_ONCE
  19. #pragma once
  20. #endif
  21. namespace boost {
  22. namespace atomics {
  23. namespace detail {
  24. /* integral types */
  25. template<typename T, bool Sign>
  26. class base_atomic<T, int, 8, Sign>
  27. {
  28. private:
  29. typedef base_atomic this_type;
  30. typedef T value_type;
  31. typedef T difference_type;
  32. protected:
  33. typedef value_type value_arg_type;
  34. public:
  35. BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
  36. BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
  37. void
  38. store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  39. {
  40. platform_fence_before_store(order);
  41. platform_store64(v, &v_);
  42. platform_fence_after_store(order);
  43. }
  44. value_type
  45. load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
  46. {
  47. value_type v = platform_load64(&v_);
  48. platform_fence_after_load(order);
  49. return v;
  50. }
  51. value_type
  52. exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  53. {
  54. value_type original = load(memory_order_relaxed);
  55. do {
  56. } while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
  57. return original;
  58. }
  59. bool
  60. compare_exchange_weak(
  61. value_type & expected,
  62. value_type desired,
  63. memory_order success_order,
  64. memory_order failure_order) volatile BOOST_NOEXCEPT
  65. {
  66. return compare_exchange_strong(expected, desired, success_order, failure_order);
  67. }
  68. bool
  69. compare_exchange_strong(
  70. value_type & expected,
  71. value_type desired,
  72. memory_order success_order,
  73. memory_order failure_order) volatile BOOST_NOEXCEPT
  74. {
  75. platform_fence_before(success_order);
  76. bool success = platform_cmpxchg64_strong(expected, desired, &v_);
  77. if (success) {
  78. platform_fence_after(success_order);
  79. } else {
  80. platform_fence_after(failure_order);
  81. }
  82. return success;
  83. }
  84. value_type
  85. fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  86. {
  87. value_type original = load(memory_order_relaxed);
  88. do {
  89. } while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
  90. return original;
  91. }
  92. value_type
  93. fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  94. {
  95. value_type original = load(memory_order_relaxed);
  96. do {
  97. } while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
  98. return original;
  99. }
  100. value_type
  101. fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  102. {
  103. value_type original = load(memory_order_relaxed);
  104. do {
  105. } while (!compare_exchange_weak(original, original & v, order, memory_order_relaxed));
  106. return original;
  107. }
  108. value_type
  109. fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  110. {
  111. value_type original = load(memory_order_relaxed);
  112. do {
  113. } while (!compare_exchange_weak(original, original | v, order, memory_order_relaxed));
  114. return original;
  115. }
  116. value_type
  117. fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  118. {
  119. value_type original = load(memory_order_relaxed);
  120. do {
  121. } while (!compare_exchange_weak(original, original ^ v, order, memory_order_relaxed));
  122. return original;
  123. }
  124. bool
  125. is_lock_free(void) const volatile BOOST_NOEXCEPT
  126. {
  127. return true;
  128. }
  129. BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
  130. BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
  131. BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
  132. private:
  133. value_type v_;
  134. };
  135. /* generic types */
  136. template<typename T, bool Sign>
  137. class base_atomic<T, void, 8, Sign>
  138. {
  139. private:
  140. typedef base_atomic this_type;
  141. typedef T value_type;
  142. typedef uint64_t storage_type;
  143. protected:
  144. typedef value_type const& value_arg_type;
  145. public:
  146. BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
  147. explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
  148. {
  149. memcpy(&v_, &v, sizeof(value_type));
  150. }
  151. void
  152. store(value_type const& value, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  153. {
  154. storage_type value_s = 0;
  155. memcpy(&value_s, &value, sizeof(value_type));
  156. platform_fence_before_store(order);
  157. platform_store64(value_s, &v_);
  158. platform_fence_after_store(order);
  159. }
  160. value_type
  161. load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
  162. {
  163. storage_type value_s = platform_load64(&v_);
  164. platform_fence_after_load(order);
  165. value_type value;
  166. memcpy(&value, &value_s, sizeof(value_type));
  167. return value;
  168. }
  169. value_type
  170. exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  171. {
  172. value_type original = load(memory_order_relaxed);
  173. do {
  174. } while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
  175. return original;
  176. }
  177. bool
  178. compare_exchange_weak(
  179. value_type & expected,
  180. value_type const& desired,
  181. memory_order success_order,
  182. memory_order failure_order) volatile BOOST_NOEXCEPT
  183. {
  184. return compare_exchange_strong(expected, desired, success_order, failure_order);
  185. }
  186. bool
  187. compare_exchange_strong(
  188. value_type & expected,
  189. value_type const& desired,
  190. memory_order success_order,
  191. memory_order failure_order) volatile BOOST_NOEXCEPT
  192. {
  193. storage_type expected_s = 0, desired_s = 0;
  194. memcpy(&expected_s, &expected, sizeof(value_type));
  195. memcpy(&desired_s, &desired, sizeof(value_type));
  196. platform_fence_before(success_order);
  197. bool success = platform_cmpxchg64_strong(expected_s, desired_s, &v_);
  198. if (success) {
  199. platform_fence_after(success_order);
  200. } else {
  201. platform_fence_after(failure_order);
  202. memcpy(&expected, &expected_s, sizeof(value_type));
  203. }
  204. return success;
  205. }
  206. bool
  207. is_lock_free(void) const volatile BOOST_NOEXCEPT
  208. {
  209. return true;
  210. }
  211. BOOST_ATOMIC_DECLARE_BASE_OPERATORS
  212. BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
  213. BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
  214. private:
  215. storage_type v_;
  216. };
  217. }
  218. }
  219. }
  220. #endif