summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/arch/qatomic_gcc.h10
-rw-r--r--src/corelib/arch/qatomic_unix.cpp13
-rw-r--r--src/corelib/arch/qatomic_unix.h40
-rw-r--r--src/corelib/thread/qatomic.cpp16
4 files changed, 78 insertions, 1 deletions
diff --git a/src/corelib/arch/qatomic_gcc.h b/src/corelib/arch/qatomic_gcc.h
index 61e709655d..4038c6dee0 100644
--- a/src/corelib/arch/qatomic_gcc.h
+++ b/src/corelib/arch/qatomic_gcc.h
@@ -75,6 +75,16 @@ template<> struct QAtomicIntegerTraits<char32_t> { enum { IsInteger = 1 }; };
#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
+#if QT_POINTER_SIZE == 8
+# define Q_ATOMIC_INT64_IS_SUPPORTED
+# define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
+# define Q_ATOMIC_INT64_TEST_AND_SET_IS_SOMETIMES_NATIVE
+# define Q_ATOMIC_INT64_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
+# define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
+template<> struct QAtomicIntegerTraits<long long> { enum { IsInteger = 1 }; };
+template<> struct QAtomicIntegerTraits<unsigned long long> { enum { IsInteger = 1 }; };
+#endif
+
template <typename X> struct QAtomicOps: QGenericAtomicOps<QAtomicOps<X> >
{
// The GCC intrinsics all have fully-ordered memory semantics, so we define
diff --git a/src/corelib/arch/qatomic_unix.cpp b/src/corelib/arch/qatomic_unix.cpp
index 4acf43d6a5..7a5c48c235 100644
--- a/src/corelib/arch/qatomic_unix.cpp
+++ b/src/corelib/arch/qatomic_unix.cpp
@@ -65,6 +65,19 @@ bool QAtomicOps<int>::testAndSetRelaxed(int &_q_value, int expectedValue, int ne
}
Q_CORE_EXPORT
+bool QAtomicOps<long long>::testAndSetRelaxed(Type &_q_value, Type expectedValue, Type newValue) Q_DECL_NOTHROW
+{
+ bool returnValue = false;
+ pthread_mutex_lock(&qAtomicMutex);
+ if (_q_value == expectedValue) {
+ _q_value = newValue;
+ returnValue = true;
+ }
+ pthread_mutex_unlock(&qAtomicMutex);
+ return returnValue;
+}
+
+Q_CORE_EXPORT
bool QAtomicOps<void *>::testAndSetRelaxed(void *&_q_value, void *expectedValue, void *newValue) Q_DECL_NOTHROW
{
bool returnValue = false;
diff --git a/src/corelib/arch/qatomic_unix.h b/src/corelib/arch/qatomic_unix.h
index 02583297f9..017adabbe2 100644
--- a/src/corelib/arch/qatomic_unix.h
+++ b/src/corelib/arch/qatomic_unix.h
@@ -64,15 +64,25 @@ QT_END_NAMESPACE
#define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_NOT_NATIVE
#define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_NOT_NATIVE
+#define Q_ATOMIC_INT64_IS_SUPPORTED
+#define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_NOT_NATIVE
+#define Q_ATOMIC_INT64_TEST_AND_SET_IS_NOT_NATIVE
+#define Q_ATOMIC_INT64_FETCH_AND_STORE_IS_NOT_NATIVE
+#define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_NOT_NATIVE
+
#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE
#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE
template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; };
+template<> struct QAtomicIntegerTraits<unsigned> { enum { IsInteger = 1 }; };
+template<> struct QAtomicIntegerTraits<long long> { enum { IsInteger = 1 }; };
+template<> struct QAtomicIntegerTraits<unsigned long long> { enum { IsInteger = 1 }; };
// No definition, needs specialization
template <typename T> struct QAtomicOps;
+// 32-bit version
template <>
struct QAtomicOps<int> : QGenericAtomicOps<QAtomicOps<int> >
{
@@ -83,6 +93,18 @@ struct QAtomicOps<int> : QGenericAtomicOps<QAtomicOps<int> >
Q_CORE_EXPORT static bool testAndSetRelaxed(int &_q_value, int expectedValue, int newValue) Q_DECL_NOTHROW;
};
+// 64-bit version
+template <>
+struct QAtomicOps<long long> : QGenericAtomicOps<QAtomicOps<long long> >
+{
+ typedef long long Type;
+
+ static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW { return false; }
+ static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return false; }
+ Q_CORE_EXPORT static bool testAndSetRelaxed(Type &_q_value, Type expectedValue, Type newValue) Q_DECL_NOTHROW;
+};
+
+// pointer version
template <>
struct QAtomicOps<void *> : QGenericAtomicOps<QAtomicOps<void *> >
{
@@ -113,5 +135,23 @@ struct QAtomicOps<T *> : QGenericAtomicOps<QAtomicOps<T *> >
}
};
+// 32- and 64-bit unsigned versions
+template <> struct QAtomicOps<unsigned> : QAtomicOps<int>
+{
+ typedef unsigned Type;
+ Q_CORE_EXPORT static bool testAndSetRelaxed(Type &_q_value, Type expectedValue, Type newValue) Q_DECL_NOTHROW
+ {
+ return QAtomicOps<int>::testAndSetRelaxed(reinterpret_cast<int &>(_q_value), int(expectedValue), int(newValue));
+ }
+};
+template <> struct QAtomicOps<unsigned long long> : QAtomicOps<long long>
+{
+ typedef unsigned long longType;
+ Q_CORE_EXPORT static bool testAndSetRelaxed(Type &_q_value, Type expectedValue, Type newValue) Q_DECL_NOTHROW
+ {
+ return QAtomicOps<long long>::testAndSetRelaxed(reinterpret_cast<long long &>(_q_value), int(expectedValue), int(newValue));
+ }
+};
+
QT_END_NAMESPACE
#endif // QATOMIC_UNIX_H
diff --git a/src/corelib/thread/qatomic.cpp b/src/corelib/thread/qatomic.cpp
index f70b58d25b..36cdfdb369 100644
--- a/src/corelib/thread/qatomic.cpp
+++ b/src/corelib/thread/qatomic.cpp
@@ -72,9 +72,10 @@
\li 32-bit: int, unsigned int, qint32, quint32, char32_t (C++11)
\li 64-bit: long long, unsigned long long, qint64, quint64
\li platform-specific size: long, unsigned long
+ \li pointer size: qintptr, quintptr, qptrdiff
\endlist
- Of the list above, only the 32-bit-sized instantiations are guaranteed to
+ Of the list above, only the 32-bit- and pointer-sized instantiations are guaranteed to
work on all platforms. Support for other sizes depends on the compiler and
processor architecture the code is being compiled for. To test whether the
other types are supported, check the macro \c Q_ATOMIC_INT\e{nn}_IS_SUPPORTED,
@@ -1213,3 +1214,16 @@
#ifndef Q_ATOMIC_INT32_IS_SUPPORTED
# error "Q_ATOMIC_INT32_IS_SUPPORTED must be defined"
#endif
+#if !defined(Q_ATOMIC_INT64_IS_SUPPORTED) && QT_POINTER_SIZE == 8
+// 64-bit platform
+# error "Q_ATOMIC_INT64_IS_SUPPORTED must be defined on a 64-bit platform"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+// The following three specializations must always be defined
+Q_STATIC_ASSERT(sizeof(QAtomicInteger<unsigned>));
+Q_STATIC_ASSERT(sizeof(QAtomicInteger<quintptr>));
+Q_STATIC_ASSERT(sizeof(QAtomicInteger<qptrdiff>));
+
+QT_END_NAMESPACE