diff options
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/arch/qatomic_windows.h | 317 | ||||
-rw-r--r-- | src/corelib/thread/qbasicatomic.h | 5 | ||||
-rw-r--r-- | src/corelib/thread/qgenericatomic.h | 40 |
3 files changed, 125 insertions, 237 deletions
diff --git a/src/corelib/arch/qatomic_windows.h b/src/corelib/arch/qatomic_windows.h index 5a8547fb05..caac54b0e4 100644 --- a/src/corelib/arch/qatomic_windows.h +++ b/src/corelib/arch/qatomic_windows.h @@ -42,17 +42,16 @@ #ifndef QATOMIC_WINDOWS_H #define QATOMIC_WINDOWS_H -#ifndef Q_CC_MSVC +#ifdef Q_CC_MSVC -// Mingw and other GCC platforms get inline assembly +#include <QtCore/qgenericatomic.h> -# ifdef __i386__ -# include "QtCore/qatomic_i386.h" -# else -# include "QtCore/qatomic_x86_64.h" -# endif +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE -#else // Q_CC_MSVC +#if 0 +#pragma qt_sync_stop_processing +#endif //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -74,7 +73,7 @@ # include <winbase.h> // It's safer to remove the volatile and let the compiler add it as needed. -# define QT_INTERLOCKED_NO_VOLATILE +# define QT_INTERLOCKED_VOLATILE # else // _WIN32_WCE >= 0x600 || !_X86_ @@ -87,7 +86,7 @@ # define QT_INTERLOCKED_INTRINSIC # endif # else -# define QT_INTERLOCKED_NO_VOLATILE +# define QT_INTERLOCKED_VOLATILE # endif # endif // _WIN32_WCE >= 0x600 || !_X86_ @@ -111,12 +110,8 @@ QT_INTERLOCKED_CONCAT( \ QT_INTERLOCKED_CONCAT(QT_INTERLOCKED_PREFIX, Interlocked), name) -#ifdef QT_INTERLOCKED_NO_VOLATILE -# define QT_INTERLOCKED_VOLATILE -# define QT_INTERLOCKED_REMOVE_VOLATILE(a) qt_interlocked_remove_volatile(a) -#else +#ifndef QT_INTERLOCKED_VOLATILE # define QT_INTERLOCKED_VOLATILE volatile -# define QT_INTERLOCKED_REMOVE_VOLATILE(a) a #endif #ifndef QT_INTERLOCKED_PREFIX @@ -173,297 +168,194 @@ extern "C" { // Interlocked* replacement macros #define QT_INTERLOCKED_INCREMENT(value) \ - QT_INTERLOCKED_FUNCTION( Increment )( \ - QT_INTERLOCKED_REMOVE_VOLATILE( value ) ) + QT_INTERLOCKED_FUNCTION(Increment)(value) #define QT_INTERLOCKED_DECREMENT(value) \ - QT_INTERLOCKED_FUNCTION( Decrement )( \ - QT_INTERLOCKED_REMOVE_VOLATILE( value ) ) + QT_INTERLOCKED_FUNCTION(Decrement)(value) #define QT_INTERLOCKED_COMPARE_EXCHANGE(value, newValue, expectedValue) \ - QT_INTERLOCKED_FUNCTION( CompareExchange )( \ - QT_INTERLOCKED_REMOVE_VOLATILE( value ), \ - newValue, \ - expectedValue ) + QT_INTERLOCKED_FUNCTION(CompareExchange)((value), (newValue), (expectedValue)) #define QT_INTERLOCKED_EXCHANGE(value, newValue) \ - QT_INTERLOCKED_FUNCTION( Exchange )( \ - QT_INTERLOCKED_REMOVE_VOLATILE( value ), \ - newValue ) + QT_INTERLOCKED_FUNCTION(Exchange)((value), (newValue)) #define QT_INTERLOCKED_EXCHANGE_ADD(value, valueToAdd) \ - QT_INTERLOCKED_FUNCTION( ExchangeAdd )( \ - QT_INTERLOCKED_REMOVE_VOLATILE( value ), \ - valueToAdd ) + QT_INTERLOCKED_FUNCTION(ExchangeAdd)((value), (valueToAdd)) #if defined(Q_OS_WINCE) || defined(__i386__) || defined(_M_IX86) # define QT_INTERLOCKED_COMPARE_EXCHANGE_POINTER(value, newValue, expectedValue) \ reinterpret_cast<void *>( \ - QT_INTERLOCKED_FUNCTION( CompareExchange )( \ - QT_INTERLOCKED_REMOVE_VOLATILE( value ## _integral ), \ - (long)( newValue ), \ - (long)( expectedValue ) )) + QT_INTERLOCKED_FUNCTION(CompareExchange)( \ + reinterpret_cast<long QT_INTERLOCKED_VOLATILE *>(value), \ + long(newValue), \ + long(expectedValue))) # define QT_INTERLOCKED_EXCHANGE_POINTER(value, newValue) \ - QT_INTERLOCKED_FUNCTION( Exchange )( \ - QT_INTERLOCKED_REMOVE_VOLATILE( value ## _integral ), \ - (quintptr)( newValue ) ) + QT_INTERLOCKED_FUNCTION(Exchange)( \ + reinterpret_cast<long QT_INTERLOCKED_VOLATILE *>(value), \ + long(newValue)) # define QT_INTERLOCKED_EXCHANGE_ADD_POINTER(value, valueToAdd) \ - QT_INTERLOCKED_FUNCTION( ExchangeAdd )( \ - QT_INTERLOCKED_REMOVE_VOLATILE( value ## _integral ), \ - valueToAdd ) + QT_INTERLOCKED_FUNCTION(ExchangeAdd)( \ + reinterpret_cast<long QT_INTERLOCKED_VOLATILE *>(value), \ + (valueToAdd)) #else // !defined(Q_OS_WINCE) && !defined(__i386__) && !defined(_M_IX86) # define QT_INTERLOCKED_COMPARE_EXCHANGE_POINTER(value, newValue, expectedValue) \ - QT_INTERLOCKED_FUNCTION( CompareExchangePointer )( \ - (void * QT_INTERLOCKED_VOLATILE *)( QT_INTERLOCKED_REMOVE_VOLATILE(value) ), \ - newValue, \ - expectedValue ) + QT_INTERLOCKED_FUNCTION(CompareExchangePointer)( \ + (void * QT_INTERLOCKED_VOLATILE *)(value), \ + (void *) (newValue), \ + (void *) (expectedValue)) # define QT_INTERLOCKED_EXCHANGE_POINTER(value, newValue) \ - QT_INTERLOCKED_FUNCTION( ExchangePointer )( \ - (void * QT_INTERLOCKED_VOLATILE *)( QT_INTERLOCKED_REMOVE_VOLATILE(value) ), \ - newValue ) + QT_INTERLOCKED_FUNCTION(ExchangePointer)( \ + (void * QT_INTERLOCKED_VOLATILE *)(value), \ + (void *) (newValue)) # define QT_INTERLOCKED_EXCHANGE_ADD_POINTER(value, valueToAdd) \ - QT_INTERLOCKED_FUNCTION( ExchangeAdd64 )( \ - QT_INTERLOCKED_REMOVE_VOLATILE( value ## _integral ), \ - valueToAdd ) + QT_INTERLOCKED_FUNCTION(ExchangeAdd64)( \ + reinterpret_cast<qint64 QT_INTERLOCKED_VOLATILE *>(value), \ + (valueToAdd)) #endif // !defined(Q_OS_WINCE) && !defined(__i386__) && !defined(_M_IX86) //////////////////////////////////////////////////////////////////////////////////////////////////// -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - #define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE #define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_WAIT_FREE -inline bool QBasicAtomicInt::isReferenceCountingNative() -{ return true; } -inline bool QBasicAtomicInt::isReferenceCountingWaitFree() -{ return true; } - #define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE #define Q_ATOMIC_INT_TEST_AND_SET_IS_WAIT_FREE -inline bool QBasicAtomicInt::isTestAndSetNative() -{ return true; } -inline bool QBasicAtomicInt::isTestAndSetWaitFree() -{ return true; } - #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE -inline bool QBasicAtomicInt::isFetchAndStoreNative() -{ return true; } -inline bool QBasicAtomicInt::isFetchAndStoreWaitFree() -{ return true; } - #define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE #define Q_ATOMIC_INT_FETCH_AND_ADD_IS_WAIT_FREE -inline bool QBasicAtomicInt::isFetchAndAddNative() -{ return true; } -inline bool QBasicAtomicInt::isFetchAndAddWaitFree() -{ return true; } +#define Q_ATOMIC_INT32_IS_SUPPORTED + +#define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_WAIT_FREE + +#define Q_ATOMIC_INT32_TEST_AND_SET_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT32_TEST_AND_SET_IS_WAIT_FREE + +#define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_WAIT_FREE + +#define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_WAIT_FREE #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree() -{ return true; } - #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree() -{ return true; } - #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_WAIT_FREE -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree() -{ return true; } - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -#ifdef QT_INTERLOCKED_NO_VOLATILE -template <class T> -Q_INLINE_TEMPLATE T *qt_interlocked_remove_volatile(T volatile *t) -{ - return const_cast<T *>(t); -} -#endif // !QT_INTERLOCKED_NO_VOLATILE //////////////////////////////////////////////////////////////////////////////////////////////////// -inline bool QBasicAtomicInt::ref() -{ - return QT_INTERLOCKED_INCREMENT(&_q_value) != 0; -} - -inline bool QBasicAtomicInt::deref() -{ - return QT_INTERLOCKED_DECREMENT(&_q_value) != 0; -} +template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned int> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<long> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned long> { enum { IsInteger = 1 }; }; -inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) -{ - return QT_INTERLOCKED_COMPARE_EXCHANGE(&_q_value, newValue, expectedValue) - == expectedValue; -} +// No definition, needs specialization +template <int N> struct QAtomicOpsBySize; -inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) +template <> +struct QAtomicOpsBySize<4> : QGenericAtomicOps<QAtomicOpsBySize<4> > { - return QT_INTERLOCKED_EXCHANGE(&_q_value, newValue); -} + // The 32-bit Interlocked*() API takes paramters as longs. + typedef long Type; -inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) -{ - return QT_INTERLOCKED_EXCHANGE_ADD(&_q_value, valueToAdd); -} + static inline bool isReferenceCountingNative() { return true; } + static inline bool isReferenceCountingWaitFree() { return true; } + static bool ref(long &_q_value); + static bool deref(long &_q_value); -//////////////////////////////////////////////////////////////////////////////////////////////////// + static inline bool isTestAndSetNative() { return true; } + static inline bool isTestAndSetWaitFree() { return true; } + static bool testAndSetRelaxed(long &_q_value, long expectedValue, long newValue); -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue) -{ - return QT_INTERLOCKED_COMPARE_EXCHANGE_POINTER(&_q_value, (void*)newValue, (void*)expectedValue) - == expectedValue; -} + static inline bool isFetchAndStoreNative() { return true; } + static inline bool isFetchAndStoreWaitFree() { return true; } + static long fetchAndStoreRelaxed(long &_q_value, long newValue); -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T* newValue) -{ - return reinterpret_cast<T *>( - QT_INTERLOCKED_EXCHANGE_POINTER(&_q_value, (void*)newValue)); -} + static inline bool isFetchAndAddNative() { return true; } + static inline bool isFetchAndAddWaitFree() { return true; } + static long fetchAndAddRelaxed(long &_q_value, QAtomicAdditiveType<long>::AdditiveT valueToAdd); +}; template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd) -{ - return reinterpret_cast<T *>( - QT_INTERLOCKED_EXCHANGE_ADD_POINTER(&_q_value, valueToAdd * sizeof(T))); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) -{ - return fetchAndStoreOrdered(newValue); -} +struct QAtomicOps : QAtomicOpsBySize<sizeof(T)> +{ }; -inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue) +inline bool QAtomicOpsBySize<4>::ref(long &_q_value) { - return fetchAndStoreOrdered(newValue); + return QT_INTERLOCKED_INCREMENT(&_q_value) != 0; } -inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) +inline bool QAtomicOpsBySize<4>::deref(long &_q_value) { - return fetchAndAddOrdered(valueToAdd); + return QT_INTERLOCKED_DECREMENT(&_q_value) != 0; } -inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) +inline bool QAtomicOpsBySize<4>::testAndSetRelaxed(long &_q_value, long expectedValue, long newValue) { - return fetchAndAddOrdered(valueToAdd); + return QT_INTERLOCKED_COMPARE_EXCHANGE(&_q_value, newValue, expectedValue) == expectedValue; } -inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) +inline long QAtomicOpsBySize<4>::fetchAndStoreRelaxed(long &_q_value, long newValue) { - return fetchAndAddOrdered(valueToAdd); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); + return QT_INTERLOCKED_EXCHANGE(&_q_value, newValue); } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue) +inline long QAtomicOpsBySize<4>::fetchAndAddRelaxed(long &_q_value, QAtomicAdditiveType<long>::AdditiveT valueToAdd) { - return testAndSetOrdered(expectedValue, newValue); + return QT_INTERLOCKED_EXCHANGE_ADD(&_q_value, valueToAdd * QAtomicAdditiveType<long>::AddScale); } +// Specialization for pointer types, since we have Interlocked*Pointer() variants in some configurations template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue) +struct QAtomicOps<T *> : QGenericAtomicOps<QAtomicOps<T *> > { - return testAndSetOrdered(expectedValue, newValue); -} + typedef T *Type; -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} + static inline bool isTestAndSetNative() { return true; } + static inline bool isTestAndSetWaitFree() { return true; } + static bool testAndSetRelaxed(T *&_q_value, T *expectedValue, T *newValue); -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} + static inline bool isFetchAndStoreNative() { return true; } + static inline bool isFetchAndStoreWaitFree() { return true; } + static T *fetchAndStoreRelaxed(T *&_q_value, T *newValue); -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} + static inline bool isFetchAndAddNative() { return true; } + static inline bool isFetchAndAddWaitFree() { return true; } + static T *fetchAndAddRelaxed(T *&_q_value, qptrdiff valueToAdd); +}; template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd) +inline bool QAtomicOps<T *>::testAndSetRelaxed(T *&_q_value, T *expectedValue, T *newValue) { - return fetchAndAddOrdered(valueToAdd); + return QT_INTERLOCKED_COMPARE_EXCHANGE_POINTER(&_q_value, newValue, expectedValue) == expectedValue; } template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd) +inline T *QAtomicOps<T *>::fetchAndStoreRelaxed(T *&_q_value, T *newValue) { - return fetchAndAddOrdered(valueToAdd); + return reinterpret_cast<T *>(QT_INTERLOCKED_EXCHANGE_POINTER(&_q_value, newValue)); } template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd) +inline T *QAtomicOps<T *>::fetchAndAddRelaxed(T *&_q_value, qptrdiff valueToAdd) { - return fetchAndAddOrdered(valueToAdd); + return reinterpret_cast<T *>(QT_INTERLOCKED_EXCHANGE_ADD_POINTER(&_q_value, valueToAdd * sizeof(T))); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -474,9 +366,7 @@ Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueTo #undef QT_INTERLOCKED_FUNCTION #undef QT_INTERLOCKED_PREFIX -#undef QT_INTERLOCKED_NO_VOLATILE #undef QT_INTERLOCKED_VOLATILE -#undef QT_INTERLOCKED_REMOVE_VOLATILE #undef QT_INTERLOCKED_INCREMENT #undef QT_INTERLOCKED_DECREMENT @@ -488,7 +378,6 @@ Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueTo #undef QT_INTERLOCKED_EXCHANGE_ADD_POINTER QT_END_NAMESPACE - QT_END_HEADER #endif // Q_CC_MSVC diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h index 3ef2d8a4cd..44f536724c 100644 --- a/src/corelib/thread/qbasicatomic.h +++ b/src/corelib/thread/qbasicatomic.h @@ -46,9 +46,8 @@ #if defined(QT_MOC) || defined(QT_BUILD_QMAKE) || defined(QT_RCC) || defined(QT_UIC) || defined(QT_BOOTSTRAPPED) # include <QtCore/qatomic_bootstrap.h> -#elif defined(Q_CC_MSVC) - // not ported yet -# define QT_OLD_ATOMICS +#elif defined(Q_OS_WIN) && defined(Q_CC_MSVC) +# include <QtCore/qatomic_windows.h> #elif defined(__arm__) || defined(__TARGET_ARCH_ARM) # include <QtCore/qatomic_arm.h> #elif defined(__i386) || defined(__i386__) diff --git a/src/corelib/thread/qgenericatomic.h b/src/corelib/thread/qgenericatomic.h index a136e98adc..984ebed47b 100644 --- a/src/corelib/thread/qgenericatomic.h +++ b/src/corelib/thread/qgenericatomic.h @@ -86,8 +86,8 @@ template <typename BaseClass> struct QGenericAtomicOps return _q_value; } - template <typename T> static inline always_inline - void store(T &_q_value, T newValue) + template <typename T, typename X> static inline always_inline + void store(T &_q_value, X newValue) { _q_value = newValue; } @@ -100,8 +100,8 @@ template <typename BaseClass> struct QGenericAtomicOps return tmp; } - template <typename T> static inline always_inline - void storeRelease(T &_q_value, T newValue) + template <typename T, typename X> static inline always_inline + void storeRelease(T &_q_value, X newValue) { BaseClass::releaseMemoryFence(); *static_cast<volatile T *>(&_q_value) = newValue; @@ -128,27 +128,27 @@ template <typename BaseClass> struct QGenericAtomicOps // Archictectures must implement them static inline bool isTestAndSetNative(); static inline bool isTestAndSetWaitFree(); - template <typename T> static inline - bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue); + template <typename T, typename X> static inline + bool testAndSetRelaxed(T &_q_value, X expectedValue, X newValue); #endif - template <typename T> static inline always_inline - bool testAndSetAcquire(T &_q_value, T expectedValue, T newValue) + template <typename T, typename X> static inline always_inline + bool testAndSetAcquire(T &_q_value, X expectedValue, X newValue) { bool tmp = BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue); BaseClass::acquireMemoryFence(); return tmp; } - template <typename T> static inline always_inline - bool testAndSetRelease(T &_q_value, T expectedValue, T newValue) + template <typename T, typename X> static inline always_inline + bool testAndSetRelease(T &_q_value, X expectedValue, X newValue) { BaseClass::releaseMemoryFence(); return BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue); } - template <typename T> static inline always_inline - bool testAndSetOrdered(T &_q_value, T expectedValue, T newValue) + template <typename T, typename X> static inline always_inline + bool testAndSetOrdered(T &_q_value, X expectedValue, X newValue) { BaseClass::orderedMemoryFence(); return BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue); @@ -157,8 +157,8 @@ template <typename BaseClass> struct QGenericAtomicOps static inline bool isFetchAndStoreNative() { return false; } static inline bool isFetchAndStoreWaitFree() { return false; } - template <typename T> static inline always_inline - T fetchAndStoreRelaxed(T &_q_value, T newValue) + template <typename T, typename X> static inline always_inline + T fetchAndStoreRelaxed(T &_q_value, X newValue) { // implement fetchAndStore on top of testAndSet Q_FOREVER { @@ -168,23 +168,23 @@ template <typename BaseClass> struct QGenericAtomicOps } } - template <typename T> static inline always_inline - T fetchAndStoreAcquire(T &_q_value, T newValue) + template <typename T, typename X> static inline always_inline + T fetchAndStoreAcquire(T &_q_value, X newValue) { T tmp = BaseClass::fetchAndStoreRelaxed(_q_value, newValue); BaseClass::acquireMemoryFence(); return tmp; } - template <typename T> static inline always_inline - T fetchAndStoreRelease(T &_q_value, T newValue) + template <typename T, typename X> static inline always_inline + T fetchAndStoreRelease(T &_q_value, X newValue) { BaseClass::releaseMemoryFence(); return BaseClass::fetchAndStoreRelaxed(_q_value, newValue); } - template <typename T> static inline always_inline - T fetchAndStoreOrdered(T &_q_value, T newValue) + template <typename T, typename X> static inline always_inline + T fetchAndStoreOrdered(T &_q_value, X newValue) { BaseClass::orderedMemoryFence(); return BaseClass::fetchAndStoreRelaxed(_q_value, newValue); |