gcc-cas.hpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. // Copyright (c) 2011 Helge Bahmann
  2. // Copyright (c) 2013 Tim Blechmann
  3. //
  4. // Distributed under the Boost Software License, Version 1.0.
  5. // See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. // Use the gnu builtin __sync_val_compare_and_swap to build
  8. // atomic operations for 32 bit and smaller.
  9. #ifndef BOOST_ATOMIC_DETAIL_GENERIC_CAS_HPP
  10. #define BOOST_ATOMIC_DETAIL_GENERIC_CAS_HPP
  11. #include <boost/cstdint.hpp>
  12. #include <boost/atomic/detail/config.hpp>
  13. #ifdef BOOST_HAS_PRAGMA_ONCE
  14. #pragma once
  15. #endif
  16. namespace boost {
  17. #define BOOST_ATOMIC_THREAD_FENCE 2
  18. inline void
  19. atomic_thread_fence(memory_order order)
  20. {
  21. switch(order)
  22. {
  23. case memory_order_relaxed:
  24. break;
  25. case memory_order_release:
  26. case memory_order_consume:
  27. case memory_order_acquire:
  28. case memory_order_acq_rel:
  29. case memory_order_seq_cst:
  30. __sync_synchronize();
  31. break;
  32. }
  33. }
  34. namespace atomics {
  35. namespace detail {
  36. inline void
  37. platform_fence_before(memory_order)
  38. {
  39. /* empty, as compare_and_swap is synchronizing already */
  40. }
  41. inline void
  42. platform_fence_after(memory_order)
  43. {
  44. /* empty, as compare_and_swap is synchronizing already */
  45. }
  46. inline void
  47. platform_fence_before_store(memory_order order)
  48. {
  49. switch(order)
  50. {
  51. case memory_order_relaxed:
  52. case memory_order_acquire:
  53. case memory_order_consume:
  54. break;
  55. case memory_order_release:
  56. case memory_order_acq_rel:
  57. case memory_order_seq_cst:
  58. __sync_synchronize();
  59. break;
  60. }
  61. }
  62. inline void
  63. platform_fence_after_store(memory_order order)
  64. {
  65. if (order == memory_order_seq_cst)
  66. __sync_synchronize();
  67. }
  68. inline void
  69. platform_fence_after_load(memory_order order)
  70. {
  71. switch(order)
  72. {
  73. case memory_order_relaxed:
  74. case memory_order_release:
  75. break;
  76. case memory_order_consume:
  77. case memory_order_acquire:
  78. case memory_order_acq_rel:
  79. case memory_order_seq_cst:
  80. __sync_synchronize();
  81. break;
  82. }
  83. }
  84. template<typename T>
  85. inline bool
  86. platform_cmpxchg32_strong(T & expected, T desired, volatile T * ptr)
  87. {
  88. T found = __sync_val_compare_and_swap(ptr, expected, desired);
  89. bool success = (found == expected);
  90. expected = found;
  91. return success;
  92. }
  93. class atomic_flag
  94. {
  95. private:
  96. atomic_flag(const atomic_flag &) /* = delete */ ;
  97. atomic_flag & operator=(const atomic_flag &) /* = delete */ ;
  98. uint32_t v_;
  99. public:
  100. BOOST_CONSTEXPR atomic_flag(void) BOOST_NOEXCEPT : v_(0) {}
  101. void
  102. clear(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  103. {
  104. atomics::detail::platform_fence_before_store(order);
  105. const_cast<volatile uint32_t &>(v_) = 0;
  106. atomics::detail::platform_fence_after_store(order);
  107. }
  108. bool
  109. test_and_set(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  110. {
  111. atomics::detail::platform_fence_before(order);
  112. uint32_t expected = v_;
  113. do {
  114. if (expected == 1)
  115. break;
  116. } while (!atomics::detail::platform_cmpxchg32(expected, (uint32_t)1, &v_));
  117. atomics::detail::platform_fence_after(order);
  118. return expected;
  119. }
  120. };
  121. #define BOOST_ATOMIC_FLAG_LOCK_FREE 2
  122. }
  123. }
  124. }
  125. #include <boost/atomic/detail/base.hpp>
  126. #if !defined(BOOST_ATOMIC_FORCE_FALLBACK)
  127. #define BOOST_ATOMIC_CHAR_LOCK_FREE 2
  128. #define BOOST_ATOMIC_SHORT_LOCK_FREE 2
  129. #define BOOST_ATOMIC_INT_LOCK_FREE 2
  130. #define BOOST_ATOMIC_LONG_LOCK_FREE (sizeof(long) <= 4 ? 2 : 0)
  131. #define BOOST_ATOMIC_LLONG_LOCK_FREE (sizeof(long long) <= 4 ? 2 : 0)
  132. #define BOOST_ATOMIC_POINTER_LOCK_FREE (sizeof(void *) <= 4 ? 2 : 0)
  133. #define BOOST_ATOMIC_BOOL_LOCK_FREE 2
  134. #include <boost/atomic/detail/cas32strong.hpp>
  135. #endif /* !defined(BOOST_ATOMIC_FORCE_FALLBACK) */
  136. #endif