generic-cas.hpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. #ifndef BOOST_ATOMIC_DETAIL_GENERIC_CAS_HPP
  2. #define BOOST_ATOMIC_DETAIL_GENERIC_CAS_HPP
  3. // Copyright (c) 2009 Helge Bahmann
  4. //
  5. // Distributed under the Boost Software License, Version 1.0.
  6. // See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. #include <cstddef>
  9. #include <boost/cstdint.hpp>
  10. #include <boost/memory_order.hpp>
  11. #include <boost/atomic/detail/config.hpp>
  12. #include <boost/atomic/detail/base.hpp>
  13. #include <boost/atomic/detail/builder.hpp>
  14. #ifdef BOOST_HAS_PRAGMA_ONCE
  15. #pragma once
  16. #endif
  17. /* fallback implementation for various compilation targets;
  18. this is *not* efficient, particularly because all operations
  19. are fully fenced (full memory barriers before and after
  20. each operation) */
  21. #if defined(__GNUC__)
  22. namespace boost { namespace atomics { namespace detail {
  23. inline int32_t
  24. fenced_compare_exchange_strong_32(volatile int32_t *ptr, int32_t expected, int32_t desired)
  25. {
  26. return __sync_val_compare_and_swap_4(ptr, expected, desired);
  27. }
  28. #define BOOST_ATOMIC_HAVE_CAS32 1
  29. #if defined(__amd64__) || defined(__i686__)
  30. inline int64_t
  31. fenced_compare_exchange_strong_64(int64_t *ptr, int64_t expected, int64_t desired)
  32. {
  33. return __sync_val_compare_and_swap_8(ptr, expected, desired);
  34. }
  35. #define BOOST_ATOMIC_HAVE_CAS64 1
  36. #endif
  37. }}}
  38. #elif defined(__ICL) || defined(_MSC_VER)
  39. #if defined(_MSC_VER)
  40. #include <Windows.h>
  41. #include <intrin.h>
  42. #endif
  43. namespace boost { namespace atomics { namespace detail {
  44. inline int32_t
  45. fenced_compare_exchange_strong(int32_t *ptr, int32_t expected, int32_t desired)
  46. {
  47. return _InterlockedCompareExchange(reinterpret_cast<volatile long*>(ptr), desired, expected);
  48. }
  49. #define BOOST_ATOMIC_HAVE_CAS32 1
  50. #if defined(_WIN64)
  51. inline int64_t
  52. fenced_compare_exchange_strong(int64_t *ptr, int64_t expected, int64_t desired)
  53. {
  54. return _InterlockedCompareExchange64(ptr, desired, expected);
  55. }
  56. #define BOOST_ATOMIC_HAVE_CAS64 1
  57. #endif
  58. }}}
  59. #elif (defined(__ICC) || defined(__ECC))
  60. namespace boost { namespace atomics { namespace detail {
  61. inline int32_t
  62. fenced_compare_exchange_strong_32(int32_t *ptr, int32_t expected, int32_t desired)
  63. {
  64. return _InterlockedCompareExchange((void*)ptr, desired, expected);
  65. }
  66. #define BOOST_ATOMIC_HAVE_CAS32 1
  67. #if defined(__x86_64)
  68. inline int64_t
  69. fenced_compare_exchange_strong(int64_t *ptr, int64_t expected, int64_t desired)
  70. {
  71. return cas64<int>(ptr, expected, desired);
  72. }
  73. #define BOOST_ATOMIC_HAVE_CAS64 1
  74. #elif defined(__ECC) //IA-64 version
  75. inline int64_t
  76. fenced_compare_exchange_strong(int64_t *ptr, int64_t expected, int64_t desired)
  77. {
  78. return _InterlockedCompareExchange64((void*)ptr, desired, expected);
  79. }
  80. #define BOOST_ATOMIC_HAVE_CAS64 1
  81. #endif
  82. }}}
  83. #elif (defined(__SUNPRO_CC) && defined(__sparc))
  84. #include <sys/atomic.h>
  85. namespace boost { namespace atomics { namespace detail {
  86. inline int32_t
  87. fenced_compare_exchange_strong_32(int32_t *ptr, int32_t expected, int32_t desired)
  88. {
  89. return atomic_cas_32((volatile unsigned int*)ptr, expected, desired);
  90. }
  91. #define BOOST_ATOMIC_HAVE_CAS32 1
  92. /* FIXME: check for 64 bit mode */
  93. inline int64_t
  94. fenced_compare_exchange_strong_64(int64_t *ptr, int64_t expected, int64_t desired)
  95. {
  96. return atomic_cas_64((volatile unsigned long long*)ptr, expected, desired);
  97. }
  98. #define BOOST_ATOMIC_HAVE_CAS64 1
  99. }}}
  100. #endif
  101. namespace boost {
  102. namespace atomics {
  103. namespace detail {
  104. #ifdef BOOST_ATOMIC_HAVE_CAS32
  105. template<typename T>
  106. class atomic_generic_cas32
  107. {
  108. private:
  109. typedef atomic_generic_cas32 this_type;
  110. public:
  111. explicit atomic_generic_cas32(T v) : i((int32_t)v) {}
  112. atomic_generic_cas32() {}
  113. T load(memory_order order=memory_order_seq_cst) const volatile
  114. {
  115. T expected=(T)i;
  116. do { } while(!const_cast<this_type *>(this)->compare_exchange_weak(expected, expected, order, memory_order_relaxed));
  117. return expected;
  118. }
  119. void store(T v, memory_order order=memory_order_seq_cst) volatile
  120. {
  121. exchange(v);
  122. }
  123. bool compare_exchange_strong(
  124. T &expected,
  125. T desired,
  126. memory_order success_order,
  127. memory_order failure_order) volatile
  128. {
  129. T found;
  130. found=(T)fenced_compare_exchange_strong_32(&i, (int32_t)expected, (int32_t)desired);
  131. bool success=(found==expected);
  132. expected=found;
  133. return success;
  134. }
  135. bool compare_exchange_weak(
  136. T &expected,
  137. T desired,
  138. memory_order success_order,
  139. memory_order failure_order) volatile
  140. {
  141. return compare_exchange_strong(expected, desired, success_order, failure_order);
  142. }
  143. T exchange(T r, memory_order order=memory_order_seq_cst) volatile
  144. {
  145. T expected=(T)i;
  146. do { } while(!compare_exchange_weak(expected, r, order, memory_order_relaxed));
  147. return expected;
  148. }
  149. bool is_lock_free(void) const volatile {return true;}
  150. typedef T integral_type;
  151. private:
  152. mutable int32_t i;
  153. };
  154. template<typename T>
  155. class platform_atomic_integral<T, 4> :
  156. public build_atomic_from_exchange<atomic_generic_cas32<T> >
  157. {
  158. public:
  159. typedef build_atomic_from_exchange<atomic_generic_cas32<T> > super;
  160. explicit platform_atomic_integral(T v) : super(v) {}
  161. platform_atomic_integral(void) {}
  162. };
  163. template<typename T>
  164. class platform_atomic_integral<T, 1> :
  165. public build_atomic_from_larger_type<atomic_generic_cas32<int32_t>, T>
  166. {
  167. public:
  168. typedef build_atomic_from_larger_type<atomic_generic_cas32<int32_t>, T> super;
  169. explicit platform_atomic_integral(T v) : super(v) {}
  170. platform_atomic_integral(void) {}
  171. };
  172. template<typename T>
  173. class platform_atomic_integral<T, 2> :
  174. public build_atomic_from_larger_type<atomic_generic_cas32<int32_t>, T>
  175. {
  176. public:
  177. typedef build_atomic_from_larger_type<atomic_generic_cas32<int32_t>, T> super;
  178. explicit platform_atomic_integral(T v) : super(v) {}
  179. platform_atomic_integral(void) {}
  180. };
  181. #endif
  182. } } }
  183. #endif