Ensure that the pointer-sized QAtomicInteger specialization exists
This is already implemented in qatomic_x86.h, qatomic_ia64.h, qatomic_mips.h, qatomic_armv6.h, and qatomic_cxx11.h. For qatomic_msvc.h, we've just fixed it. For qatomic_gcc.h, we know that the compiler supports it, so just add it. According to the GCC manual, it might print a warning on some platforms, so we only enable that on 64-bit builds. For qatomic_unix.h, the support was missing (along with support for unsigned 32-bit), so this commits adds it. For qatomic_armv5.h, the platform does not always support 64-bit atomics, but ARMv5 cannot compile in 64-bit mode anyway. Change-Id: Ia8b3b5c641f11e5df05937fe7442be0a223174ef Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This commit is contained in:
parent
e4533e3aeb
commit
8d2a9bcf1d
@ -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
|
||||
|
@ -64,6 +64,19 @@ bool QAtomicOps<int>::testAndSetRelaxed(int &_q_value, int expectedValue, int ne
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user