5#ifndef V8_BASE_ATOMIC_UTILS_H_
6#define V8_BASE_ATOMIC_UTILS_H_
47 return static_cast<S
>(
value);
57 return reinterpret_cast<S*
>(
value);
65template <
typename TAtomicStorageType>
93 typename std::remove_reference<T>::type new_value) {
101 typename std::remove_reference<T>::type new_value) {
107 template <
typename T>
109 typename std::remove_reference<T>::type new_value) {
115 template <
typename T>
117 typename std::remove_reference<T>::type new_value) {
123 template <
typename T>
125 T* addr,
typename std::remove_reference<T>::type old_value,
126 typename std::remove_reference<T>::type new_value) {
133 template <
typename T>
135 T* addr,
typename std::remove_reference<T>::type old_value,
136 typename std::remove_reference<T>::type new_value) {
143 template <
typename T>
145 T* addr,
typename std::remove_reference<T>::type old_value,
146 typename std::remove_reference<T>::type new_value) {
153 template <
typename T>
155 T* addr,
typename std::remove_reference<T>::type old_value,
156 typename std::remove_reference<T>::type new_value) {
165 template <
typename T>
170 T new_value, old_value_before_cas;
172 if ((old_value &
mask) == bits)
return false;
173 new_value = (old_value & ~mask) | bits;
174 old_value_before_cas = old_value;
176 }
while (old_value != old_value_before_cas);
182 template <
typename T>
187 T new_value, old_value_before_cas;
189 if ((old_value &
mask) == bits)
return false;
190 new_value = (old_value & ~mask) | bits;
191 old_value_before_cas = old_value;
193 }
while (old_value != old_value_before_cas);
198 template <
typename U>
204 return static_cast<U
>(
value);
208 template <
typename U>
214 return reinterpret_cast<U*
>(
value);
217 template <
typename T,
typename U>
227 template <
typename T>
231 template <
typename T>
256#if V8_HOST_ARCH_64_BIT
259 using type = base::Atomic64;
265template <
typename TAtomicStorageType>
268 template <
typename T>
276 std::atomic<T>* number, T amount,
277 std::memory_order order = std::memory_order_seq_cst)
278 requires std::is_unsigned<T>::value
280 const T old = number->fetch_add(amount, order);
287 std::atomic<T>* number, T amount,
288 std::memory_order order = std::memory_order_seq_cst)
289 requires std::is_unsigned<T>::value
291 const T old = number->fetch_sub(amount, order);
298 static_assert(
sizeof(
T) ==
sizeof(std::atomic<T>));
299 static_assert(
alignof(
T) >=
alignof(std::atomic<T>));
300 return reinterpret_cast<std::atomic<T>*
>(t);
305 static_assert(
sizeof(
T) ==
sizeof(std::atomic<T>));
306 static_assert(
alignof(
T) >=
alignof(std::atomic<T>));
307 return reinterpret_cast<const std::atomic<T>*
>(t);
static T Relaxed_CompareAndSwap(T *addr, typename std::remove_reference< T >::type old_value, typename std::remove_reference< T >::type new_value)
static void Release_Store(T *addr, typename std::remove_reference< T >::type new_value)
static T AcquireRelease_CompareAndSwap(T *addr, typename std::remove_reference< T >::type old_value, typename std::remove_reference< T >::type new_value)
static void SeqCst_Store(T *addr, typename std::remove_reference< T >::type new_value)
static T Acquire_Load(T *addr)
static void Relaxed_Store(T *addr, typename std::remove_reference< T >::type new_value)
static T Release_CompareAndSwap(T *addr, typename std::remove_reference< T >::type old_value, typename std::remove_reference< T >::type new_value)
static bool Release_SetBits(T *addr, T bits, T mask)
static const AtomicStorageType * to_storage_addr(const T *value)
static T SeqCst_Swap(T *addr, typename std::remove_reference< T >::type new_value)
static T SeqCst_Load(T *addr)
static T SeqCst_CompareAndSwap(T *addr, typename std::remove_reference< T >::type old_value, typename std::remove_reference< T >::type new_value)
static T Relaxed_Load(T *addr)
static AtomicStorageType * to_storage_addr(T *value)
static bool Relaxed_SetBits(T *addr, T bits, T mask)
TAtomicStorageType AtomicStorageType
static bool SetBits(T *addr, T bits, T mask)=delete
V8_INLINE void SetValue(T new_value)
V8_INLINE T Value() const
void Relaxed_Store(volatile Atomic8 *ptr, Atomic8 value)
Atomic8 Release_CompareAndSwap(volatile Atomic8 *ptr, Atomic8 old_value, Atomic8 new_value)
Atomic8 Relaxed_CompareAndSwap(volatile Atomic8 *ptr, Atomic8 old_value, Atomic8 new_value)
Atomic8 Relaxed_Load(volatile const Atomic8 *ptr)
Atomic32 SeqCst_CompareAndSwap(volatile Atomic32 *ptr, Atomic32 old_value, Atomic32 new_value)
Atomic8 SeqCst_Load(volatile const Atomic8 *ptr)
Atomic8 Acquire_Load(volatile const Atomic8 *ptr)
Atomic32 SeqCst_AtomicExchange(volatile Atomic32 *ptr, Atomic32 new_value)
void CheckedDecrement(std::atomic< T > *number, T amount, std::memory_order order=std::memory_order_seq_cst)
void Release_Store(volatile Atomic8 *ptr, Atomic8 value)
V8_INLINE std::atomic< T > * AsAtomicPtr(T *t)
void SeqCst_Store(volatile Atomic8 *ptr, Atomic8 value)
void CheckedIncrement(std::atomic< T > *number, T amount, std::memory_order order=std::memory_order_seq_cst)
Atomic32 AcquireRelease_CompareAndSwap(volatile Atomic32 *ptr, Atomic32 old_value, Atomic32 new_value)
#define DCHECK_GE(v1, v2)
#define DCHECK_EQ(v1, v2)
static AtomicStorageType to_storage_type(U *value)
static U * to_return_type(AtomicStorageType value)
static base::StrongAlias< T, U > to_return_type(AtomicStorageType value)
static AtomicStorageType to_storage_type(base::StrongAlias< T, U > value)
static U to_return_type(AtomicStorageType value)
static AtomicStorageType to_storage_type(U value)
static base::AtomicWord to_storage_type(S *value)
static S * to_return_type(base::AtomicWord value)
static S to_return_type(base::AtomicWord value)
static base::AtomicWord to_storage_type(S value)
std::unique_ptr< ValueMirror > value