summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2015-01-15 15:16:53 -0800
committerThiago Macieira <thiago.macieira@intel.com>2015-03-05 00:05:00 +0000
commit212285639d748c7def8648f89b8c1c21c5f481e6 (patch)
treee283c0e0e99fb5aee81a2364f4ed00478bc26b36
parent126d489f7f561bc3967ee2a36624c3b1fa26f974 (diff)
Add missing fetchAndXxx methods to atomic classes based on std::atomic
And add tests for the GCC intrinsics and for std::atomic. Task-number: QTBUG-43794 Change-Id: Ic5d393bfd36e48a193fcffff13b9b2dbaee80469 Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
-rw-r--r--src/corelib/arch/qatomic_cxx11.h96
-rw-r--r--src/corelib/thread/qbasicatomic.h8
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/char/char.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/char16_t/char16_t.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/char32_t/char32_t.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/cxx11/char/char.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/cxx11/char16_t/char16_t.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/cxx11/char32_t/char32_t.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/cxx11/int/int.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/cxx11/long/long.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/cxx11/qlonglong/qlonglong.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/cxx11/qptrdiff/qptrdiff.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/cxx11/quintptr/quintptr.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/cxx11/qulonglong/qulonglong.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/cxx11/schar/schar.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/cxx11/short/short.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/cxx11/uchar/uchar.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/cxx11/uint/uint.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/cxx11/ulong/ulong.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/cxx11/ushort/ushort.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/cxx11/wchar_t/wchar_t.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/gcc/char/char.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/gcc/char16_t/char16_t.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/gcc/char32_t/char32_t.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/gcc/int/int.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/gcc/long/long.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/gcc/qlonglong/qlonglong.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/gcc/qptrdiff/qptrdiff.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/gcc/quintptr/quintptr.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/gcc/qulonglong/qulonglong.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/gcc/schar/schar.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/gcc/short/short.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/gcc/uchar/uchar.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/gcc/uint/uint.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/gcc/ulong/ulong.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/gcc/ushort/ushort.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/gcc/wchar_t/wchar_t.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/int/int.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/long/long.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pri19
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pro39
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/qlonglong/qlonglong.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/qptrdiff/qptrdiff.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/quintptr/quintptr.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/qulonglong/qulonglong.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/schar/schar.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/short/short.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp24
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/uchar/uchar.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/uint/uint.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/ulong/ulong.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/ushort/ushort.pro1
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/wchar_t/wchar_t.pro1
53 files changed, 215 insertions, 19 deletions
diff --git a/src/corelib/arch/qatomic_cxx11.h b/src/corelib/arch/qatomic_cxx11.h
index a58c8ab72e..09e900f4ea 100644
--- a/src/corelib/arch/qatomic_cxx11.h
+++ b/src/corelib/arch/qatomic_cxx11.h
@@ -230,6 +230,102 @@ template <typename X> struct QAtomicOps
{
return _q_value.fetch_add(valueToAdd, std::memory_order_acq_rel);
}
+
+ template <typename T> static inline
+ T fetchAndSubRelaxed(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+ {
+ return _q_value.fetch_sub(valueToAdd, std::memory_order_relaxed);
+ }
+
+ template <typename T> static inline
+ T fetchAndSubAcquire(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+ {
+ return _q_value.fetch_sub(valueToAdd, std::memory_order_acquire);
+ }
+
+ template <typename T> static inline
+ T fetchAndSubRelease(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+ {
+ return _q_value.fetch_sub(valueToAdd, std::memory_order_release);
+ }
+
+ template <typename T> static inline
+ T fetchAndSubOrdered(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+ {
+ return _q_value.fetch_sub(valueToAdd, std::memory_order_acq_rel);
+ }
+
+ template <typename T> static inline
+ T fetchAndAndRelaxed(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+ {
+ return _q_value.fetch_and(valueToAdd, std::memory_order_relaxed);
+ }
+
+ template <typename T> static inline
+ T fetchAndAndAcquire(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+ {
+ return _q_value.fetch_and(valueToAdd, std::memory_order_acquire);
+ }
+
+ template <typename T> static inline
+ T fetchAndAndRelease(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+ {
+ return _q_value.fetch_and(valueToAdd, std::memory_order_release);
+ }
+
+ template <typename T> static inline
+ T fetchAndAndOrdered(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+ {
+ return _q_value.fetch_and(valueToAdd, std::memory_order_acq_rel);
+ }
+
+ template <typename T> static inline
+ T fetchAndOrRelaxed(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+ {
+ return _q_value.fetch_or(valueToAdd, std::memory_order_relaxed);
+ }
+
+ template <typename T> static inline
+ T fetchAndOrAcquire(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+ {
+ return _q_value.fetch_or(valueToAdd, std::memory_order_acquire);
+ }
+
+ template <typename T> static inline
+ T fetchAndOrRelease(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+ {
+ return _q_value.fetch_or(valueToAdd, std::memory_order_release);
+ }
+
+ template <typename T> static inline
+ T fetchAndOrOrdered(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+ {
+ return _q_value.fetch_or(valueToAdd, std::memory_order_acq_rel);
+ }
+
+ template <typename T> static inline
+ T fetchAndXorRelaxed(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+ {
+ return _q_value.fetch_xor(valueToAdd, std::memory_order_relaxed);
+ }
+
+ template <typename T> static inline
+ T fetchAndXorAcquire(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+ {
+ return _q_value.fetch_xor(valueToAdd, std::memory_order_acquire);
+ }
+
+ template <typename T> static inline
+ T fetchAndXorRelease(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+ {
+ return _q_value.fetch_xor(valueToAdd, std::memory_order_release);
+ }
+
+ template <typename T> static inline
+ T fetchAndXorOrdered(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+ {
+ return _q_value.fetch_xor(valueToAdd, std::memory_order_acq_rel);
+ }
};
#ifdef ATOMIC_VAR_INIT
diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h
index 16a27862c2..ecf39d699f 100644
--- a/src/corelib/thread/qbasicatomic.h
+++ b/src/corelib/thread/qbasicatomic.h
@@ -39,6 +39,14 @@
#if defined(QT_BOOTSTRAPPED)
# include <QtCore/qatomic_bootstrap.h>
+// The following two are used for testing only.
+// Note that we don't check the compiler support -- you had better
+// know what you're doing if you set them
+#elif defined(QT_ATOMIC_FORCE_CXX11)
+# include <QtCore/qatomic_cxx11.h>
+#elif defined(QT_ATOMIC_FORCE_GCC)
+# include <QtCore/qatomic_gcc.h>
+
// Compiler dependent implementation
#elif defined(Q_CC_MSVC)
# include <QtCore/qatomic_msvc.h>
diff --git a/tests/auto/corelib/thread/qatomicinteger/char/char.pro b/tests/auto/corelib/thread/qatomicinteger/char/char.pro
index 51ef1add8f..1e97d5cbae 100644
--- a/tests/auto/corelib/thread/qatomicinteger/char/char.pro
+++ b/tests/auto/corelib/thread/qatomicinteger/char/char.pro
@@ -1,2 +1 @@
-TYPE = $$basename(PWD)
include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/char16_t/char16_t.pro b/tests/auto/corelib/thread/qatomicinteger/char16_t/char16_t.pro
index 51ef1add8f..1e97d5cbae 100644
--- a/tests/auto/corelib/thread/qatomicinteger/char16_t/char16_t.pro
+++ b/tests/auto/corelib/thread/qatomicinteger/char16_t/char16_t.pro
@@ -1,2 +1 @@
-TYPE = $$basename(PWD)
include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/char32_t/char32_t.pro b/tests/auto/corelib/thread/qatomicinteger/char32_t/char32_t.pro
index 51ef1add8f..1e97d5cbae 100644
--- a/tests/auto/corelib/thread/qatomicinteger/char32_t/char32_t.pro
+++ b/tests/auto/corelib/thread/qatomicinteger/char32_t/char32_t.pro
@@ -1,2 +1 @@
-TYPE = $$basename(PWD)
include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/char/char.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/char/char.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/char/char.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/char16_t/char16_t.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/char16_t/char16_t.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/char16_t/char16_t.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/char32_t/char32_t.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/char32_t/char32_t.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/char32_t/char32_t.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/int/int.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/int/int.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/int/int.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/long/long.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/long/long.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/long/long.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/qlonglong/qlonglong.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/qlonglong/qlonglong.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/qlonglong/qlonglong.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/qptrdiff/qptrdiff.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/qptrdiff/qptrdiff.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/qptrdiff/qptrdiff.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/quintptr/quintptr.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/quintptr/quintptr.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/quintptr/quintptr.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/qulonglong/qulonglong.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/qulonglong/qulonglong.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/qulonglong/qulonglong.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/schar/schar.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/schar/schar.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/schar/schar.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/short/short.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/short/short.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/short/short.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/uchar/uchar.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/uchar/uchar.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/uchar/uchar.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/uint/uint.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/uint/uint.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/uint/uint.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/ulong/ulong.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/ulong/ulong.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/ulong/ulong.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/ushort/ushort.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/ushort/ushort.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/ushort/ushort.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/wchar_t/wchar_t.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/wchar_t/wchar_t.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/wchar_t/wchar_t.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/char/char.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/char/char.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/gcc/char/char.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/char16_t/char16_t.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/char16_t/char16_t.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/gcc/char16_t/char16_t.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/char32_t/char32_t.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/char32_t/char32_t.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/gcc/char32_t/char32_t.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/int/int.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/int/int.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/gcc/int/int.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/long/long.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/long/long.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/gcc/long/long.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/qlonglong/qlonglong.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/qlonglong/qlonglong.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/gcc/qlonglong/qlonglong.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/qptrdiff/qptrdiff.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/qptrdiff/qptrdiff.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/gcc/qptrdiff/qptrdiff.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/quintptr/quintptr.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/quintptr/quintptr.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/gcc/quintptr/quintptr.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/qulonglong/qulonglong.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/qulonglong/qulonglong.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/gcc/qulonglong/qulonglong.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/schar/schar.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/schar/schar.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/gcc/schar/schar.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/short/short.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/short/short.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/gcc/short/short.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/uchar/uchar.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/uchar/uchar.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/gcc/uchar/uchar.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/uint/uint.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/uint/uint.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/gcc/uint/uint.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/ulong/ulong.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/ulong/ulong.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/gcc/ulong/ulong.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/ushort/ushort.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/ushort/ushort.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/gcc/ushort/ushort.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/wchar_t/wchar_t.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/wchar_t/wchar_t.pro
new file mode 100644
index 0000000000..64401f0229
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/gcc/wchar_t/wchar_t.pro
@@ -0,0 +1 @@
+include(../../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/int/int.pro b/tests/auto/corelib/thread/qatomicinteger/int/int.pro
index 51ef1add8f..1e97d5cbae 100644
--- a/tests/auto/corelib/thread/qatomicinteger/int/int.pro
+++ b/tests/auto/corelib/thread/qatomicinteger/int/int.pro
@@ -1,2 +1 @@
-TYPE = $$basename(PWD)
include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/long/long.pro b/tests/auto/corelib/thread/qatomicinteger/long/long.pro
index 51ef1add8f..1e97d5cbae 100644
--- a/tests/auto/corelib/thread/qatomicinteger/long/long.pro
+++ b/tests/auto/corelib/thread/qatomicinteger/long/long.pro
@@ -1,2 +1 @@
-TYPE = $$basename(PWD)
include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pri b/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pri
index dc7cc8bcec..d9ebe64d5b 100644
--- a/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pri
+++ b/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pri
@@ -1,7 +1,20 @@
-isEmpty(TYPE): error("Project must define TYPE variable")
+# Get our build type from the directory name
+TYPE = $$basename(_PRO_FILE_PWD_)
+dn = $$dirname(_PRO_FILE_PWD_)
+FORCE = $$basename(dn)
+
+equals(FORCE, cxx11) {
+ suffix = Cxx11_$$TYPE
+ DEFINES += QT_ATOMIC_FORCE_CXX11
+} else: equals(FORCE, gcc) {
+ suffix = Gcc_$$TYPE
+ DEFINES += QT_ATOMIC_FORCE_GCC
+} else {
+ suffix = $$TYPE
+}
CONFIG += testcase parallel_test
QT = core testlib
-TARGET = tst_qatomicinteger_$$TYPE
+TARGET = tst_qatomicinteger_$$lower($$suffix)
SOURCES = $$PWD/tst_qatomicinteger.cpp
-DEFINES += QATOMIC_TEST_TYPE=$$TYPE tst_QAtomicIntegerXX=tst_QAtomicInteger_$$TYPE
+DEFINES += QATOMIC_TEST_TYPE=$$TYPE tst_QAtomicIntegerXX=tst_QAtomicInteger_$$suffix
diff --git a/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pro b/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pro
index 373e8801a4..58e5b157bd 100644
--- a/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pro
+++ b/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pro
@@ -17,3 +17,42 @@ SUBDIRS=\
ushort \
wchar_t \
+
+contains(QT_CONFIG, c++11)|msvc: SUBDIRS +=\
+ cxx11/char \
+ cxx11/char16_t \
+ cxx11/char32_t \
+ cxx11/int \
+ cxx11/long \
+ cxx11/qlonglong \
+ cxx11/qptrdiff \
+ cxx11/quintptr \
+ cxx11/qulonglong \
+ cxx11/schar \
+ cxx11/short \
+ cxx11/uchar \
+ cxx11/uint \
+ cxx11/ulong \
+ cxx11/ushort \
+ cxx11/wchar_t \
+
+
+# The GCC-style atomics only support 32-bit and pointer-sized but add
+# them all anyway so we ensure the macros are properly defined
+gcc: SUBDIRS +=\
+ gcc/char \
+ gcc/char16_t \
+ gcc/char32_t \
+ gcc/int \
+ gcc/long \
+ gcc/qlonglong \
+ gcc/qptrdiff \
+ gcc/quintptr \
+ gcc/qulonglong \
+ gcc/schar \
+ gcc/short \
+ gcc/uchar \
+ gcc/uint \
+ gcc/ulong \
+ gcc/ushort \
+ gcc/wchar_t \
diff --git a/tests/auto/corelib/thread/qatomicinteger/qlonglong/qlonglong.pro b/tests/auto/corelib/thread/qatomicinteger/qlonglong/qlonglong.pro
index 51ef1add8f..1e97d5cbae 100644
--- a/tests/auto/corelib/thread/qatomicinteger/qlonglong/qlonglong.pro
+++ b/tests/auto/corelib/thread/qatomicinteger/qlonglong/qlonglong.pro
@@ -1,2 +1 @@
-TYPE = $$basename(PWD)
include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/qptrdiff/qptrdiff.pro b/tests/auto/corelib/thread/qatomicinteger/qptrdiff/qptrdiff.pro
index 51ef1add8f..1e97d5cbae 100644
--- a/tests/auto/corelib/thread/qatomicinteger/qptrdiff/qptrdiff.pro
+++ b/tests/auto/corelib/thread/qatomicinteger/qptrdiff/qptrdiff.pro
@@ -1,2 +1 @@
-TYPE = $$basename(PWD)
include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/quintptr/quintptr.pro b/tests/auto/corelib/thread/qatomicinteger/quintptr/quintptr.pro
index 51ef1add8f..1e97d5cbae 100644
--- a/tests/auto/corelib/thread/qatomicinteger/quintptr/quintptr.pro
+++ b/tests/auto/corelib/thread/qatomicinteger/quintptr/quintptr.pro
@@ -1,2 +1 @@
-TYPE = $$basename(PWD)
include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/qulonglong/qulonglong.pro b/tests/auto/corelib/thread/qatomicinteger/qulonglong/qulonglong.pro
index 51ef1add8f..1e97d5cbae 100644
--- a/tests/auto/corelib/thread/qatomicinteger/qulonglong/qulonglong.pro
+++ b/tests/auto/corelib/thread/qatomicinteger/qulonglong/qulonglong.pro
@@ -1,2 +1 @@
-TYPE = $$basename(PWD)
include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/schar/schar.pro b/tests/auto/corelib/thread/qatomicinteger/schar/schar.pro
index 51ef1add8f..1e97d5cbae 100644
--- a/tests/auto/corelib/thread/qatomicinteger/schar/schar.pro
+++ b/tests/auto/corelib/thread/qatomicinteger/schar/schar.pro
@@ -1,2 +1 @@
-TYPE = $$basename(PWD)
include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/short/short.pro b/tests/auto/corelib/thread/qatomicinteger/short/short.pro
index 51ef1add8f..1e97d5cbae 100644
--- a/tests/auto/corelib/thread/qatomicinteger/short/short.pro
+++ b/tests/auto/corelib/thread/qatomicinteger/short/short.pro
@@ -1,2 +1 @@
-TYPE = $$basename(PWD)
include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp b/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp
index cb01237b85..d3c85c54a7 100644
--- a/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp
+++ b/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp
@@ -31,6 +31,30 @@
**
****************************************************************************/
+#ifdef QT_ATOMIC_FORCE_CXX11
+// We need to check if this compiler has C++11 atomics and constexpr support.
+// We can't rely on qcompilerdetection.h because it forces all of qglobal.h to
+// be included, which causes qbasicatomic.h to be included too.
+// Incomplete, but ok
+# if defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1500 && (__cplusplus >= 201103L || defined(__INTEL_CXX11_MODE__))
+# elif defined(__clang__) && (__cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__))
+# if !__has_feature(cxx_constexpr) || !__has_feature(cxx_atomic) || !__has_include(<atomic>)
+# undef QT_ATOMIC_FORCE_CXX11
+# endif
+# elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 407 && (__cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__))
+# elif defined(_MSC_VER) && _MSC_VER >= 1900
+ // We need MSVC 2015 because of: atomics (2012), constexpr (2015), and unrestricted unions (2015).
+ // Support for constexpr is not working completely on MSVC 2015 but it's enough for the test.
+# else
+# undef QT_ATOMIC_FORCE_CXX11
+# endif
+
+# ifndef QT_ATOMIC_FORCE_CXX11
+# undef QATOMIC_TEST_TYPE
+# define QATOMIC_TEST_TYPE unsupported
+# endif
+#endif
+
#include <QtTest>
#include <QAtomicInt>
diff --git a/tests/auto/corelib/thread/qatomicinteger/uchar/uchar.pro b/tests/auto/corelib/thread/qatomicinteger/uchar/uchar.pro
index 51ef1add8f..1e97d5cbae 100644
--- a/tests/auto/corelib/thread/qatomicinteger/uchar/uchar.pro
+++ b/tests/auto/corelib/thread/qatomicinteger/uchar/uchar.pro
@@ -1,2 +1 @@
-TYPE = $$basename(PWD)
include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/uint/uint.pro b/tests/auto/corelib/thread/qatomicinteger/uint/uint.pro
index 51ef1add8f..1e97d5cbae 100644
--- a/tests/auto/corelib/thread/qatomicinteger/uint/uint.pro
+++ b/tests/auto/corelib/thread/qatomicinteger/uint/uint.pro
@@ -1,2 +1 @@
-TYPE = $$basename(PWD)
include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/ulong/ulong.pro b/tests/auto/corelib/thread/qatomicinteger/ulong/ulong.pro
index 51ef1add8f..1e97d5cbae 100644
--- a/tests/auto/corelib/thread/qatomicinteger/ulong/ulong.pro
+++ b/tests/auto/corelib/thread/qatomicinteger/ulong/ulong.pro
@@ -1,2 +1 @@
-TYPE = $$basename(PWD)
include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/ushort/ushort.pro b/tests/auto/corelib/thread/qatomicinteger/ushort/ushort.pro
index 51ef1add8f..1e97d5cbae 100644
--- a/tests/auto/corelib/thread/qatomicinteger/ushort/ushort.pro
+++ b/tests/auto/corelib/thread/qatomicinteger/ushort/ushort.pro
@@ -1,2 +1 @@
-TYPE = $$basename(PWD)
include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/wchar_t/wchar_t.pro b/tests/auto/corelib/thread/qatomicinteger/wchar_t/wchar_t.pro
index 51ef1add8f..1e97d5cbae 100644
--- a/tests/auto/corelib/thread/qatomicinteger/wchar_t/wchar_t.pro
+++ b/tests/auto/corelib/thread/qatomicinteger/wchar_t/wchar_t.pro
@@ -1,2 +1 @@
-TYPE = $$basename(PWD)
include(../qatomicinteger.pri)