9#include <QtCore/qgenericatomic.h>
10#include <QtCore/qyieldcpu.h>
18#pragma qt_sync_skip_header_check
19#pragma qt_sync_stop_processing
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39template <
int N>
struct QAtomicTraits
40{
static inline bool isLockFree(); };
42#define Q_ATOMIC_INT32_IS_SUPPORTED
43#if ATOMIC_INT_LOCK_FREE
== 2
44# define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
45# define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
46# define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
47# define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
48# define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
49# define Q_ATOMIC_INT32_TEST_AND_SET_IS_ALWAYS_NATIVE
50# define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_ALWAYS_NATIVE
51# define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_ALWAYS_NATIVE
53template <>
inline bool QAtomicTraits<4>::isLockFree()
55#elif ATOMIC_INT_LOCK_FREE == 1
56# define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
57# define Q_ATOMIC_INT_TEST_AND_SET_IS_SOMETIMES_NATIVE
58# define Q_ATOMIC_INT_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
59# define Q_ATOMIC_INT_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
60# define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
61# define Q_ATOMIC_INT32_TEST_AND_SET_IS_SOMETIMES_NATIVE
62# define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
63# define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
65template <>
inline bool QAtomicTraits<4>::isLockFree()
68# define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NEVER_NATIVE
69# define Q_ATOMIC_INT_TEST_AND_SET_IS_NEVER_NATIVE
70# define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NEVER_NATIVE
71# define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NEVER_NATIVE
72# define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_NEVER_NATIVE
73# define Q_ATOMIC_INT32_TEST_AND_SET_IS_NEVER_NATIVE
74# define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_NEVER_NATIVE
75# define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_NEVER_NATIVE
77template <>
inline bool QAtomicTraits<4>::isLockFree()
81#if ATOMIC_POINTER_LOCK_FREE
== 2
82# define Q_ATOMIC_POINTER_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
83# define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
84# define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
85# define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
86#elif ATOMIC_POINTER_LOCK_FREE == 1
87# define Q_ATOMIC_POINTER_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
88# define Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE
89# define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
90# define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
92# define Q_ATOMIC_POINTER_REFERENCE_COUNTING_IS_NEVER_NATIVE
93# define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NEVER_NATIVE
94# define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NEVER_NATIVE
95# define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NEVER_NATIVE
99#define Q_ATOMIC_INT8_IS_SUPPORTED
100#if ATOMIC_CHAR_LOCK_FREE
== 2
101# define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
102# define Q_ATOMIC_INT8_TEST_AND_SET_IS_ALWAYS_NATIVE
103# define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_ALWAYS_NATIVE
104# define Q_ATOMIC_INT8_FETCH_AND_ADD_IS_ALWAYS_NATIVE
106template <>
inline bool QAtomicTraits<1>::isLockFree()
108#elif ATOMIC_CHAR_LOCK_FREE == 1
109# define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
110# define Q_ATOMIC_INT8_TEST_AND_SET_IS_SOMETIMES_NATIVE
111# define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
112# define Q_ATOMIC_INT8_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
114template <>
inline bool QAtomicTraits<1>::isLockFree()
117# define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_NEVER_NATIVE
118# define Q_ATOMIC_INT8_TEST_AND_SET_IS_NEVER_NATIVE
119# define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_NEVER_NATIVE
120# define Q_ATOMIC_INT8_FETCH_AND_ADD_IS_NEVER_NATIVE
122template <>
bool QAtomicTraits<1>::isLockFree()
126template<>
struct QAtomicOpsSupport<2> {
enum { IsSupported = 1 }; };
127#define Q_ATOMIC_INT16_IS_SUPPORTED
128#if ATOMIC_SHORT_LOCK_FREE
== 2
129# define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
130# define Q_ATOMIC_INT16_TEST_AND_SET_IS_ALWAYS_NATIVE
131# define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_ALWAYS_NATIVE
132# define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_ALWAYS_NATIVE
134template <>
inline bool QAtomicTraits<2>::isLockFree()
136#elif ATOMIC_SHORT_LOCK_FREE == 1
137# define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
138# define Q_ATOMIC_INT16_TEST_AND_SET_IS_SOMETIMES_NATIVE
139# define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
140# define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
142template <>
inline bool QAtomicTraits<2>::isLockFree()
145# define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_NEVER_NATIVE
146# define Q_ATOMIC_INT16_TEST_AND_SET_IS_NEVER_NATIVE
147# define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_NEVER_NATIVE
148# define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_NEVER_NATIVE
150template <>
inline bool QAtomicTraits<2>::isLockFree()
154#if !defined(QT_BOOTSTRAPPED) && QT_CONFIG(std_atomic64)
155template<>
struct QAtomicOpsSupport<8> {
enum { IsSupported = 1 }; };
156# define Q_ATOMIC_INT64_IS_SUPPORTED
157# if ATOMIC_LLONG_LOCK_FREE == 2
158# define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
159# define Q_ATOMIC_INT64_TEST_AND_SET_IS_ALWAYS_NATIVE
160# define Q_ATOMIC_INT64_FETCH_AND_STORE_IS_ALWAYS_NATIVE
161# define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_ALWAYS_NATIVE
163template <>
inline bool QAtomicTraits<8>::isLockFree()
165# elif ATOMIC_LLONG_LOCK_FREE == 1
166# define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
167# define Q_ATOMIC_INT64_TEST_AND_SET_IS_SOMETIMES_NATIVE
168# define Q_ATOMIC_INT64_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
169# define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
171template <>
inline bool QAtomicTraits<8>::isLockFree()
174# define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_NEVER_NATIVE
175# define Q_ATOMIC_INT64_TEST_AND_SET_IS_NEVER_NATIVE
176# define Q_ATOMIC_INT64_FETCH_AND_STORE_IS_NEVER_NATIVE
177# define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_NEVER_NATIVE
179template <>
inline bool QAtomicTraits<8>::isLockFree()
188 template <
typename T>
static inline
189 T
load(
const std::atomic<T> &_q_value)
noexcept
191 return _q_value.load(
std::memory_order_relaxed);
194 template <
typename T>
static inline
195 T
load(
const volatile std::atomic<T> &_q_value)
noexcept
197 return _q_value.load(
std::memory_order_relaxed);
200 template <
typename T>
static inline
203 return _q_value.load(
std::memory_order_relaxed);
206 template <
typename T>
static inline
209 return _q_value.load(
std::memory_order_relaxed);
212 template <
typename T>
static inline
215 return _q_value.load(
std::memory_order_acquire);
218 template <
typename T>
static inline
221 return _q_value.load(
std::memory_order_acquire);
224 template <
typename T>
static inline
225 void store(
std::atomic<T> &_q_value, T newValue)
noexcept
227 _q_value.store(newValue,
std::memory_order_relaxed);
230 template <
typename T>
static inline
233 _q_value.store(newValue,
std::memory_order_relaxed);
236 template <
typename T>
static inline
239 _q_value.store(newValue,
std::memory_order_release);
244 template <
typename T>
245 static inline bool ref(
std::atomic<T> &_q_value)
248
249
250
251
252
253
254
255
256
257
258
259
260 return _q_value.fetch_add(1,
std::memory_order_acq_rel) != T(-1);
263 template <
typename T>
264 static inline bool deref(
std::atomic<T> &_q_value)
noexcept
267 return _q_value.fetch_sub(1,
std::memory_order_acq_rel) != T(1);
271 {
return QAtomicTraits<
sizeof(X)>::isLockFree(); }
274 template <
typename T>
275 static bool testAndSetRelaxed(
std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue =
nullptr)
noexcept
277 bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue,
std::memory_order_relaxed,
std::memory_order_relaxed);
279 *currentValue = expectedValue;
283 template <
typename T>
284 static bool testAndSetAcquire(
std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue =
nullptr)
noexcept
286 bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue,
std::memory_order_acquire,
std::memory_order_acquire);
288 *currentValue = expectedValue;
292 template <
typename T>
293 static bool testAndSetRelease(
std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue =
nullptr)
noexcept
295 bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue,
std::memory_order_release,
std::memory_order_relaxed);
297 *currentValue = expectedValue;
301 template <
typename T>
302 static bool testAndSetOrdered(
std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue =
nullptr)
noexcept
304 bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue,
std::memory_order_acq_rel,
std::memory_order_acquire);
306 *currentValue = expectedValue;
313 template <
typename T>
316 return _q_value.exchange(newValue,
std::memory_order_relaxed);
319 template <
typename T>
322 return _q_value.exchange(newValue,
std::memory_order_acquire);
325 template <
typename T>
328 return _q_value.exchange(newValue,
std::memory_order_release);
331 template <
typename T>
334 return _q_value.exchange(newValue,
std::memory_order_acq_rel);
340 template <
typename T>
static inline
343 return _q_value.fetch_add(valueToAdd,
std::memory_order_relaxed);
346 template <
typename T>
static inline
349 return _q_value.fetch_add(valueToAdd,
std::memory_order_acquire);
352 template <
typename T>
static inline
355 return _q_value.fetch_add(valueToAdd,
std::memory_order_release);
358 template <
typename T>
static inline
361 return _q_value.fetch_add(valueToAdd,
std::memory_order_acq_rel);
364 template <
typename T>
static inline
367 return _q_value.fetch_sub(valueToAdd,
std::memory_order_relaxed);
370 template <
typename T>
static inline
373 return _q_value.fetch_sub(valueToAdd,
std::memory_order_acquire);
376 template <
typename T>
static inline
379 return _q_value.fetch_sub(valueToAdd,
std::memory_order_release);
382 template <
typename T>
static inline
385 return _q_value.fetch_sub(valueToAdd,
std::memory_order_acq_rel);
388 template <
typename T>
static inline
391 return _q_value.fetch_and(valueToAdd,
std::memory_order_relaxed);
394 template <
typename T>
static inline
397 return _q_value.fetch_and(valueToAdd,
std::memory_order_acquire);
400 template <
typename T>
static inline
403 return _q_value.fetch_and(valueToAdd,
std::memory_order_release);
406 template <
typename T>
static inline
409 return _q_value.fetch_and(valueToAdd,
std::memory_order_acq_rel);
412 template <
typename T>
static inline
415 return _q_value.fetch_or(valueToAdd,
std::memory_order_relaxed);
418 template <
typename T>
static inline
421 return _q_value.fetch_or(valueToAdd,
std::memory_order_acquire);
424 template <
typename T>
static inline
427 return _q_value.fetch_or(valueToAdd,
std::memory_order_release);
430 template <
typename T>
static inline
433 return _q_value.fetch_or(valueToAdd,
std::memory_order_acq_rel);
436 template <
typename T>
static inline
439 return _q_value.fetch_xor(valueToAdd,
std::memory_order_relaxed);
442 template <
typename T>
static inline
445 return _q_value.fetch_xor(valueToAdd,
std::memory_order_acquire);
448 template <
typename T>
static inline
451 return _q_value.fetch_xor(valueToAdd,
std::memory_order_release);
454 template <
typename T>
static inline
457 return _q_value.fetch_xor(valueToAdd,
std::memory_order_acq_rel);
461# define Q_BASIC_ATOMIC_INITIALIZER(a) { a }
static void storeRelease(std::atomic< T > &_q_value, T newValue) noexcept
static bool isFetchAndAddNative() noexcept
static constexpr bool isFetchAndStoreWaitFree() noexcept
static T fetchAndOrOrdered(std::atomic< T > &_q_value, typename QAtomicAdditiveType< T >::AdditiveT valueToAdd) noexcept
static T fetchAndOrAcquire(std::atomic< T > &_q_value, typename QAtomicAdditiveType< T >::AdditiveT valueToAdd) noexcept
static T fetchAndSubOrdered(std::atomic< T > &_q_value, typename QAtomicAdditiveType< T >::AdditiveT valueToAdd) noexcept
static T fetchAndStoreRelaxed(std::atomic< T > &_q_value, T newValue) noexcept
static T fetchAndAddAcquire(std::atomic< T > &_q_value, typename QAtomicAdditiveType< T >::AdditiveT valueToAdd) noexcept
static T fetchAndSubRelaxed(std::atomic< T > &_q_value, typename QAtomicAdditiveType< T >::AdditiveT valueToAdd) noexcept
static T fetchAndAndRelaxed(std::atomic< T > &_q_value, typename QAtomicAdditiveType< T >::AdditiveT valueToAdd) noexcept
static bool isReferenceCountingNative() noexcept
static bool testAndSetOrdered(std::atomic< T > &_q_value, T expectedValue, T newValue, T *currentValue=nullptr) noexcept
static T fetchAndAddOrdered(std::atomic< T > &_q_value, typename QAtomicAdditiveType< T >::AdditiveT valueToAdd) noexcept
static T fetchAndStoreOrdered(std::atomic< T > &_q_value, T newValue) noexcept
static bool ref(std::atomic< T > &_q_value)
static T fetchAndXorOrdered(std::atomic< T > &_q_value, typename QAtomicAdditiveType< T >::AdditiveT valueToAdd) noexcept
static constexpr bool isFetchAndAddWaitFree() noexcept
static T fetchAndAddRelease(std::atomic< T > &_q_value, typename QAtomicAdditiveType< T >::AdditiveT valueToAdd) noexcept
static T loadRelaxed(const volatile std::atomic< T > &_q_value) noexcept
static T fetchAndAndRelease(std::atomic< T > &_q_value, typename QAtomicAdditiveType< T >::AdditiveT valueToAdd) noexcept
static bool testAndSetRelease(std::atomic< T > &_q_value, T expectedValue, T newValue, T *currentValue=nullptr) noexcept
static T fetchAndStoreAcquire(std::atomic< T > &_q_value, T newValue) noexcept
static T fetchAndXorRelaxed(std::atomic< T > &_q_value, typename QAtomicAdditiveType< T >::AdditiveT valueToAdd) noexcept
static T fetchAndOrRelaxed(std::atomic< T > &_q_value, typename QAtomicAdditiveType< T >::AdditiveT valueToAdd) noexcept
static T fetchAndAndAcquire(std::atomic< T > &_q_value, typename QAtomicAdditiveType< T >::AdditiveT valueToAdd) noexcept
static bool isFetchAndStoreNative() noexcept
static bool deref(std::atomic< T > &_q_value) noexcept
static T loadRelaxed(const std::atomic< T > &_q_value) noexcept
static bool testAndSetRelaxed(std::atomic< T > &_q_value, T expectedValue, T newValue, T *currentValue=nullptr) noexcept
static bool isTestAndSetNative() noexcept
static T fetchAndXorRelease(std::atomic< T > &_q_value, typename QAtomicAdditiveType< T >::AdditiveT valueToAdd) noexcept
static void storeRelaxed(std::atomic< T > &_q_value, T newValue) noexcept
static T loadAcquire(const volatile std::atomic< T > &_q_value) noexcept
static T loadAcquire(const std::atomic< T > &_q_value) noexcept
static T load(const std::atomic< T > &_q_value) noexcept
static T fetchAndSubRelease(std::atomic< T > &_q_value, typename QAtomicAdditiveType< T >::AdditiveT valueToAdd) noexcept
static constexpr bool isTestAndSetWaitFree() noexcept
static T fetchAndAddRelaxed(std::atomic< T > &_q_value, typename QAtomicAdditiveType< T >::AdditiveT valueToAdd) noexcept
static T load(const volatile std::atomic< T > &_q_value) noexcept
static T fetchAndSubAcquire(std::atomic< T > &_q_value, typename QAtomicAdditiveType< T >::AdditiveT valueToAdd) noexcept
static void store(std::atomic< T > &_q_value, T newValue) noexcept
static T fetchAndStoreRelease(std::atomic< T > &_q_value, T newValue) noexcept
static T fetchAndAndOrdered(std::atomic< T > &_q_value, typename QAtomicAdditiveType< T >::AdditiveT valueToAdd) noexcept
static bool testAndSetAcquire(std::atomic< T > &_q_value, T expectedValue, T newValue, T *currentValue=nullptr) noexcept
static T fetchAndXorAcquire(std::atomic< T > &_q_value, typename QAtomicAdditiveType< T >::AdditiveT valueToAdd) noexcept
static T fetchAndOrRelease(std::atomic< T > &_q_value, typename QAtomicAdditiveType< T >::AdditiveT valueToAdd) noexcept
static constexpr bool isReferenceCountingWaitFree() noexcept