5 #ifndef V8_BASE_ATOMIC_UTILS_H_ 6 #define V8_BASE_ATOMIC_UTILS_H_ 11 #include "src/base/atomicops.h" 12 #include "src/base/macros.h" 25 : value_(cast_helper<T>::to_storage_type(initial)) {}
27 V8_INLINE
T Value()
const {
28 return cast_helper<T>::to_return_type(base::Acquire_Load(&value_));
31 V8_INLINE
void SetValue(
T new_value) {
32 base::Release_Store(&value_, cast_helper<T>::to_storage_type(new_value));
36 STATIC_ASSERT(
sizeof(
T) <=
sizeof(base::AtomicWord));
40 static base::AtomicWord to_storage_type(S value) {
41 return static_cast<base::AtomicWord
>(value);
43 static S to_return_type(base::AtomicWord value) {
44 return static_cast<S
>(value);
49 struct cast_helper<S*> {
50 static base::AtomicWord to_storage_type(S* value) {
51 return reinterpret_cast<base::AtomicWord
>(value);
53 static S* to_return_type(base::AtomicWord value) {
54 return reinterpret_cast<S*
>(value);
58 base::AtomicWord value_;
62 template <
typename TAtomicStorageType>
65 using AtomicStorageType = TAtomicStorageType;
68 static T Acquire_Load(
T* addr) {
69 STATIC_ASSERT(
sizeof(
T) <=
sizeof(AtomicStorageType));
70 return cast_helper<T>::to_return_type(
71 base::Acquire_Load(to_storage_addr(addr)));
75 static T Relaxed_Load(
T* addr) {
76 STATIC_ASSERT(
sizeof(
T) <=
sizeof(AtomicStorageType));
77 return cast_helper<T>::to_return_type(
78 base::Relaxed_Load(to_storage_addr(addr)));
82 static void Release_Store(
T* addr,
83 typename std::remove_reference<T>::type new_value) {
84 STATIC_ASSERT(
sizeof(
T) <=
sizeof(AtomicStorageType));
85 base::Release_Store(to_storage_addr(addr),
86 cast_helper<T>::to_storage_type(new_value));
90 static void Relaxed_Store(
T* addr,
91 typename std::remove_reference<T>::type new_value) {
92 STATIC_ASSERT(
sizeof(
T) <=
sizeof(AtomicStorageType));
93 base::Relaxed_Store(to_storage_addr(addr),
94 cast_helper<T>::to_storage_type(new_value));
98 static T Release_CompareAndSwap(
99 T* addr,
typename std::remove_reference<T>::type old_value,
100 typename std::remove_reference<T>::type new_value) {
101 STATIC_ASSERT(
sizeof(
T) <=
sizeof(AtomicStorageType));
102 return cast_helper<T>::to_return_type(base::Release_CompareAndSwap(
103 to_storage_addr(addr), cast_helper<T>::to_storage_type(old_value),
104 cast_helper<T>::to_storage_type(new_value)));
109 template <
typename T>
110 static bool SetBits(
T* addr,
T bits,
T mask) {
111 STATIC_ASSERT(
sizeof(
T) <=
sizeof(AtomicStorageType));
112 DCHECK_EQ(bits & ~mask, static_cast<T>(0));
116 old_value = Relaxed_Load(addr);
117 if ((old_value & mask) == bits)
return false;
118 new_value = (old_value & ~mask) | bits;
119 }
while (Release_CompareAndSwap(addr, old_value, new_value) != old_value);
124 template <
typename U>
126 static AtomicStorageType to_storage_type(U value) {
127 return static_cast<AtomicStorageType
>(value);
129 static U to_return_type(AtomicStorageType value) {
130 return static_cast<U
>(value);
134 template <
typename U>
135 struct cast_helper<U*> {
136 static AtomicStorageType to_storage_type(U* value) {
137 return reinterpret_cast<AtomicStorageType
>(value);
139 static U* to_return_type(AtomicStorageType value) {
140 return reinterpret_cast<U*
>(value);
144 template <
typename T>
145 static AtomicStorageType* to_storage_addr(
T* value) {
146 return reinterpret_cast<AtomicStorageType*
>(value);
148 template <
typename T>
149 static const AtomicStorageType* to_storage_addr(
const T* value) {
150 return reinterpret_cast<const AtomicStorageType*
>(value);
160 template <
typename TAtomicStorageType>
163 template <
typename T>
164 static bool SetBits(
T* addr,
T bits,
T mask) =
delete;
169 template <
typename T,
170 typename =
typename std::enable_if<std::is_unsigned<T>::value>
::type>
171 inline void CheckedIncrement(std::atomic<T>* number, T amount) {
172 const T old = number->fetch_add(amount);
173 DCHECK_GE(old + amount, old);
177 template <
typename T,
178 typename =
typename std::enable_if<std::is_unsigned<T>::value>
::type>
179 inline void CheckedDecrement(std::atomic<T>* number,
T amount) {
180 const T old = number->fetch_sub(amount);
181 DCHECK_GE(old, amount);
188 #endif // V8_BASE_ATOMIC_UTILS_H_