diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2015-01-15 15:16:53 -0800 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2015-03-05 00:05:00 +0000 |
commit | 212285639d748c7def8648f89b8c1c21c5f481e6 (patch) | |
tree | e283c0e0e99fb5aee81a2364f4ed00478bc26b36 /src/corelib | |
parent | 126d489f7f561bc3967ee2a36624c3b1fa26f974 (diff) |
Add missing fetchAndXxx methods to atomic classes based on std::atomic
And add tests for the GCC intrinsics and for std::atomic.
Task-number: QTBUG-43794
Change-Id: Ic5d393bfd36e48a193fcffff13b9b2dbaee80469
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/arch/qatomic_cxx11.h | 96 | ||||
-rw-r--r-- | src/corelib/thread/qbasicatomic.h | 8 |
2 files changed, 104 insertions, 0 deletions
diff --git a/src/corelib/arch/qatomic_cxx11.h b/src/corelib/arch/qatomic_cxx11.h index a58c8ab72e..09e900f4ea 100644 --- a/src/corelib/arch/qatomic_cxx11.h +++ b/src/corelib/arch/qatomic_cxx11.h @@ -230,6 +230,102 @@ template <typename X> struct QAtomicOps { return _q_value.fetch_add(valueToAdd, std::memory_order_acq_rel); } + + template <typename T> static inline + T fetchAndSubRelaxed(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_sub(valueToAdd, std::memory_order_relaxed); + } + + template <typename T> static inline + T fetchAndSubAcquire(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_sub(valueToAdd, std::memory_order_acquire); + } + + template <typename T> static inline + T fetchAndSubRelease(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_sub(valueToAdd, std::memory_order_release); + } + + template <typename T> static inline + T fetchAndSubOrdered(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_sub(valueToAdd, std::memory_order_acq_rel); + } + + template <typename T> static inline + T fetchAndAndRelaxed(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_and(valueToAdd, std::memory_order_relaxed); + } + + template <typename T> static inline + T fetchAndAndAcquire(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_and(valueToAdd, std::memory_order_acquire); + } + + template <typename T> static inline + T fetchAndAndRelease(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_and(valueToAdd, std::memory_order_release); + } + + template <typename T> static inline + T fetchAndAndOrdered(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_and(valueToAdd, std::memory_order_acq_rel); + } + + template <typename T> static inline + T fetchAndOrRelaxed(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_or(valueToAdd, std::memory_order_relaxed); + } + + template <typename T> static inline + T fetchAndOrAcquire(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_or(valueToAdd, std::memory_order_acquire); + } + + template <typename T> static inline + T fetchAndOrRelease(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_or(valueToAdd, std::memory_order_release); + } + + template <typename T> static inline + T fetchAndOrOrdered(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_or(valueToAdd, std::memory_order_acq_rel); + } + + template <typename T> static inline + T fetchAndXorRelaxed(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_xor(valueToAdd, std::memory_order_relaxed); + } + + template <typename T> static inline + T fetchAndXorAcquire(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_xor(valueToAdd, std::memory_order_acquire); + } + + template <typename T> static inline + T fetchAndXorRelease(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_xor(valueToAdd, std::memory_order_release); + } + + template <typename T> static inline + T fetchAndXorOrdered(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_xor(valueToAdd, std::memory_order_acq_rel); + } }; #ifdef ATOMIC_VAR_INIT diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h index 16a27862c2..ecf39d699f 100644 --- a/src/corelib/thread/qbasicatomic.h +++ b/src/corelib/thread/qbasicatomic.h @@ -39,6 +39,14 @@ #if defined(QT_BOOTSTRAPPED) # include <QtCore/qatomic_bootstrap.h> +// The following two are used for testing only. +// Note that we don't check the compiler support -- you had better +// know what you're doing if you set them +#elif defined(QT_ATOMIC_FORCE_CXX11) +# include <QtCore/qatomic_cxx11.h> +#elif defined(QT_ATOMIC_FORCE_GCC) +# include <QtCore/qatomic_gcc.h> + // Compiler dependent implementation #elif defined(Q_CC_MSVC) # include <QtCore/qatomic_msvc.h> |