diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2013-02-27 17:25:45 -0800 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-02-16 05:12:47 +0100 |
commit | 19c70982517e76d89bb3da931e1390a6386603da (patch) | |
tree | e316ad490dd3207cf3e2552eb6c074a66cea3285 /src/corelib/thread/qgenericatomic.h | |
parent | 634f82f1f1fda7983abf70b58e43c580b1f01df0 (diff) |
Add the rest of the non-volatile members of std::atomic to QBasicAtomic
[ChangeLog][QtCore][Atomic support]Added more operations to the atomic
classes, including operator T(), operator=(T), operator++,
operator--. For the QAtomicInteger, bit-manipulation operations are
also provided, both in operator and in fetchAndXxxYyyyyy modes.
Change-Id: I39c07be74e15e0a48f9e931f4342b182004dee1a
Reviewed-by: David Faure <david.faure@kdab.com>
Diffstat (limited to 'src/corelib/thread/qgenericatomic.h')
-rw-r--r-- | src/corelib/thread/qgenericatomic.h | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/src/corelib/thread/qgenericatomic.h b/src/corelib/thread/qgenericatomic.h index aab0cfbb45..0c66d45855 100644 --- a/src/corelib/thread/qgenericatomic.h +++ b/src/corelib/thread/qgenericatomic.h @@ -43,6 +43,7 @@ #define QGENERICATOMIC_H #include <QtCore/qglobal.h> +#include <QtCore/qtypeinfo.h> QT_BEGIN_NAMESPACE @@ -259,6 +260,138 @@ template <typename BaseClass> struct QGenericAtomicOps BaseClass::orderedMemoryFence(_q_value); return BaseClass::fetchAndAddRelaxed(_q_value, valueToAdd); } + + template <typename T> static inline always_inline + T fetchAndSubRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) Q_DECL_NOTHROW + { + // implement fetchAndSub on top of testAndSet + Q_FOREVER { + T tmp = BaseClass::load(_q_value); + if (BaseClass::testAndSetRelaxed(_q_value, tmp, T(tmp - operand))) + return tmp; + } + } + + template <typename T> static inline always_inline + T fetchAndSubAcquire(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) Q_DECL_NOTHROW + { + T tmp = BaseClass::fetchAndSubRelaxed(_q_value, operand); + BaseClass::acquireMemoryFence(_q_value); + return tmp; + } + + template <typename T> static inline always_inline + T fetchAndSubRelease(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) Q_DECL_NOTHROW + { + BaseClass::releaseMemoryFence(_q_value); + return BaseClass::fetchAndSubRelaxed(_q_value, operand); + } + + template <typename T> static inline always_inline + T fetchAndSubOrdered(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) Q_DECL_NOTHROW + { + BaseClass::orderedMemoryFence(_q_value); + return BaseClass::fetchAndSubRelaxed(_q_value, operand); + } + + template <typename T> static inline always_inline + T fetchAndAndRelaxed(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW + { + // implement fetchAndAnd on top of testAndSet + Q_FOREVER { + T tmp = BaseClass::load(_q_value); + if (BaseClass::testAndSetRelaxed(_q_value, tmp, T(tmp & operand))) + return tmp; + } + } + + template <typename T> static inline always_inline + T fetchAndAndAcquire(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW + { + T tmp = BaseClass::fetchAndAndRelaxed(_q_value, operand); + BaseClass::acquireMemoryFence(_q_value); + return tmp; + } + + template <typename T> static inline always_inline + T fetchAndAndRelease(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW + { + BaseClass::releaseMemoryFence(_q_value); + return BaseClass::fetchAndAndRelaxed(_q_value, operand); + } + + template <typename T> static inline always_inline + T fetchAndAndOrdered(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW + { + BaseClass::orderedMemoryFence(_q_value); + return BaseClass::fetchAndAndRelaxed(_q_value, operand); + } + + template <typename T> static inline always_inline + T fetchAndOrRelaxed(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW + { + // implement fetchAndOr on top of testAndSet + Q_FOREVER { + T tmp = BaseClass::load(_q_value); + if (BaseClass::testAndSetRelaxed(_q_value, tmp, T(tmp | operand))) + return tmp; + } + } + + template <typename T> static inline always_inline + T fetchAndOrAcquire(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW + { + T tmp = BaseClass::fetchAndOrRelaxed(_q_value, operand); + BaseClass::acquireMemoryFence(_q_value); + return tmp; + } + + template <typename T> static inline always_inline + T fetchAndOrRelease(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW + { + BaseClass::releaseMemoryFence(_q_value); + return BaseClass::fetchAndOrRelaxed(_q_value, operand); + } + + template <typename T> static inline always_inline + T fetchAndOrOrdered(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW + { + BaseClass::orderedMemoryFence(_q_value); + return BaseClass::fetchAndOrRelaxed(_q_value, operand); + } + + template <typename T> static inline always_inline + T fetchAndXorRelaxed(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW + { + // implement fetchAndXor on top of testAndSet + Q_FOREVER { + T tmp = BaseClass::load(_q_value); + if (BaseClass::testAndSetRelaxed(_q_value, tmp, T(tmp ^ operand))) + return tmp; + } + } + + template <typename T> static inline always_inline + T fetchAndXorAcquire(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW + { + T tmp = BaseClass::fetchAndXorRelaxed(_q_value, operand); + BaseClass::acquireMemoryFence(_q_value); + return tmp; + } + + template <typename T> static inline always_inline + T fetchAndXorRelease(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW + { + BaseClass::releaseMemoryFence(_q_value); + return BaseClass::fetchAndXorRelaxed(_q_value, operand); + } + + template <typename T> static inline always_inline + T fetchAndXorOrdered(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW + { + BaseClass::orderedMemoryFence(_q_value); + return BaseClass::fetchAndXorRelaxed(_q_value, operand); + } }; #undef always_inline |