diff options
Diffstat (limited to 'src/corelib/thread/qatomic.cpp')
-rw-r--r-- | src/corelib/thread/qatomic.cpp | 1127 |
1 files changed, 1127 insertions, 0 deletions
diff --git a/src/corelib/thread/qatomic.cpp b/src/corelib/thread/qatomic.cpp new file mode 100644 index 0000000000..f426feb22d --- /dev/null +++ b/src/corelib/thread/qatomic.cpp @@ -0,0 +1,1127 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \class QAtomicInt + \brief The QAtomicInt class provides platform-independent atomic operations on integers. + \since 4.4 + + \ingroup thread + + For atomic operations on pointers, see the QAtomicPointer class. + + An complex operation that completes without interruption is said + to be \e atomic. The QAtomicInt class provides atomic reference + counting, test-and-set, fetch-and-store, and fetch-and-add for + integers. + + \section1 Non-atomic convenience operators + + For convenience, QAtomicInt provides integer comparison, cast, and + assignment operators. Note that a combination of these operators + is \e not an atomic operation. + + \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 doc/src/snippets/code/src_corelib_thread_qatomic.cpp 0 + + \section2 Memory ordering + + QAtomicInt 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 + + \o Relaxed - memory ordering is unspecified, leaving the compiler + and processor to freely reorder memory accesses. + + \o Acquire - memory access following the atomic operation (in + program order) may not be re-ordered before the atomic operation. + + \o Release - memory access before the atomic operation (in program + order) may not be re-ordered after the atomic operation. + + \o Ordered - the same Acquire and Release semantics combined. + + \endlist + + \section2 Test-and-set + + If the current value of the QAtomicInt is an expected value, the + test-and-set functions assign a new value to the QAtomicInt 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 doc/src/snippets/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 + QAtomicInt and then assign a new value, returning the original + value. This operation equates to the following code: + + \snippet doc/src/snippets/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 + QAtomicInt and then add the given value to the current value, + returning the original value. This operation equates to the + following code: + + \snippet doc/src/snippets/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 QAtomicInt is + guaranteed to work atomically on all processors. However, since + not all processors implement support for every operation provided + by QAtomicInt, 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{OPERATION}_IS_\e{HOW}_NATIVE. \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_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE is defined, + neither Q_ATOMIC_INT_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE nor + Q_ATOMIC_INT_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{OPERATION}_IS_WAIT_FREE in addition to the + Q_ATOMIC_INT_\e{OPERATION}_IS_ALWAYS_NATIVE. + + In cases where an atomic operation is only supported in newer + generations of the processor, QAtomicInt 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 QAtomicInt: + + \list + + \o Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE + \o Q_ATOMIC_INT_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE + \o Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE + \o Q_ATOMIC_INT_REFERENCE_COUNTING_IS_WAIT_FREE + + \o Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE + \o Q_ATOMIC_INT_TEST_AND_SET_IS_SOMETIMES_NATIVE + \o Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE + \o Q_ATOMIC_INT_TEST_AND_SET_IS_WAIT_FREE + + \o Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE + \o Q_ATOMIC_INT_FETCH_AND_STORE_IS_SOMETIMES_NATIVE + \o Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE + \o Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE + + \o Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE + \o Q_ATOMIC_INT_FETCH_AND_ADD_IS_SOMETIMES_NATIVE + \o Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE + \o Q_ATOMIC_INT_FETCH_AND_ADD_IS_WAIT_FREE + + \endlist + + \sa QAtomicPointer +*/ + +/*! \fn QAtomicInt::QAtomicInt(int value) + + Constructs a QAtomicInt with the given \a value. +*/ + +/*! \fn QAtomicInt::QAtomicInt(const QAtomicInt &other) + + Constructs a copy of \a other. +*/ + +/*! \fn QAtomicInt &QAtomicInt::operator=(int value) + + Assigns the \a value to this QAtomicInt and returns a reference to + this QAtomicInt. +*/ + +/*! \fn QAtomicInt &QAtomicInt::operator=(const QAtomicInt &other) + + Assigns \a other to this QAtomicInt and returns a reference to + this QAtomicInt. +*/ + +/*! \fn bool QAtomicInt::operator==(int value) const + + Returns true if the \a value is equal to the value in this + QAtomicInt; otherwise returns false. +*/ + +/*! \fn bool QAtomicInt::operator!=(int value) const + + Returns true if the value of this QAtomicInt is not equal to \a + value; otherwise returns false. +*/ + +/*! \fn bool QAtomicInt::operator!() const + + Returns true is the value of this QAtomicInt is zero; otherwise + returns false. +*/ + +/*! \fn QAtomicInt::operator int() const + + Returns the value stored by the QAtomicInt object as an integer. +*/ + +/*! \fn bool QAtomicInt::isReferenceCountingNative() + + Returns true if reference counting is implemented using atomic + processor instructions, false otherwise. +*/ + +/*! \fn bool QAtomicInt::isReferenceCountingWaitFree() + + Returns true if atomic reference counting is wait-free, false + otherwise. +*/ + +/*! \fn bool QAtomicInt::ref() + Atomically increments the value of this QAtomicInt. Returns true + if the new value is non-zero, false otherwise. + + This function uses \e ordered \l {QAtomicInt#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() +*/ + +/*! \fn bool QAtomicInt::deref() + Atomically decrements the value of this QAtomicInt. Returns true + if the new value is non-zero, false otherwise. + + This function uses \e ordered \l {QAtomicInt#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() +*/ + +/*! \fn bool QAtomicInt::isTestAndSetNative() + + Returns true if test-and-set is implemented using atomic processor + instructions, false otherwise. +*/ + +/*! \fn bool QAtomicInt::isTestAndSetWaitFree() + + Returns true if atomic test-and-set is wait-free, false otherwise. +*/ + +/*! \fn bool QAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) + + Atomic test-and-set. + + If the current value of this QAtomicInt is the \a expectedValue, + the test-and-set functions assign the \a newValue to this + QAtomicInt and return true. If the values are \e not the same, + this function does nothing and returns false. + + This function uses \e relaxed \l {QAtomicInt#Memory + ordering}{memory ordering} semantics, leaving the compiler and + processor to freely reorder memory accesses. +*/ + +/*! \fn bool QAtomicInt::testAndSetAcquire(int expectedValue, int newValue) + + Atomic test-and-set. + + If the current value of this QAtomicInt is the \a expectedValue, + the test-and-set functions assign the \a newValue to this + QAtomicInt and return true. If the values are \e not the same, + this function does nothing and returns false. + + This function uses \e acquire \l {QAtomicInt#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 bool QAtomicInt::testAndSetRelease(int expectedValue, int newValue) + + Atomic test-and-set. + + If the current value of this QAtomicInt is the \a expectedValue, + the test-and-set functions assign the \a newValue to this + QAtomicInt and return true. If the values are \e not the same, + this function does nothing and returns false. + + This function uses \e release \l {QAtomicInt#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 bool QAtomicInt::testAndSetOrdered(int expectedValue, int newValue) + + Atomic test-and-set. + + If the current value of this QAtomicInt is the \a expectedValue, + the test-and-set functions assign the \a newValue to this + QAtomicInt and return true. If the values are \e not the same, + this function does nothing and returns false. + + This function uses \e ordered \l {QAtomicInt#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 bool QAtomicInt::isFetchAndStoreNative() + + Returns true if fetch-and-store is implemented using atomic + processor instructions, false otherwise. +*/ + +/*! \fn bool QAtomicInt::isFetchAndStoreWaitFree() + + Returns true if atomic fetch-and-store is wait-free, false + otherwise. +*/ + +/*! \fn int QAtomicInt::fetchAndStoreRelaxed(int newValue) + + Atomic fetch-and-store. + + Reads the current value of this QAtomicInt and then assigns it the + \a newValue, returning the original value. + + This function uses \e relaxed \l {QAtomicInt#Memory + ordering}{memory ordering} semantics, leaving the compiler and + processor to freely reorder memory accesses. +*/ + +/*! \fn int QAtomicInt::fetchAndStoreAcquire(int newValue) + + Atomic fetch-and-store. + + Reads the current value of this QAtomicInt and then assigns it the + \a newValue, returning the original value. + + This function uses \e acquire \l {QAtomicInt#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 int QAtomicInt::fetchAndStoreRelease(int newValue) + + Atomic fetch-and-store. + + Reads the current value of this QAtomicInt and then assigns it the + \a newValue, returning the original value. + + This function uses \e release \l {QAtomicInt#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 int QAtomicInt::fetchAndStoreOrdered(int newValue) + + Atomic fetch-and-store. + + Reads the current value of this QAtomicInt and then assigns it the + \a newValue, returning the original value. + + This function uses \e ordered \l {QAtomicInt#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 bool QAtomicInt::isFetchAndAddNative() + + Returns true if fetch-and-add is implemented using atomic + processor instructions, false otherwise. +*/ + +/*! \fn bool QAtomicInt::isFetchAndAddWaitFree() + + Returns true if atomic fetch-and-add is wait-free, false + otherwise. +*/ + +/*! \fn int QAtomicInt::fetchAndAddRelaxed(int valueToAdd) + + Atomic fetch-and-add. + + Reads the current value of this QAtomicInt and then adds + \a valueToAdd to the current value, returning the original value. + + This function uses \e relaxed \l {QAtomicInt#Memory + ordering}{memory ordering} semantics, leaving the compiler and + processor to freely reorder memory accesses. +*/ + +/*! \fn int QAtomicInt::fetchAndAddAcquire(int valueToAdd) + + Atomic fetch-and-add. + + Reads the current value of this QAtomicInt and then adds + \a valueToAdd to the current value, returning the original value. + + This function uses \e acquire \l {QAtomicInt#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 int QAtomicInt::fetchAndAddRelease(int valueToAdd) + + Atomic fetch-and-add. + + Reads the current value of this QAtomicInt and then adds + \a valueToAdd to the current value, returning the original value. + + This function uses \e release \l {QAtomicInt#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 int QAtomicInt::fetchAndAddOrdered(int valueToAdd) + + Atomic fetch-and-add. + + Reads the current value of this QAtomicInt and then adds + \a valueToAdd to the current value, returning the original value. + + This function uses \e ordered \l {QAtomicInt#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_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE + \relates QAtomicInt + + This macro is defined if and only if all generations of your + processor support atomic reference counting. +*/ + +/*! + \macro Q_ATOMIC_INT_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE + \relates QAtomicInt + + This macro is defined when only certain generations of the + processor support atomic reference counting. Use the + QAtomicInt::isReferenceCountingNative() function to check what + your processor supports. +*/ + +/*! + \macro Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE + \relates QAtomicInt + + This macro is defined when the hardware does not support atomic + reference counting. +*/ + +/*! + \macro Q_ATOMIC_INT_REFERENCE_COUNTING_IS_WAIT_FREE + \relates QAtomicInt + + This macro is defined together with + Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE to indicate that + the reference counting is wait-free. +*/ + +/*! + \macro Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE + \relates QAtomicInt + + This macro is defined if and only if your processor supports + atomic test-and-set on integers. +*/ + +/*! + \macro Q_ATOMIC_INT_TEST_AND_SET_IS_SOMETIMES_NATIVE + \relates QAtomicInt + + This macro is defined when only certain generations of the + processor support atomic test-and-set on integers. Use the + QAtomicInt::isTestAndSetNative() function to check what your + processor supports. +*/ + +/*! + \macro Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE + \relates QAtomicInt + + This macro is defined when the hardware does not support atomic + test-and-set on integers. +*/ + +/*! + \macro Q_ATOMIC_INT_TEST_AND_SET_IS_WAIT_FREE + \relates QAtomicInt + + This macro is defined together with + Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE to indicate that the + atomic test-and-set on integers is wait-free. +*/ + +/*! + \macro Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE + \relates QAtomicInt + + This macro is defined if and only if your processor supports + atomic fetch-and-store on integers. +*/ + +/*! + \macro Q_ATOMIC_INT_FETCH_AND_STORE_IS_SOMETIMES_NATIVE + \relates QAtomicInt + + This macro is defined when only certain generations of the + processor support atomic fetch-and-store on integers. Use the + QAtomicInt::isFetchAndStoreNative() function to check what your + processor supports. +*/ + +/*! + \macro Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE + \relates QAtomicInt + + This macro is defined when the hardware does not support atomic + fetch-and-store on integers. +*/ + +/*! + \macro Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE + \relates QAtomicInt + + This macro is defined together with + Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE to indicate that the + atomic fetch-and-store on integers is wait-free. +*/ + +/*! + \macro Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE + \relates QAtomicInt + + This macro is defined if and only if your processor supports + atomic fetch-and-add on integers. +*/ + +/*! + \macro Q_ATOMIC_INT_FETCH_AND_ADD_IS_SOMETIMES_NATIVE + \relates QAtomicInt + + This macro is defined when only certain generations of the + processor support atomic fetch-and-add on integers. Use the + QAtomicInt::isFetchAndAddNative() function to check what your + processor supports. +*/ + +/*! + \macro Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE + \relates QAtomicInt + + This macro is defined when the hardware does not support atomic + fetch-and-add on integers. +*/ + +/*! + \macro Q_ATOMIC_INT_FETCH_AND_ADD_IS_WAIT_FREE + \relates QAtomicInt + + This macro is defined together with + Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE to indicate that the + atomic fetch-and-add on integers is wait-free. +*/ + + + + +/*! + \class QAtomicPointer + \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 QAtomicInt class. + + An complex operation that completes without interruption is said + to be \e atomic. The QAtomicPointer class provides atomic + test-and-set, fetch-and-store, and fetch-and-add for pointers. + + \section1 Non-atomic convenience operators + + For convenience, QAtomicPointer provides pointer comparison, cast, + dereference, and assignment operators. Note that these operators + are \e not atomic. + + \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 + + \o Relaxed - memory ordering is unspecified, leaving the compiler + and processor to freely reorder memory accesses. + + \o Acquire - memory access following the atomic operation (in + program order) may not be re-ordered before the atomic operation. + + \o Release - memory access before the atomic operation (in program + order) may not be re-ordered after the atomic operation. + + \o 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 doc/src/snippets/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 doc/src/snippets/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 doc/src/snippets/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 + + \o Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE + \o Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE + \o Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE + \o Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE + + \o Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE + \o Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE + \o Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE + \o Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE + + \o Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE + \o Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE + \o Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE + \o Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_WAIT_FREE + + \endlist + + \sa QAtomicInt +*/ + +/*! \fn QAtomicPointer::QAtomicPointer(T *value) + + Constructs a QAtomicPointer with the given \a value. +*/ + +/*! \fn QAtomicPointer::QAtomicPointer(const QAtomicPointer<T> &other) + + Constructs a copy of \a other. +*/ + +/*! \fn QAtomicPointer<T> &QAtomicPointer::operator=(T *value) + + Assigns the \a value to this QAtomicPointer and returns a + reference to this QAtomicPointer. +*/ + +/*! \fn QAtomicPointer<T> &QAtomicPointer::operator=(const QAtomicPointer<T> &other) + + Assigns \a other to this QAtomicPointer and returns a reference to + this QAtomicPointer. +*/ + +/*! \fn bool QAtomicPointer::operator==(T *value) const + + Returns true if the \a value is equal to the value in this + QAtomicPointer; otherwise returns false. +*/ + +/*! \fn bool QAtomicPointer::operator!=(T *value) const + + Returns true if the value of this QAtomicPointer is not equal to + \a value; otherwise returns false. +*/ + +/*! \fn bool QAtomicPointer::operator!() const + + Returns true is the current value of this QAtomicPointer is zero; + otherwise returns false. +*/ + +/*! \fn QAtomicPointer::operator T *() const + + Returns the current pointer value stored by this QAtomicPointer + object. +*/ + +/*! \fn T *QAtomicPointer::operator->() const + +*/ + +/*! \fn bool QAtomicPointer::isTestAndSetNative() + + Returns true if test-and-set is implemented using atomic processor + instructions, false otherwise. +*/ + +/*! \fn bool QAtomicPointer::isTestAndSetWaitFree() + + Returns true if atomic test-and-set is wait-free, false otherwise. +*/ + +/*! \fn bool QAtomicPointer::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 false. + + This function uses \e relaxed \l {QAtomicPointer#Memory + ordering}{memory ordering} semantics, leaving the compiler and + processor to freely reorder memory accesses. +*/ + +/*! \fn bool QAtomicPointer::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 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 bool QAtomicPointer::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 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 bool QAtomicPointer::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 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 bool QAtomicPointer::isFetchAndStoreNative() + + Returns true if fetch-and-store is implemented using atomic + processor instructions, false otherwise. +*/ + +/*! \fn bool QAtomicPointer::isFetchAndStoreWaitFree() + + Returns true if atomic fetch-and-store is wait-free, false + otherwise. +*/ + +/*! \fn T *QAtomicPointer::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 T *QAtomicPointer::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 T *QAtomicPointer::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 T *QAtomicPointer::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 bool QAtomicPointer::isFetchAndAddNative() + + Returns true if fetch-and-add is implemented using atomic + processor instructions, false otherwise. +*/ + +/*! \fn bool QAtomicPointer::isFetchAndAddWaitFree() + + Returns true if atomic fetch-and-add is wait-free, false + otherwise. +*/ + +/*! \fn T *QAtomicPointer::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 T *QAtomicPointer::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 T *QAtomicPointer::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 T *QAtomicPointer::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. +*/ |