summaryrefslogtreecommitdiff
path: root/src/corelib/thread/qatomic.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/thread/qatomic.cpp')
-rw-r--r--src/corelib/thread/qatomic.cpp1127
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.
+*/