summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread
diff options
context:
space:
mode:
authorBradley T. Hughes <bradley.hughes@nokia.com>2012-01-30 15:04:06 +0100
committerQt by Nokia <qt-info@nokia.com>2012-02-02 11:10:04 +0100
commit307c03497301015c418d4bfe462b14ed9cdf2f1b (patch)
tree82a97cd92aa2036b75d043df32a76efb0240644a /src/corelib/thread
parentf04756f3f542eeeae416724046bfec96d977701e (diff)
Port the Windows atomic implementation to use QGenericAtomicOps
First, we do not need to have the QT_INTERLOCKED_REMOVE_VOLATILE(a) macro anymore either, since the value stored in QBasicAtomicInteger is not volatile. Windows provides Interlocked*Pointer() functions in some configurations, so we provide a partial specialization of QAtomicOps for pointer types. For integer types, QAtomicOps selects an implementation based on the size of the type. At the moment, we only support 32-bit types, but it will be possible to add 64-bit later. Note that the 32-bit specialization of QAtomicOpsBySize declares the Type typedef as long, not int, since the Windows Interlocked*() API takes parameters as longs and long pointers. Since this typedef differs from the type given to QBasicAtomicInteger<T> by the QBasicAtomicInt typedef, we need to templatise the _q_value parameter separately from the other arguments in QGenericAtomicOps. This templatisation would be necessary to port other architectures, such as PA_RISC, where we need to have an int[4] array in the atomic type while the arguments do not need this array. Change-Id: Id71fa1ae334da2023553cb402b45e6c285f1d344 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com> Reviewed-by: João Abecasis <joao.abecasis@nokia.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/thread')
-rw-r--r--src/corelib/thread/qbasicatomic.h5
-rw-r--r--src/corelib/thread/qgenericatomic.h40
2 files changed, 22 insertions, 23 deletions
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);