atomicops_internals_mac.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. // This file is an internal atomic implementation, use base/atomicops.h instead.
  5. #ifndef BASE_ATOMICOPS_INTERNALS_MAC_H_
  6. #define BASE_ATOMICOPS_INTERNALS_MAC_H_
  7. #include <libkern/OSAtomic.h>
  8. namespace base {
  9. namespace subtle {
  10. inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
  11. Atomic32 old_value,
  12. Atomic32 new_value) {
  13. Atomic32 prev_value;
  14. do {
  15. if (OSAtomicCompareAndSwap32(old_value, new_value,
  16. const_cast<Atomic32*>(ptr))) {
  17. return old_value;
  18. }
  19. prev_value = *ptr;
  20. } while (prev_value == old_value);
  21. return prev_value;
  22. }
  23. inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
  24. Atomic32 new_value) {
  25. Atomic32 old_value;
  26. do {
  27. old_value = *ptr;
  28. } while (!OSAtomicCompareAndSwap32(old_value, new_value,
  29. const_cast<Atomic32*>(ptr)));
  30. return old_value;
  31. }
  32. inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
  33. Atomic32 increment) {
  34. return OSAtomicAdd32(increment, const_cast<Atomic32*>(ptr));
  35. }
  36. inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
  37. Atomic32 increment) {
  38. return OSAtomicAdd32Barrier(increment, const_cast<Atomic32*>(ptr));
  39. }
  40. inline void MemoryBarrier() {
  41. OSMemoryBarrier();
  42. }
  43. inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
  44. Atomic32 old_value,
  45. Atomic32 new_value) {
  46. Atomic32 prev_value;
  47. do {
  48. if (OSAtomicCompareAndSwap32Barrier(old_value, new_value,
  49. const_cast<Atomic32*>(ptr))) {
  50. return old_value;
  51. }
  52. prev_value = *ptr;
  53. } while (prev_value == old_value);
  54. return prev_value;
  55. }
  56. inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
  57. Atomic32 old_value,
  58. Atomic32 new_value) {
  59. return Acquire_CompareAndSwap(ptr, old_value, new_value);
  60. }
  61. inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
  62. *ptr = value;
  63. }
  64. inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
  65. *ptr = value;
  66. MemoryBarrier();
  67. }
  68. inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
  69. MemoryBarrier();
  70. *ptr = value;
  71. }
  72. inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
  73. return *ptr;
  74. }
  75. inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
  76. Atomic32 value = *ptr;
  77. MemoryBarrier();
  78. return value;
  79. }
  80. inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
  81. MemoryBarrier();
  82. return *ptr;
  83. }
  84. #ifdef __LP64__
  85. // 64-bit implementation on 64-bit platform
  86. inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
  87. Atomic64 old_value,
  88. Atomic64 new_value) {
  89. Atomic64 prev_value;
  90. do {
  91. if (OSAtomicCompareAndSwap64(old_value, new_value,
  92. reinterpret_cast<volatile int64_t*>(ptr))) {
  93. return old_value;
  94. }
  95. prev_value = *ptr;
  96. } while (prev_value == old_value);
  97. return prev_value;
  98. }
  99. inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
  100. Atomic64 new_value) {
  101. Atomic64 old_value;
  102. do {
  103. old_value = *ptr;
  104. } while (!OSAtomicCompareAndSwap64(old_value, new_value,
  105. reinterpret_cast<volatile int64_t*>(ptr)));
  106. return old_value;
  107. }
  108. inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
  109. Atomic64 increment) {
  110. return OSAtomicAdd64(increment, reinterpret_cast<volatile int64_t*>(ptr));
  111. }
  112. inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
  113. Atomic64 increment) {
  114. return OSAtomicAdd64Barrier(increment,
  115. reinterpret_cast<volatile int64_t*>(ptr));
  116. }
  117. inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
  118. Atomic64 old_value,
  119. Atomic64 new_value) {
  120. Atomic64 prev_value;
  121. do {
  122. if (OSAtomicCompareAndSwap64Barrier(
  123. old_value, new_value, reinterpret_cast<volatile int64_t*>(ptr))) {
  124. return old_value;
  125. }
  126. prev_value = *ptr;
  127. } while (prev_value == old_value);
  128. return prev_value;
  129. }
  130. inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
  131. Atomic64 old_value,
  132. Atomic64 new_value) {
  133. // The lib kern interface does not distinguish between
  134. // Acquire and Release memory barriers; they are equivalent.
  135. return Acquire_CompareAndSwap(ptr, old_value, new_value);
  136. }
  137. inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
  138. *ptr = value;
  139. }
  140. inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
  141. *ptr = value;
  142. MemoryBarrier();
  143. }
  144. inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
  145. MemoryBarrier();
  146. *ptr = value;
  147. }
  148. inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
  149. return *ptr;
  150. }
  151. inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
  152. Atomic64 value = *ptr;
  153. MemoryBarrier();
  154. return value;
  155. }
  156. inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
  157. MemoryBarrier();
  158. return *ptr;
  159. }
  160. #endif // defined(__LP64__)
  161. } // namespace base::subtle
  162. } // namespace base
  163. #endif // BASE_ATOMICOPS_INTERNALS_MAC_H_