| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Copyright (C) 2016 Intel Corporation. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the QtCore module of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:LGPL$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU Lesser General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU Lesser |
| ** General Public License version 3 as published by the Free Software |
| ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
| ** packaging of this file. Please review the following information to |
| ** ensure the GNU Lesser General Public License version 3 requirements |
| ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU |
| ** General Public License version 2.0 or (at your option) the GNU General |
| ** Public license version 3 or any later version approved by the KDE Free |
| ** Qt Foundation. The licenses are as published by the Free Software |
| ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
| ** included in the packaging of this file. Please review the following |
| ** information to ensure the GNU General Public License requirements will |
| ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
| ** https://www.gnu.org/licenses/gpl-3.0.html. |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| #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 \c T must be a C++ integer type: |
| \list |
| \li 8-bit: char, signed char, unsigned char, qint8, quint8 |
| \li 16-bit: short, unsigned short, qint16, quint16, char16_t (C++11) |
| \li 32-bit: int, unsigned int, qint32, quint32, char32_t (C++11) |
| \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 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 |
| other types are supported, check the macro \c Q_ATOMIC_INT\e{nn}_IS_SUPPORTED, |
| where \c{\e{nn}} is the number of bits desired. |
| |
| \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 \a 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>::load() const |
| \obsolete |
| |
| Use loadRelaxed() instead. |
| |
| 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>::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>::store(T newValue) |
| \obsolete |
| |
| Use storeRelaxed() instead. |
| |
| Atomically stores the \a newValue value into this atomic type, using |
| relaxed memory ordering. |
| |
| \sa storeRelease(), 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 store(), 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> 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. |
| |
| 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. |
| |
| 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> bool QAtomicInteger<T>::testAndSetAcquire(T expectedValue, T newValue) |
| |
| 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 true. If the values are \e not the same, |
| this function does nothing and returns \c false. |
| |
| 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> bool QAtomicInteger<T>::testAndSetRelease(T expectedValue, T newValue) |
| |
| 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 true. If the values are \e not the same, |
| this function does nothing and returns \c false. |
| |
| 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> bool QAtomicInteger<T>::testAndSetOrdered(T expectedValue, T newValue) |
| |
| 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 true. If the values are \e not the same, |
| this function does nothing and returns \c false. |
| |
| 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>::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. |
| Q_ATOMIC_INT32_IS_SUPPORTED is always defined. |
| |
| \e{nn} is the size of the integer, in bits (8, 16, 32 or 64). |
| */ |
| |
| /*! |
| \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<T>::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<T>::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<T>::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<T>::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. |
| |
| \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 \a 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 |
| */ |
| |
| /*! |
| \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>::load() const |
| \obsolete |
| |
| Use loadRelaxed() instead. |
| |
| 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>::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>::store(T *newValue) |
| \obsolete |
| |
| Use storeRelaxed() instead. |
| |
| Atomically stores the \a newValue value into this atomic type, using |
| relaxed memory ordering. |
| |
| \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. |
| |
| 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. |
| |
| 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. |
| |
| 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. |
| |
| 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>::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_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 |
| Q_STATIC_ASSERT(sizeof(QAtomicInteger<unsigned>)); |
| Q_STATIC_ASSERT(sizeof(QAtomicInteger<long>)); |
| Q_STATIC_ASSERT(sizeof(QAtomicInteger<unsigned long>)); |
| Q_STATIC_ASSERT(sizeof(QAtomicInteger<quintptr>)); |
| Q_STATIC_ASSERT(sizeof(QAtomicInteger<qptrdiff>)); |
| #ifdef Q_COMPILER_UNICODE_STRINGS |
| Q_STATIC_ASSERT(sizeof(QAtomicInteger<char32_t>)); |
| #endif |
| |
| #ifdef Q_ATOMIC_INT16_IS_SUPPORTED |
| Q_STATIC_ASSERT(sizeof(QAtomicInteger<short>)); |
| Q_STATIC_ASSERT(sizeof(QAtomicInteger<unsigned short>)); |
| # if WCHAR_MAX < 0x10000 |
| Q_STATIC_ASSERT(sizeof(QAtomicInteger<wchar_t>)); |
| # endif |
| # ifdef Q_COMPILER_UNICODE_STRINGS |
| Q_STATIC_ASSERT(sizeof(QAtomicInteger<char16_t>)); |
| # endif |
| #endif |
| |
| #ifdef Q_ATOMIC_INT64_IS_SUPPORTED |
| Q_STATIC_ASSERT(sizeof(QAtomicInteger<qint64>)); |
| Q_STATIC_ASSERT(sizeof(QAtomicInteger<quint64>)); |
| #endif |
| |
| #if WCHAR_MAX == INT_MAX |
| Q_STATIC_ASSERT(sizeof(QAtomicInteger<wchar_t>)); |
| #endif |
| |
| QT_END_NAMESPACE |