Revision control

++ // Copyright (C) 2016 The Qt Company Ltd.
++ // Copyright (C) 2016 Intel Corporation.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
++ // Qt-Security score:significant reason:default
++
++ #include "qatomic.h"
++
++ /*!
++ \class QAtomicInt
++ \inmodule QtCore
++ \brief The QAtomicInt class provides platform-independent atomic operations on int.
++ \since 4.4
++
++ This class is a equivalent to \c{QAtomicInteger<int>}. All other
++ functionality is equivalent. Please see that class for more information.
++
++ \sa QAtomicInteger, QAtomicPointer
++ */
++
++ /*!
++ \class QAtomicInteger
++ \inmodule QtCore
++ \brief The QAtomicInteger class provides platform-independent atomic operations on integers.
++ \ingroup thread
++ \since 5.3
++
++ For atomic operations on pointers, see the QAtomicPointer class.
++
++ An \e atomic operation is a complex operation that completes without interruption.
++ The QAtomicInteger class provides atomic reference counting, test-and-set, fetch-and-store,
++ and fetch-and-add for integers. The template parameter \a T specifies the integer type
++ being made atomic.
++
++ The template parameter \a T must be a C++ integer type:
++ \list
++ \li 8-bit: bool, char, signed char, unsigned char, qint8, quint8, char8_t (C++20)
++ \li 16-bit: short, unsigned short, qint16, quint16, char16_t
++ \li 32-bit: int, unsigned int, qint32, quint32, char32_t
++ \li 64-bit: long long, unsigned long long, qint64, quint64
++ \li platform-specific size: long, unsigned long
++ \li pointer size: qintptr, quintptr, qptrdiff
++ \endlist
++
++ Of the list above, only the 8-bit, 16-bit, 32-bit- and pointer-sized
++ instantiations are guaranteed to work on all platforms. Support for other
++ sizes depends on the compiler and processor architecture the code is being
++ compiled for. To test whether the 64-bit types are supported on 32-bit
++ platforms, check the macro \c Q_ATOMIC_INT64_IS_SUPPORTED.
++
++ \section1 The Atomic API
++
++ \section2 Reference counting
++
++ The ref() and deref() functions provide an efficient reference
++ counting API. The return value of these functions are used to
++ indicate when the last reference has been released. These
++ functions allow you to implement your own implicitly shared
++ classes.
++
++ \snippet code/src_corelib_thread_qatomic.cpp 0
++
++ \section2 Memory ordering
++
++ QAtomicInteger provides several implementations of the atomic
++ test-and-set, fetch-and-store, and fetch-and-add functions. Each
++ implementation defines a memory ordering semantic that describes
++ how memory accesses surrounding the atomic instruction are
++ executed by the processor. Since many modern architectures allow
++ out-of-order execution and memory ordering, using the correct
++ semantic is necessary to ensure that your application functions
++ properly on all processors.
++
++ \list
++
++ \li Relaxed - memory ordering is unspecified, leaving the compiler
++ and processor to freely reorder memory accesses.
++
++ \li Acquire - memory access following the atomic operation (in
++ program order) may not be re-ordered before the atomic operation.
++
++ \li Release - memory access before the atomic operation (in program
++ order) may not be re-ordered after the atomic operation.
++
++ \li Ordered - the same Acquire and Release semantics combined.
++
++ \endlist
++
++ \section2 Test-and-set
++
++ If the current value of the QAtomicInteger is an expected value, the
++ test-and-set functions assign a new value to the QAtomicInteger and
++ return true. If values are \e not the same, these functions do
++ nothing and return false. This operation equates to the following
++ code:
++
++ \snippet code/src_corelib_thread_qatomic.cpp 1
++
++ There are 4 test-and-set functions: testAndSetRelaxed(),
++ testAndSetAcquire(), testAndSetRelease(), and
++ testAndSetOrdered(). See above for an explanation of the different
++ memory ordering semantics.
++
++ \section2 Fetch-and-store
++
++ The atomic fetch-and-store functions read the current value of the
++ QAtomicInteger and then assign a new value, returning the original
++ value. This operation equates to the following code:
++
++ \snippet code/src_corelib_thread_qatomic.cpp 2
++
++ There are 4 fetch-and-store functions: fetchAndStoreRelaxed(),
++ fetchAndStoreAcquire(), fetchAndStoreRelease(), and
++ fetchAndStoreOrdered(). See above for an explanation of the
++ different memory ordering semantics.
++
++ \section2 Fetch-and-add
++
++ The atomic fetch-and-add functions read the current value of the
++ QAtomicInteger and then add the given value to the current value,
++ returning the original value. This operation equates to the
++ following code:
++
++ \snippet code/src_corelib_thread_qatomic.cpp 3
++
++ There are 4 fetch-and-add functions: fetchAndAddRelaxed(),
++ fetchAndAddAcquire(), fetchAndAddRelease(), and
++ fetchAndAddOrdered(). See above for an explanation of the
++ different memory ordering semantics.
++
++ \section1 Feature Tests for the Atomic API
++
++ Providing a platform-independent atomic API that works on all
++ processors is challenging. The API provided by QAtomicInteger is
++ guaranteed to work atomically on all processors. However, since
++ not all processors implement support for every operation provided
++ by QAtomicInteger, it is necessary to expose information about the
++ processor.
++
++ You can check at compile time which features are supported on your
++ hardware using various macros. These will tell you if your
++ hardware always, sometimes, or does not support a particular
++ operation. The macros have the form
++ Q_ATOMIC_INT\e{nn}_\e{OPERATION}_IS_\e{HOW}_NATIVE. \e{nn} is the
++ size of the integer (in bits), \e{OPERATION}
++ is one of REFERENCE_COUNTING, TEST_AND_SET,
++ FETCH_AND_STORE, or FETCH_AND_ADD, and \e{HOW} is one of
++ ALWAYS, SOMETIMES, or NOT. There will always be exactly one
++ defined macro per operation. For example, if
++ Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_ALWAYS_NATIVE is defined,
++ neither Q_ATOMIC_INT_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE nor
++ Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_NOT_NATIVE will be defined.
++
++ An operation that completes in constant time is said to be
++ wait-free. Such operations are not implemented using locks or
++ loops of any kind. For atomic operations that are always
++ supported, and that are wait-free, Qt defines the
++ Q_ATOMIC_INT\e{nn}_\e{OPERATION}_IS_WAIT_FREE in addition to the
++ Q_ATOMIC_INT\e{nn}_\e{OPERATION}_IS_ALWAYS_NATIVE.
++
++ In cases where an atomic operation is only supported in newer
++ generations of the processor, QAtomicInteger also provides a way to
++ check at runtime what your hardware supports with the
++ isReferenceCountingNative(), isTestAndSetNative(),
++ isFetchAndStoreNative(), and isFetchAndAddNative()
++ functions. Wait-free implementations can be detected using the
++ isReferenceCountingWaitFree(), isTestAndSetWaitFree(),
++ isFetchAndStoreWaitFree(), and isFetchAndAddWaitFree() functions.
++
++ Below is a complete list of all feature macros for QAtomicInteger:
++
++ \list
++
++ \li Q_ATOMIC_INT\e{nn}_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
++ \li Q_ATOMIC_INT\e{nn}_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
++ \li Q_ATOMIC_INT\e{nn}_REFERENCE_COUNTING_IS_NOT_NATIVE
++ \li Q_ATOMIC_INT\e{nn}_REFERENCE_COUNTING_IS_WAIT_FREE
++
++ \li Q_ATOMIC_INT\e{nn}_TEST_AND_SET_IS_ALWAYS_NATIVE
++ \li Q_ATOMIC_INT\e{nn}_TEST_AND_SET_IS_SOMETIMES_NATIVE
++ \li Q_ATOMIC_INT\e{nn}_TEST_AND_SET_IS_NOT_NATIVE
++ \li Q_ATOMIC_INT\e{nn}_TEST_AND_SET_IS_WAIT_FREE
++
++ \li Q_ATOMIC_INT\e{nn}_FETCH_AND_STORE_IS_ALWAYS_NATIVE
++ \li Q_ATOMIC_INT\e{nn}_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
++ \li Q_ATOMIC_INT\e{nn}_FETCH_AND_STORE_IS_NOT_NATIVE
++ \li Q_ATOMIC_INT\e{nn}_FETCH_AND_STORE_IS_WAIT_FREE
++
++ \li Q_ATOMIC_INT\e{nn}_FETCH_AND_ADD_IS_ALWAYS_NATIVE
++ \li Q_ATOMIC_INT\e{nn}_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
++ \li Q_ATOMIC_INT\e{nn}_FETCH_AND_ADD_IS_NOT_NATIVE
++ \li Q_ATOMIC_INT\e{nn}_FETCH_AND_ADD_IS_WAIT_FREE
++
++ \endlist
++
++ For compatibility with previous versions of Qt, macros with an empty \e{nn}
++ are equivalent to the 32-bit macros. For example,
++ Q_ATOMIC_INT_REFERENCE_COUNTING_IS_WAIT_FREE is the same as
++ Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_WAIT_FREE.
++
++ \sa QAtomicPointer
++ */
++
++ /*!
++ \fn QAtomicInt::QAtomicInt(int value)
++
++ Constructs a QAtomicInt with the given \a value.
++ */
++
++ /*!
++ \fn template <typename T> QAtomicInteger<T>::QAtomicInteger(T value)
++
++ Constructs a QAtomicInteger with the given \a value.
++ */
++
++ /*!
++ \fn template <typename T> QAtomicInteger<T>::QAtomicInteger(const QAtomicInteger &other)
++
++ Constructs a copy of \a other.
++ */
++
++ /*!
++ \fn template <typename T> QAtomicInteger &QAtomicInteger<T>::operator=(const QAtomicInteger &other)
++
++ Assigns \a other to this QAtomicInteger and returns a reference to
++ this QAtomicInteger.
++ */
++
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::loadRelaxed() const
++ \since 5.14
++
++ Atomically loads the value of this QAtomicInteger using relaxed memory
++ ordering. The value is not modified in any way, but note that there's no
++ guarantee that it remains so.
++
++ \sa storeRelaxed(), loadAcquire()
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::loadAcquire() const
++
++ Atomically loads the value of this QAtomicInteger using the "Acquire" memory
++ ordering. The value is not modified in any way, but note that there's no
++ guarantee that it remains so.
++
++ \sa storeRelaxed(), loadRelaxed()
++ */
++
++ /*!
++ \fn template <typename T> void QAtomicInteger<T>::storeRelaxed(T newValue)
++ \since 5.14
++
++ Atomically stores the \a newValue value into this atomic type, using
++ relaxed memory ordering.
++
++ \sa storeRelease(), loadRelaxed()
++ */
++
++ /*!
++ \fn template <typename T> void QAtomicInteger<T>::storeRelease(T newValue)
++
++ Atomically stores the \a newValue value into this atomic type, using
++ the "Release" memory ordering.
++
++ \sa storeRelaxed(), loadAcquire()
++ */
++
++ /*!
++ \fn template <typename T> QAtomicInteger<T>::operator T() const
++ \since 5.3
++
++ Atomically loads the value of this QAtomicInteger using a sequentially
++ consistent memory ordering if possible; or "Acquire" ordering if not. The
++ value is not modified in any way, but note that there's no guarantee that
++ it remains so.
++
++ \sa loadRelaxed(), loadAcquire()
++ */
++
++ /*!
++ \fn template <typename T> QAtomicInteger &QAtomicInteger<T>::operator=(T)
++ \since 5.3
++
++ Atomically stores the other value into this atomic type using a
++ sequentially consistent memory ordering if possible; or "Release" ordering
++ if not. This function returns a reference to this object.
++
++ \sa storeRelaxed(), storeRelease()
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicInteger<T>::isReferenceCountingNative()
++
++ Returns \c true if reference counting is implemented using atomic
++ processor instructions, false otherwise.
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicInteger<T>::isReferenceCountingWaitFree()
++
++ Returns \c true if atomic reference counting is wait-free, false
++ otherwise.
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicInteger<T>::ref()
++ Atomically increments the value of this QAtomicInteger. Returns \c true
++ if the new value is non-zero, false otherwise.
++
++ This function uses \e ordered \l {QAtomicInteger#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access before and after the atomic operation (in program order)
++ may not be re-ordered.
++
++ \sa deref(), operator++()
++ */
++
++ /*!
++ \fn template <typename T> void QAtomicInteger<T>::refRelaxed()
++ \internal
++ Atomically increments the value of this QAtomicInteger.
++
++ In contrast to ref(), this uses relaxed semantics, which is
++ all that is needed for reference counting (together with deref's
++ acquire-release semantics).
++ It also doesn't return anything.
++
++ \sa deref(), operator++()
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::operator++()
++ \since 5.3
++
++ Atomically pre-increments the value of this QAtomicInteger. Returns the new
++ value of this atomic.
++
++ This function uses a sequentially consistent memory ordering if possible;
++ or "Ordered" ordering if not.
++
++ \sa ref(), operator++(int), operator--()
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::operator++(int)
++ \since 5.3
++
++ Atomically post-increments the value of this QAtomicInteger. Returns the old
++ value of this atomic.
++
++ This function uses a sequentially consistent memory ordering if possible;
++ or "Ordered" ordering if not.
++
++ \sa ref(), operator++(), operator--(int)
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicInteger<T>::deref()
++ Atomically decrements the value of this QAtomicInteger. Returns \c true
++ if the new value is non-zero, false otherwise.
++
++ This function uses \e ordered \l {QAtomicInteger#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access before and after the atomic operation (in program order)
++ may not be re-ordered.
++
++ \sa ref(), operator--()
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::operator--()
++ \since 5.3
++
++ Atomically pre-decrements the value of this QAtomicInteger. Returns the new
++ value of this atomic.
++
++ This function uses a sequentially consistent memory ordering if possible;
++ or "Ordered" ordering if not.
++
++ \sa deref(), operator--(int), operator++()
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::operator--(int)
++ \since 5.3
++
++ Atomically post-decrements the value of this QAtomicInteger. Returns the old
++ value of this atomic.
++
++ This function uses a sequentially consistent memory ordering if possible;
++ or "Ordered" ordering if not.
++
++ \sa deref(), operator--(), operator++(int)
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicInteger<T>::isTestAndSetNative()
++
++ Returns \c true if test-and-set is implemented using atomic processor
++ instructions, false otherwise.
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicInteger<T>::isTestAndSetWaitFree()
++
++ Returns \c true if atomic test-and-set is wait-free, false otherwise.
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicInteger<T>::testAndSetRelaxed(T expectedValue, T newValue)
++
++ Atomic test-and-set.
++
++ \note If you use this function in a loop, consider using the overload with the
++ additional \c{T &currentValue} argument instead, which avoids the extra loadRelaxed() on
++ failure.
++
++ If the current value of this QAtomicInteger is the \a expectedValue,
++ the test-and-set functions assign the \a newValue to this
++ QAtomicInteger and return true. If the values are \e not the same,
++ this function does nothing and returns \c false.
++
++ //![memory-order-relaxed]
++ This function uses \e relaxed \l {QAtomicInteger#Memory
++ ordering}{memory ordering} semantics, leaving the compiler and
++ processor to freely reorder memory accesses.
++ //![memory-order-relaxed]
++
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicInteger<T>::testAndSetAcquire(T expectedValue, T newValue)
++
++ Atomic test-and-set.
++
++ \note If you use this function in a loop, consider using the overload with the
++ additional \c{T &currentValue} argument instead, which avoids the extra loadAcquire() on
++ failure.
++
++ If the current value of this QAtomicInteger is the \a expectedValue,
++ the test-and-set functions assign the \a newValue to this
++ QAtomicInteger and return true. If the values are \e not the same,
++ this function does nothing and returns \c false.
++
++ //![memory-order-acquire]
++ This function uses \e acquire \l {QAtomicInteger#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access following the atomic operation (in program order) may not
++ be re-ordered before the atomic operation.
++ //![memory-order-acquire]
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicInteger<T>::testAndSetRelease(T expectedValue, T newValue)
++
++ Atomic test-and-set.
++
++ \note If you use this function in a loop, consider using the overload with the
++ additional \c{T &currentValue} argument instead, which avoids the extra loadRelaxed() on
++ failure.
++
++ If the current value of this QAtomicInteger is the \a expectedValue,
++ the test-and-set functions assign the \a newValue to this
++ QAtomicInteger and return true. If the values are \e not the same,
++ this function does nothing and returns \c false.
++
++ //![memory-order-release]
++ This function uses \e release \l {QAtomicInteger#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access before the atomic operation (in program order) may not be
++ re-ordered after the atomic operation.
++ //![memory-order-release]
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicInteger<T>::testAndSetOrdered(T expectedValue, T newValue)
++
++ Atomic test-and-set.
++
++ \note If you use this function in a loop, consider using the overload with the
++ additional \c{T &currentValue} argument instead, which avoids the extra loadAcquire() on
++ failure.
++
++ If the current value of this QAtomicInteger is the \a expectedValue,
++ the test-and-set functions assign the \a newValue to this
++ QAtomicInteger and return true. If the values are \e not the same,
++ this function does nothing and returns \c false.
++
++ //![memory-order-ordered]
++ This function uses \e ordered \l {QAtomicInteger#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access before and after the atomic operation (in program order)
++ may not be re-ordered.
++ //![memory-order-ordered]
++
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicInteger<T>::testAndSetRelaxed(T expectedValue, T newValue, T &currentValue)
++ \since 5.3
++
++ Atomic test-and-set.
++
++ If the current value of this QAtomicInteger is the \a expectedValue, the
++ test-and-set functions assign the \a newValue to this QAtomicInteger and
++ return \c true. If the values are \e not the same, the functions load the
++ current value of this QAtomicInteger into \a currentValue and return \c false.
++
++ //![memory-order-3-arg-relaxed]
++ \include qatomic.cpp memory-order-relaxed
++ If the test-and-set fails, the \a currentValue is loaded with \e relaxed
++ \l {QAtomicInteger#Memory ordering}{memory ordering} semantics.
++ //![memory-order-3-arg-relaxed]
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicInteger<T>::testAndSetAcquire(T expectedValue, T newValue, T &currentValue)
++ \since 5.3
++
++ Atomic test-and-set.
++
++ If the current value of this QAtomicInteger is the \a expectedValue, the
++ test-and-set functions assign the \a newValue to this QAtomicInteger and
++ return \c true. If the values are \e not the same, the functions load the
++ current value of this QAtomicInteger into \a currentValue and return \c false.
++
++ //![memory-order-3-arg-acquire]
++ \include qatomic.cpp memory-order-acquire
++ If the test-and-set fails, the \a currentValue is loaded with \e acquire
++ \l {QAtomicInteger#Memory ordering}{memory ordering} semantics.
++ //![memory-order-3-arg-acquire]
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicInteger<T>::testAndSetRelease(T expectedValue, T newValue, T &currentValue)
++ \since 5.3
++
++ Atomic test-and-set.
++
++ If the current value of this QAtomicInteger is the \a expectedValue, the
++ test-and-set functions assign the \a newValue to this QAtomicInteger and
++ return \c true. If the values are \e not the same, the functions loads the
++ current value of this QAtomicInteger into \a currentValue and return \c false.
++
++ //![memory-order-3-arg-release]
++ \include qatomic.cpp memory-order-release
++ If the test-and-set fails, the \a currentValue is loaded with \e relaxed
++ \l {QAtomicInteger#Memory ordering}{memory ordering} semantics.
++ //![memory-order-3-arg-release]
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicInteger<T>::testAndSetOrdered(T expectedValue, T newValue, T &currentValue)
++ \since 5.3
++
++ Atomic test-and-set.
++
++ If the current value of this QAtomicInteger is the \a expectedValue, the
++ test-and-set functions assign the \a newValue to this QAtomicInteger and
++ return \c true. If the values are \e not the same, it loads the current
++ value of this QAtomicInteger into \a currentValue and return \c false.
++
++ //![memory-order-3-arg-ordered]
++ \include qatomic.cpp memory-order-ordered
++ If the test-and-set fails, the \a currentValue is loaded with \e acquire
++ \l {QAtomicInteger#Memory ordering}{memory ordering} semantics.
++ //![memory-order-3-arg-ordered]
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicInteger<T>::isFetchAndStoreNative()
++
++ Returns \c true if fetch-and-store is implemented using atomic
++ processor instructions, false otherwise.
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicInteger<T>::isFetchAndStoreWaitFree()
++
++ Returns \c true if atomic fetch-and-store is wait-free, false
++ otherwise.
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::fetchAndStoreRelaxed(T newValue)
++
++ Atomic fetch-and-store.
++
++ Reads the current value of this QAtomicInteger and then assigns it the
++ \a newValue, returning the original value.
++
++ This function uses \e relaxed \l {QAtomicInteger#Memory
++ ordering}{memory ordering} semantics, leaving the compiler and
++ processor to freely reorder memory accesses.
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::fetchAndStoreAcquire(T newValue)
++
++ Atomic fetch-and-store.
++
++ Reads the current value of this QAtomicInteger and then assigns it the
++ \a newValue, returning the original value.
++
++ This function uses \e acquire \l {QAtomicInteger#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access following the atomic operation (in program order) may not
++ be re-ordered before the atomic operation.
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::fetchAndStoreRelease(T newValue)
++
++ Atomic fetch-and-store.
++
++ Reads the current value of this QAtomicInteger and then assigns it the
++ \a newValue, returning the original value.
++
++ This function uses \e release \l {QAtomicInteger#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access before the atomic operation (in program order) may not be
++ re-ordered after the atomic operation.
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::fetchAndStoreOrdered(T newValue)
++
++ Atomic fetch-and-store.
++
++ Reads the current value of this QAtomicInteger and then assigns it the
++ \a newValue, returning the original value.
++
++ This function uses \e ordered \l {QAtomicInteger#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access before and after the atomic operation (in program order)
++ may not be re-ordered.
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicInteger<T>::isFetchAndAddNative()
++
++ Returns \c true if fetch-and-add is implemented using atomic
++ processor instructions, false otherwise.
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicInteger<T>::isFetchAndAddWaitFree()
++
++ Returns \c true if atomic fetch-and-add is wait-free, false
++ otherwise.
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::fetchAndAddRelaxed(T valueToAdd)
++
++ Atomic fetch-and-add.
++
++ Reads the current value of this QAtomicInteger and then adds
++ \a valueToAdd to the current value, returning the original value.
++
++ This function uses \e relaxed \l {QAtomicInteger#Memory
++ ordering}{memory ordering} semantics, leaving the compiler and
++ processor to freely reorder memory accesses.
++
++ \sa operator+=(), fetchAndSubRelaxed()
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::fetchAndAddAcquire(T valueToAdd)
++
++ Atomic fetch-and-add.
++
++ Reads the current value of this QAtomicInteger and then adds
++ \a valueToAdd to the current value, returning the original value.
++
++ This function uses \e acquire \l {QAtomicInteger#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access following the atomic operation (in program order) may not
++ be re-ordered before the atomic operation.
++
++ \sa operator+=(), fetchAndSubAcquire()
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::fetchAndAddRelease(T valueToAdd)
++
++ Atomic fetch-and-add.
++
++ Reads the current value of this QAtomicInteger and then adds
++ \a valueToAdd to the current value, returning the original value.
++
++ This function uses \e release \l {QAtomicInteger#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access before the atomic operation (in program order) may not be
++ re-ordered after the atomic operation.
++
++ \sa operator+=(), fetchAndSubRelease()
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::fetchAndAddOrdered(T valueToAdd)
++
++ Atomic fetch-and-add.
++
++ Reads the current value of this QAtomicInteger and then adds
++ \a valueToAdd to the current value, returning the original value.
++
++ This function uses \e ordered \l {QAtomicInteger#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access before and after the atomic operation (in program order)
++ may not be re-ordered.
++
++ \sa operator+=(), fetchAndSubOrdered()
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::operator+=(T value)
++ \since 5.3
++
++ Atomic add-and-fetch.
++
++ Reads the current value of this QAtomicInteger and then adds
++ \a value to the current value, returning the new value.
++
++ This function uses a sequentially consistent memory ordering if possible;
++ or "Ordered" ordering if not.
++
++ \sa fetchAndAddOrdered(), operator-=()
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::fetchAndSubRelaxed(T valueToSub)
++ \since 5.3
++
++ Atomic fetch-and-sub.
++
++ Reads the current value of this QAtomicInteger and then subtracts
++ \a valueToSub to the current value, returning the original value.
++
++ This function uses \e relaxed \l {QAtomicInteger#Memory
++ ordering}{memory ordering} semantics, leaving the compiler and
++ processor to freely reorder memory accesses.
++
++ \sa operator-=(), fetchAndAddRelaxed()
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::fetchAndSubAcquire(T valueToSub)
++ \since 5.3
++
++ Atomic fetch-and-sub.
++
++ Reads the current value of this QAtomicInteger and then subtracts
++ \a valueToSub to the current value, returning the original value.
++
++ This function uses \e acquire \l {QAtomicInteger#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access following the atomic operation (in program order) may not
++ be re-ordered before the atomic operation.
++
++ \sa operator-=(), fetchAndAddAcquire()
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::fetchAndSubRelease(T valueToSub)
++ \since 5.3
++
++ Atomic fetch-and-sub.
++
++ Reads the current value of this QAtomicInteger and then subtracts
++ \a valueToSub to the current value, returning the original value.
++
++ This function uses \e release \l {QAtomicInteger#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access before the atomic operation (in program order) may not be
++ re-ordered after the atomic operation.
++
++ \sa operator-=(), fetchAndAddRelease()
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::fetchAndSubOrdered(T valueToSub)
++ \since 5.3
++
++ Atomic fetch-and-sub.
++
++ Reads the current value of this QAtomicInteger and then subtracts
++ \a valueToSub to the current value, returning the original value.
++
++ This function uses \e ordered \l {QAtomicInteger#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access before and after the atomic operation (in program order)
++ may not be re-ordered.
++
++ \sa operator-=(), fetchAndAddOrdered()
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::operator-=(T value)
++ \since 5.3
++
++ Atomic sub-and-fetch.
++
++ Reads the current value of this QAtomicInteger and then subtracts
++ \a value to the current value, returning the new value.
++
++ This function uses a sequentially consistent memory ordering if possible;
++ or "Ordered" ordering if not.
++
++ \sa fetchAndSubOrdered(), operator+=()
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::fetchAndOrRelaxed(T valueToOr)
++ \since 5.3
++
++ Atomic fetch-and-or.
++
++ Reads the current value of this QAtomicInteger and then bitwise-ORs
++ \a valueToOr to the current value, returning the original value.
++
++ This function uses \e relaxed \l {QAtomicInteger#Memory
++ ordering}{memory ordering} semantics, leaving the compiler and
++ processor to freely reorder memory accesses.
++
++ \sa operator|=()
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::fetchAndOrAcquire(T valueToOr)
++ \since 5.3
++
++ Atomic fetch-and-or.
++
++ Reads the current value of this QAtomicInteger and then bitwise-ORs
++ \a valueToOr to the current value, returning the original value.
++
++ This function uses \e acquire \l {QAtomicInteger#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access following the atomic operation (in program order) may not
++ be re-ordered before the atomic operation.
++
++ \sa operator|=()
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::fetchAndOrRelease(T valueToOr)
++ \since 5.3
++
++ Atomic fetch-and-or.
++
++ Reads the current value of this QAtomicInteger and then bitwise-ORs
++ \a valueToOr to the current value, returning the original value.
++
++ This function uses \e release \l {QAtomicInteger#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access before the atomic operation (in program order) may not be
++ re-ordered after the atomic operation.
++
++ \sa operator|=()
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::fetchAndOrOrdered(T valueToOr)
++ \since 5.3
++
++ Atomic fetch-and-or.
++
++ Reads the current value of this QAtomicInteger and then bitwise-ORs
++ \a valueToOr to the current value, returning the original value.
++
++ This function uses \e ordered \l {QAtomicInteger#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access before and after the atomic operation (in program order)
++ may not be re-ordered.
++
++ \sa operator|=()
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::operator|=(T value)
++ \since 5.3
++
++ Atomic or-and-fetch.
++
++ Reads the current value of this QAtomicInteger and then bitwise-ORs
++ \a value to the current value, returning the new value.
++
++ This function uses a sequentially consistent memory ordering if possible;
++ or "Ordered" ordering if not.
++
++ \sa fetchAndOrOrdered()
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::fetchAndXorRelaxed(T valueToXor)
++ \since 5.3
++
++ Atomic fetch-and-xor.
++
++ Reads the current value of this QAtomicInteger and then bitwise-XORs
++ \a valueToXor to the current value, returning the original value.
++
++ This function uses \e relaxed \l {QAtomicInteger#Memory
++ ordering}{memory ordering} semantics, leaving the compiler and
++ processor to freely reorder memory accesses.
++
++ \sa operator^=()
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::fetchAndXorAcquire(T valueToXor)
++ \since 5.3
++
++ Atomic fetch-and-xor.
++
++ Reads the current value of this QAtomicInteger and then bitwise-XORs
++ \a valueToXor to the current value, returning the original value.
++
++ This function uses \e acquire \l {QAtomicInteger#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access following the atomic operation (in program order) may not
++ be re-ordered before the atomic operation.
++
++ \sa operator^=()
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::fetchAndXorRelease(T valueToXor)
++ \since 5.3
++
++ Atomic fetch-and-xor.
++
++ Reads the current value of this QAtomicInteger and then bitwise-XORs
++ \a valueToXor to the current value, returning the original value.
++
++ This function uses \e release \l {QAtomicInteger#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access before the atomic operation (in program order) may not be
++ re-ordered after the atomic operation.
++
++ \sa operator^=()
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::fetchAndXorOrdered(T valueToXor)
++ \since 5.3
++
++ Atomic fetch-and-xor.
++
++ Reads the current value of this QAtomicInteger and then bitwise-XORs
++ \a valueToXor to the current value, returning the original value.
++
++ This function uses \e ordered \l {QAtomicInteger#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access before and after the atomic operation (in program order)
++ may not be re-ordered.
++
++ \sa operator^=()
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::operator^=(T value)
++ \since 5.3
++
++ Atomic xor-and-fetch.
++
++ Reads the current value of this QAtomicInteger and then bitwise-XORs
++ \a value to the current value, returning the new value.
++
++ This function uses a sequentially consistent memory ordering if possible;
++ or "Ordered" ordering if not.
++
++ \sa fetchAndXorOrdered()
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::fetchAndAndRelaxed(T valueToAnd)
++ \since 5.3
++
++ Atomic fetch-and-and.
++
++ Reads the current value of this QAtomicInteger and then bitwise-ANDs
++ \a valueToAnd to the current value, returning the original value.
++
++ This function uses \e relaxed \l {QAtomicInteger#Memory
++ ordering}{memory ordering} semantics, leaving the compiler and
++ processor to freely reorder memory accesses.
++
++ \sa operator&=()
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::fetchAndAndAcquire(T valueToAnd)
++ \since 5.3
++
++ Atomic fetch-and-and.
++
++ Reads the current value of this QAtomicInteger and then bitwise-ANDs
++ \a valueToAnd to the current value, returning the original value.
++
++ This function uses \e acquire \l {QAtomicInteger#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access following the atomic operation (in program order) may not
++ be re-ordered before the atomic operation.
++
++ \sa operator&=()
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::fetchAndAndRelease(T valueToAnd)
++ \since 5.3
++
++ Atomic fetch-and-and.
++
++ Reads the current value of this QAtomicInteger and then bitwise-ANDs
++ \a valueToAnd to the current value, returning the original value.
++
++ This function uses \e release \l {QAtomicInteger#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access before the atomic operation (in program order) may not be
++ re-ordered after the atomic operation.
++
++ \sa operator&=()
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::fetchAndAndOrdered(T valueToAnd)
++ \since 5.3
++
++ Atomic fetch-and-and.
++
++ Reads the current value of this QAtomicInteger and then bitwise-ANDs
++ \a valueToAnd to the current value, returning the original value.
++
++ This function uses \e ordered \l {QAtomicInteger#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access before and after the atomic operation (in program order)
++ may not be re-ordered.
++
++ \sa operator&=()
++ */
++
++ /*!
++ \fn template <typename T> T QAtomicInteger<T>::operator&=(T value)
++ \since 5.3
++
++ Atomic add-and-fetch.
++
++ Reads the current value of this QAtomicInteger and then bitwise-ANDs
++ \a value to the current value, returning the new value.
++
++ This function uses a sequentially consistent memory ordering if possible;
++ or "Ordered" ordering if not.
++
++ \sa fetchAndAndOrdered()
++ */
++
++ /*!
++ \macro Q_ATOMIC_INTnn_IS_SUPPORTED
++ \relates QAtomicInteger
++
++ This macro is defined if atomic integers of size \e{nn} (in bits) are
++ supported in this compiler / architecture combination.
++
++ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
++
++ The following macros always defined:
++
++ \list
++ \li Q_ATOMIC_INT8_IS_SUPPORTED
++ \li Q_ATOMIC_INT16_IS_SUPPORTED
++ \li Q_ATOMIC_INT32_IS_SUPPORTED
++ \endlist
++ */
++
++ /*!
++ \macro Q_ATOMIC_INTnn_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
++ \relates QAtomicInteger
++
++ This macro is defined if and only if all generations of your
++ processor support atomic reference counting.
++
++ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
++ */
++
++ /*!
++ \macro Q_ATOMIC_INTnn_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
++ \relates QAtomicInteger
++
++ This macro is defined when only certain generations of the
++ processor support atomic reference counting. Use the
++ QAtomicInteger::isReferenceCountingNative() function to check what
++ your processor supports.
++
++ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
++ */
++
++ /*!
++ \macro Q_ATOMIC_INTnn_REFERENCE_COUNTING_IS_NOT_NATIVE
++ \relates QAtomicInteger
++
++ This macro is defined when the hardware does not support atomic
++ reference counting.
++
++ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
++ */
++
++ /*!
++ \macro Q_ATOMIC_INTnn_REFERENCE_COUNTING_IS_WAIT_FREE
++ \relates QAtomicInteger
++
++ This macro is defined together with
++ Q_ATOMIC_INTnn_REFERENCE_COUNTING_IS_ALWAYS_NATIVE to indicate that
++ the reference counting is wait-free.
++
++ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
++ */
++
++ /*!
++ \macro Q_ATOMIC_INTnn_TEST_AND_SET_IS_ALWAYS_NATIVE
++ \relates QAtomicInteger
++
++ This macro is defined if and only if your processor supports
++ atomic test-and-set on integers.
++
++ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
++ */
++
++ /*!
++ \macro Q_ATOMIC_INTnn_TEST_AND_SET_IS_SOMETIMES_NATIVE
++ \relates QAtomicInteger
++
++ This macro is defined when only certain generations of the
++ processor support atomic test-and-set on integers. Use the
++ QAtomicInteger::isTestAndSetNative() function to check what your
++ processor supports.
++
++ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
++ */
++
++ /*!
++ \macro Q_ATOMIC_INTnn_TEST_AND_SET_IS_NOT_NATIVE
++ \relates QAtomicInteger
++
++ This macro is defined when the hardware does not support atomic
++ test-and-set on integers.
++
++ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
++ */
++
++ /*!
++ \macro Q_ATOMIC_INTnn_TEST_AND_SET_IS_WAIT_FREE
++ \relates QAtomicInteger
++
++ This macro is defined together with
++ Q_ATOMIC_INTnn_TEST_AND_SET_IS_ALWAYS_NATIVE to indicate that the
++ atomic test-and-set on integers is wait-free.
++
++ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
++ */
++
++ /*!
++ \macro Q_ATOMIC_INTnn_FETCH_AND_STORE_IS_ALWAYS_NATIVE
++ \relates QAtomicInteger
++
++ This macro is defined if and only if your processor supports
++ atomic fetch-and-store on integers.
++
++ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
++ */
++
++ /*!
++ \macro Q_ATOMIC_INTnn_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
++ \relates QAtomicInteger
++
++ This macro is defined when only certain generations of the
++ processor support atomic fetch-and-store on integers. Use the
++ QAtomicInteger::isFetchAndStoreNative() function to check what your
++ processor supports.
++
++ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
++ */
++
++ /*!
++ \macro Q_ATOMIC_INTnn_FETCH_AND_STORE_IS_NOT_NATIVE
++ \relates QAtomicInteger
++
++ This macro is defined when the hardware does not support atomic
++ fetch-and-store on integers.
++
++ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
++ */
++
++ /*!
++ \macro Q_ATOMIC_INTnn_FETCH_AND_STORE_IS_WAIT_FREE
++ \relates QAtomicInteger
++
++ This macro is defined together with
++ Q_ATOMIC_INTnn_FETCH_AND_STORE_IS_ALWAYS_NATIVE to indicate that the
++ atomic fetch-and-store on integers is wait-free.
++
++ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
++ */
++
++ /*!
++ \macro Q_ATOMIC_INTnn_FETCH_AND_ADD_IS_ALWAYS_NATIVE
++ \relates QAtomicInteger
++
++ This macro is defined if and only if your processor supports
++ atomic fetch-and-add on integers.
++
++ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
++ */
++
++ /*!
++ \macro Q_ATOMIC_INTnn_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
++ \relates QAtomicInteger
++
++ This macro is defined when only certain generations of the
++ processor support atomic fetch-and-add on integers. Use the
++ QAtomicInteger::isFetchAndAddNative() function to check what your
++ processor supports.
++
++ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
++ */
++
++ /*!
++ \macro Q_ATOMIC_INTnn_FETCH_AND_ADD_IS_NOT_NATIVE
++ \relates QAtomicInteger
++
++ This macro is defined when the hardware does not support atomic
++ fetch-and-add on integers.
++
++ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
++ */
++
++ /*!
++ \macro Q_ATOMIC_INTnn_FETCH_AND_ADD_IS_WAIT_FREE
++ \relates QAtomicInteger
++
++ This macro is defined together with
++ Q_ATOMIC_INTnn_FETCH_AND_ADD_IS_ALWAYS_NATIVE to indicate that the
++ atomic fetch-and-add on integers is wait-free.
++
++ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
++ */
++
++
++
++
++ /*!
++ \class QAtomicPointer
++ \inmodule QtCore
++ \brief The QAtomicPointer class is a template class that provides platform-independent atomic operations on pointers.
++ \since 4.4
++
++ \ingroup thread
++
++ For atomic operations on integers, see the QAtomicInteger class.
++
++ An \e atomic operation is a complex operation that completes without interruption.
++ The QAtomicPointer class provides atomic test-and-set, fetch-and-store, and fetch-and-add
++ for pointers. The template parameter \a T specifies the pointed-to type.
++
++ \section1 The Atomic API
++
++ \section2 Memory ordering
++
++ QAtomicPointer provides several implementations of the atomic
++ test-and-set, fetch-and-store, and fetch-and-add functions. Each
++ implementation defines a memory ordering semantic that describes
++ how memory accesses surrounding the atomic instruction are
++ executed by the processor. Since many modern architectures allow
++ out-of-order execution and memory ordering, using the correct
++ semantic is necessary to ensure that your application functions
++ properly on all processors.
++
++ \list
++
++ \li Relaxed - memory ordering is unspecified, leaving the compiler
++ and processor to freely reorder memory accesses.
++
++ \li Acquire - memory access following the atomic operation (in
++ program order) may not be re-ordered before the atomic operation.
++
++ \li Release - memory access before the atomic operation (in program
++ order) may not be re-ordered after the atomic operation.
++
++ \li Ordered - the same Acquire and Release semantics combined.
++
++ \endlist
++
++ \section2 Test-and-set
++
++ If the current value of the QAtomicPointer is an expected value,
++ the test-and-set functions assign a new value to the
++ QAtomicPointer and return true. If values are \e not the same,
++ these functions do nothing and return false. This operation
++ equates to the following code:
++
++ \snippet code/src_corelib_thread_qatomic.cpp 4
++
++ There are 4 test-and-set functions: testAndSetRelaxed(),
++ testAndSetAcquire(), testAndSetRelease(), and
++ testAndSetOrdered(). See above for an explanation of the different
++ memory ordering semantics.
++
++ \section2 Fetch-and-store
++
++ The atomic fetch-and-store functions read the current value of the
++ QAtomicPointer and then assign a new value, returning the original
++ value. This operation equates to the following code:
++
++ \snippet code/src_corelib_thread_qatomic.cpp 5
++
++ There are 4 fetch-and-store functions: fetchAndStoreRelaxed(),
++ fetchAndStoreAcquire(), fetchAndStoreRelease(), and
++ fetchAndStoreOrdered(). See above for an explanation of the
++ different memory ordering semantics.
++
++ \section2 Fetch-and-add
++
++ The atomic fetch-and-add functions read the current value of the
++ QAtomicPointer and then add the given value to the current value,
++ returning the original value. This operation equates to the
++ following code:
++
++ \snippet code/src_corelib_thread_qatomic.cpp 6
++
++ There are 4 fetch-and-add functions: fetchAndAddRelaxed(),
++ fetchAndAddAcquire(), fetchAndAddRelease(), and
++ fetchAndAddOrdered(). See above for an explanation of the
++ different memory ordering semantics.
++
++ \section1 Feature Tests for the Atomic API
++
++ Providing a platform-independent atomic API that works on all
++ processors is challenging. The API provided by QAtomicPointer is
++ guaranteed to work atomically on all processors. However, since
++ not all processors implement support for every operation provided
++ by QAtomicPointer, it is necessary to expose information about the
++ processor.
++
++ You can check at compile time which features are supported on your
++ hardware using various macros. These will tell you if your
++ hardware always, sometimes, or does not support a particular
++ operation. The macros have the form
++ Q_ATOMIC_POINTER_\e{OPERATION}_IS_\e{HOW}_NATIVE. \e{OPERATION} is
++ one of TEST_AND_SET, FETCH_AND_STORE, or FETCH_AND_ADD, and
++ \e{HOW} is one of ALWAYS, SOMETIMES, or NOT. There will always be
++ exactly one defined macro per operation. For example, if
++ Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE is defined, neither
++ Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE nor
++ Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE will be defined.
++
++ An operation that completes in constant time is said to be
++ wait-free. Such operations are not implemented using locks or
++ loops of any kind. For atomic operations that are always
++ supported, and that are wait-free, Qt defines the
++ Q_ATOMIC_POINTER_\e{OPERATION}_IS_WAIT_FREE in addition to the
++ Q_ATOMIC_POINTER_\e{OPERATION}_IS_ALWAYS_NATIVE.
++
++ In cases where an atomic operation is only supported in newer
++ generations of the processor, QAtomicPointer also provides a way
++ to check at runtime what your hardware supports with the
++ isTestAndSetNative(), isFetchAndStoreNative(), and
++ isFetchAndAddNative() functions. Wait-free implementations can be
++ detected using the isTestAndSetWaitFree(),
++ isFetchAndStoreWaitFree(), and isFetchAndAddWaitFree() functions.
++
++ Below is a complete list of all feature macros for QAtomicPointer:
++
++ \list
++
++ \li Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
++ \li Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE
++ \li Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
++ \li Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE
++
++ \li Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
++ \li Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
++ \li Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE
++ \li Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE
++
++ \li Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
++ \li Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
++ \li Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE
++ \li Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_WAIT_FREE
++
++ \endlist
++
++ \sa QAtomicInteger, qYieldCpu()
++ */
++
++ /*!
++ \fn template <typename T> QAtomicPointer<T>::QAtomicPointer(T *value)
++
++ Constructs a QAtomicPointer with the given \a value.
++ */
++
++ /*!
++ \fn template <typename T> QAtomicPointer<T>::QAtomicPointer(const QAtomicPointer<T> &other)
++
++ Constructs a copy of \a other.
++ */
++
++ /*!
++ \fn template <typename T> QAtomicPointer &QAtomicPointer<T>::operator=(const QAtomicPointer &other)
++
++ Assigns \a other to this QAtomicPointer and returns a reference to
++ this QAtomicPointer.
++ */
++
++ /*!
++ \fn template <typename T> T *QAtomicPointer<T>::loadRelaxed() const
++ \since 5.14
++
++ Atomically loads the value of this QAtomicPointer using relaxed memory
++ ordering. The value is not modified in any way, but note that there's no
++ guarantee that it remains so.
++
++ \sa storeRelaxed(), loadAcquire()
++ */
++
++
++ /*!
++ \fn template <typename T> T *QAtomicPointer<T>::loadAcquire() const
++
++ Atomically loads the value of this QAtomicPointer using the "Acquire" memory
++ ordering. The value is not modified in any way, but note that there's no
++ guarantee that it remains so.
++
++ \sa storeRelease(), loadRelaxed()
++ */
++
++ /*!
++ \fn template <typename T> void QAtomicPointer<T>::storeRelaxed(T *newValue)
++ \since 5.14
++
++ Atomically stores the \a newValue value into this atomic type, using
++ relaxed memory ordering.
++
++ \sa storeRelease(), loadRelaxed()
++ */
++
++ /*!
++ \fn template <typename T> void QAtomicPointer<T>::storeRelease(T *newValue)
++
++ Atomically stores the \a newValue value into this atomic type, using
++ the "Release" memory ordering.
++
++ \sa storeRelaxed(), loadRelaxed()
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicPointer<T>::isTestAndSetNative()
++
++ Returns \c true if test-and-set is implemented using atomic processor
++ instructions, false otherwise.
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicPointer<T>::isTestAndSetWaitFree()
++
++ Returns \c true if atomic test-and-set is wait-free, false otherwise.
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
++
++ Atomic test-and-set.
++
++ \note If you use this function in a loop, consider using the overload with the
++ additional \c{T *&currentValue} argument instead, which avoids the extra load() on
++ failure.
++
++ If the current value of this QAtomicPointer is the \a expectedValue,
++ the test-and-set functions assign the \a newValue to this
++ QAtomicPointer and return true. If the values are \e not the same,
++ this function does nothing and returns \c false.
++
++ This function uses \e relaxed \l {QAtomicPointer#Memory
++ ordering}{memory ordering} semantics, leaving the compiler and
++ processor to freely reorder memory accesses.
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
++
++ Atomic test-and-set.
++
++ \note If you use this function in a loop, consider using the overload with the
++ additional \c{T *&currentValue} argument instead, which avoids the extra load() on
++ failure.
++
++ If the current value of this QAtomicPointer is the \a expectedValue,
++ the test-and-set functions assign the \a newValue to this
++ QAtomicPointer and return true. If the values are \e not the same,
++ this function does nothing and returns \c false.
++
++ This function uses \e acquire \l {QAtomicPointer#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access following the atomic operation (in program order) may not
++ be re-ordered before the atomic operation.
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
++
++ Atomic test-and-set.
++
++ \note If you use this function in a loop, consider using the overload with the
++ additional \c{T *&currentValue} argument instead, which avoids the extra load() on
++ failure.
++
++ If the current value of this QAtomicPointer is the \a expectedValue,
++ the test-and-set functions assign the \a newValue to this
++ QAtomicPointer and return true. If the values are \e not the same,
++ this function does nothing and returns \c false.
++
++ This function uses \e release \l {QAtomicPointer#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access before the atomic operation (in program order) may not be
++ re-ordered after the atomic operation.
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
++
++ Atomic test-and-set.
++
++ \note If you use this function in a loop, consider using the overload with the
++ additional \c{T *&currentValue} argument instead, which avoids the extra load() on
++ failure.
++
++ If the current value of this QAtomicPointer is the \a expectedValue,
++ the test-and-set functions assign the \a newValue to this
++ QAtomicPointer and return true. If the values are \e not the same,
++ this function does nothing and returns \c false.
++
++ This function uses \e ordered \l {QAtomicPointer#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access before and after the atomic operation (in program order)
++ may not be re-ordered.
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue, T *&currentValue)
++
++ Atomic test-and-set.
++
++ If the current value of this QAtomicPointer is the \a expectedValue, the
++ test-and-set functions assign the \a newValue to this QAtomicPointer and
++ return \c true. If the values are \e not the same, the functions load the
++ current value of this QAtomicPointer into \a currentValue and return \c false.
++
++ \include qatomic.cpp memory-order-3-arg-relaxed
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue, T *&currentValue)
++
++ Atomic test-and-set.
++
++ If the current value of this QAtomicPointer is the \a expectedValue, the
++ test-and-set functions assign the \a newValue to this QAtomicPointer and
++ return \c true. If the values are \e not the same, the functions load the
++ current value of this QAtomicPointer into \a currentValue and return \c false.
++
++ \include qatomic.cpp memory-order-3-arg-acquire
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue, T *&currentValue)
++
++ Atomic test-and-set.
++
++ If the current value of this QAtomicPointer is the \a expectedValue, the
++ test-and-set functions assign the \a newValue to this QAtomicPointer and
++ return \c true. If the values are \e not the same, the functions load the
++ current value of this QAtomicPointer into \a currentValue and return \c false.
++
++ \include qatomic.cpp memory-order-3-arg-release
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue, T *&currentValue)
++
++ Atomic test-and-set.
++
++ If the current value of this QAtomicPointer is the \a expectedValue, the
++ test-and-set functions assign the \a newValue to this QAtomicPointer and
++ return \c true. If the values are \e not the same, the functions load the
++ current value of this QAtomicPointer into \a currentValue and return \c false.
++
++ \include qatomic.cpp memory-order-3-arg-ordered
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicPointer<T>::isFetchAndStoreNative()
++
++ Returns \c true if fetch-and-store is implemented using atomic
++ processor instructions, false otherwise.
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicPointer<T>::isFetchAndStoreWaitFree()
++
++ Returns \c true if atomic fetch-and-store is wait-free, false
++ otherwise.
++ */
++
++ /*!
++ \fn template <typename T> T *QAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
++
++ Atomic fetch-and-store.
++
++ Reads the current value of this QAtomicPointer and then assigns it the
++ \a newValue, returning the original value.
++
++ This function uses \e relaxed \l {QAtomicPointer#Memory
++ ordering}{memory ordering} semantics, leaving the compiler and
++ processor to freely reorder memory accesses.
++ */
++
++ /*!
++ \fn template <typename T> T *QAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
++
++ Atomic fetch-and-store.
++
++ Reads the current value of this QAtomicPointer and then assigns it the
++ \a newValue, returning the original value.
++
++ This function uses \e acquire \l {QAtomicPointer#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access following the atomic operation (in program order) may not
++ be re-ordered before the atomic operation.
++ */
++
++ /*!
++ \fn template <typename T> T *QAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
++
++ Atomic fetch-and-store.
++
++ Reads the current value of this QAtomicPointer and then assigns it the
++ \a newValue, returning the original value.
++
++ This function uses \e release \l {QAtomicPointer#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access before the atomic operation (in program order) may not be
++ re-ordered after the atomic operation.
++ */
++
++ /*!
++ \fn template <typename T> T *QAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
++
++ Atomic fetch-and-store.
++
++ Reads the current value of this QAtomicPointer and then assigns it the
++ \a newValue, returning the original value.
++
++ This function uses \e ordered \l {QAtomicPointer#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access before and after the atomic operation (in program order)
++ may not be re-ordered.
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicPointer<T>::isFetchAndAddNative()
++
++ Returns \c true if fetch-and-add is implemented using atomic
++ processor instructions, false otherwise.
++ */
++
++ /*!
++ \fn template <typename T> bool QAtomicPointer<T>::isFetchAndAddWaitFree()
++
++ Returns \c true if atomic fetch-and-add is wait-free, false
++ otherwise.
++ */
++
++ /*!
++ \fn template <typename T> T *QAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
++
++ Atomic fetch-and-add.
++
++ Reads the current value of this QAtomicPointer and then adds
++ \a valueToAdd to the current value, returning the original value.
++
++ This function uses \e relaxed \l {QAtomicPointer#Memory
++ ordering}{memory ordering} semantics, leaving the compiler and
++ processor to freely reorder memory accesses.
++ */
++
++ /*!
++ \fn template <typename T> T *QAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
++
++ Atomic fetch-and-add.
++
++ Reads the current value of this QAtomicPointer and then adds
++ \a valueToAdd to the current value, returning the original value.
++
++ This function uses \e acquire \l {QAtomicPointer#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access following the atomic operation (in program order) may not
++ be re-ordered before the atomic operation.
++ */
++
++ /*!
++ \fn template <typename T> T *QAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
++
++ Atomic fetch-and-add.
++
++ Reads the current value of this QAtomicPointer and then adds
++ \a valueToAdd to the current value, returning the original value.
++
++ This function uses \e release \l {QAtomicPointer#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access before the atomic operation (in program order) may not be
++ re-ordered after the atomic operation.
++ */
++
++ /*!
++ \fn template <typename T> T *QAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
++
++ Atomic fetch-and-add.
++
++ Reads the current value of this QAtomicPointer and then adds
++ \a valueToAdd to the current value, returning the original value.
++
++ This function uses \e ordered \l {QAtomicPointer#Memory
++ ordering}{memory ordering} semantics, which ensures that memory
++ access before and after the atomic operation (in program order)
++ may not be re-ordered.
++ */
++
++ /*!
++ \macro Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
++ \relates QAtomicPointer
++
++ This macro is defined if and only if your processor supports
++ atomic test-and-set on pointers.
++ */
++
++ /*!
++ \macro Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE
++ \relates QAtomicPointer
++
++ This macro is defined when only certain generations of the
++ processor support atomic test-and-set on pointers. Use the
++ QAtomicPointer::isTestAndSetNative() function to check what your
++ processor supports.
++ */
++
++ /*!
++ \macro Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
++ \relates QAtomicPointer
++
++ This macro is defined when the hardware does not support atomic
++ test-and-set on pointers.
++ */
++
++ /*!
++ \macro Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE
++ \relates QAtomicPointer
++
++ This macro is defined together with
++ Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE to indicate that
++ the atomic test-and-set on pointers is wait-free.
++ */
++
++ /*!
++ \macro Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
++ \relates QAtomicPointer
++
++ This macro is defined if and only if your processor supports
++ atomic fetch-and-store on pointers.
++ */
++
++ /*!
++ \macro Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
++ \relates QAtomicPointer
++
++ This macro is defined when only certain generations of the
++ processor support atomic fetch-and-store on pointers. Use the
++ QAtomicPointer::isFetchAndStoreNative() function to check what
++ your processor supports.
++ */
++
++ /*!
++ \macro Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE
++ \relates QAtomicPointer
++
++ This macro is defined when the hardware does not support atomic
++ fetch-and-store on pointers.
++ */
++
++ /*!
++ \macro Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE
++ \relates QAtomicPointer
++
++ This macro is defined together with
++ Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE to indicate that
++ the atomic fetch-and-store on pointers is wait-free.
++ */
++
++ /*!
++ \macro Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
++ \relates QAtomicPointer
++
++ This macro is defined if and only if your processor supports
++ atomic fetch-and-add on pointers.
++ */
++
++ /*!
++ \macro Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
++ \relates QAtomicPointer
++
++ This macro is defined when only certain generations of the
++ processor support atomic fetch-and-add on pointers. Use the
++ QAtomicPointer::isFetchAndAddNative() function to check what your
++ processor supports.
++ */
++
++ /*!
++ \macro Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE
++ \relates QAtomicPointer
++
++ This macro is defined when the hardware does not support atomic
++ fetch-and-add on pointers.
++ */
++
++ /*!
++ \macro Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_WAIT_FREE
++ \relates QAtomicPointer
++
++ This macro is defined together with
++ Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE to indicate that
++ the atomic fetch-and-add on pointers is wait-free.
++ */
++
++ // static checks
++ #ifndef Q_ATOMIC_INT8_IS_SUPPORTED
++ # error "Q_ATOMIC_INT8_IS_SUPPORTED must be defined"
++ #endif
++ #ifndef Q_ATOMIC_INT16_IS_SUPPORTED
++ # error "Q_ATOMIC_INT16_IS_SUPPORTED must be defined"
++ #endif
++ #ifndef Q_ATOMIC_INT32_IS_SUPPORTED
++ # error "Q_ATOMIC_INT32_IS_SUPPORTED must be defined"
++ #endif
++ #if !defined(Q_ATOMIC_INT64_IS_SUPPORTED) && QT_POINTER_SIZE == 8
++ // 64-bit platform
++ # error "Q_ATOMIC_INT64_IS_SUPPORTED must be defined on a 64-bit platform"
++ #endif
++
++ QT_BEGIN_NAMESPACE
++
++ // The following specializations must always be defined
++ static_assert(sizeof(QAtomicInteger<unsigned>));
++ static_assert(sizeof(QAtomicInteger<long>));
++ static_assert(sizeof(QAtomicInteger<unsigned long>));
++ static_assert(sizeof(QAtomicInteger<quintptr>));
++ static_assert(sizeof(QAtomicInteger<qptrdiff>));
++ static_assert(sizeof(QAtomicInteger<char32_t>));
++
++ static_assert(sizeof(QAtomicInteger<short>));
++ static_assert(sizeof(QAtomicInteger<unsigned short>));
++ static_assert(sizeof(QAtomicInteger<wchar_t>));
++ static_assert(sizeof(QAtomicInteger<char16_t>));
++
++ static_assert(sizeof(QAtomicInteger<char>));
++ static_assert(sizeof(QAtomicInteger<unsigned char>));
++ static_assert(sizeof(QAtomicInteger<signed char>));
++ static_assert(sizeof(QAtomicInteger<bool>));
++
++ #ifdef Q_ATOMIC_INT64_IS_SUPPORTED
++ static_assert(sizeof(QAtomicInteger<qint64>));
++ static_assert(sizeof(QAtomicInteger<quint64>));
++ #endif
++
++ QT_END_NAMESPACE