summaryrefslogtreecommitdiffstats
path: root/src/corelib/arch
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2016-07-19 19:51:41 +0200
committerEdward Welbourne <edward.welbourne@qt.io>2016-07-19 20:14:40 +0200
commit782ebeada125e3d8a293c7806e34cc737c30ddda (patch)
tree5516ad24a7532d650289758abd5e92a35bc2240e /src/corelib/arch
parent091df96fb8da356dc9de81dc390f55e66d4d7c01 (diff)
parent62cbb434579a56871f0917bc306d592055381c00 (diff)
Merge remote-tracking branch 'origin/5.7' into dev
Conflicts: qmake/library/qmakebuiltins.cpp qmake/library/qmakeevaluator.cpp qmake/library/qmakeevaluator.h qmake/project.h QMakeEvaluator: * evaluateConditional(): one side changed return type, the other changed a parameter type. * split_value_list(): one side changed a parameter adjacent to where ... * expandVariableReferences(): ... the other killed one overload and changed the survivor src/corelib/io/qlockfile_unix.cpp One side changed a #if condition, the other moved NETBSD's part of what it controlled. src/corelib/tools/qdatetime.cpp One side fixed a reachable Q_UNREACHABLE in toMSecsSinceEpoch(), the other moved it from the private class to the public one, in the midst of the "short date-time" optimization, which confused diff entirely. One side changed a QStringLiteral to QLatin1String, the other rewrote adjoining code. src/network/kernel/qauthenticator.cpp Both rewrote a line, equivalently; kept the dev version. src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h One side changed #if-ery that the other removed. tools/configure/configureapp.cpp One side added a check to -target parsing; the other killed -target. tests/auto/testlib/selftests/expected_cmptest.lightxml tests/auto/testlib/selftests/expected_cmptest.teamcity tests/auto/testlib/selftests/expected_cmptest.txt tests/auto/testlib/selftests/expected_cmptest.xml tests/auto/testlib/selftests/expected_cmptest.xunitxml Regenerated using generate_expected_output.py I note that quite a few other expected_* come out changed, now. There was no git-conflict in src/widgets/kernel/qformlayout.cpp but it didn't compile; one side removed some unused methods; the other found uses for one of them. Put FixedColumnMatrix<>::removeRow(int) back for its new user. Change-Id: I8cc2a71add48c0a848e13cfc47b5a7754e8ca584
Diffstat (limited to 'src/corelib/arch')
-rw-r--r--src/corelib/arch/qatomic_cxx11.h187
1 files changed, 156 insertions, 31 deletions
diff --git a/src/corelib/arch/qatomic_cxx11.h b/src/corelib/arch/qatomic_cxx11.h
index bb49aae4fb..9658aca37c 100644
--- a/src/corelib/arch/qatomic_cxx11.h
+++ b/src/corelib/arch/qatomic_cxx11.h
@@ -53,44 +53,168 @@ QT_END_NAMESPACE
#pragma qt_sync_stop_processing
#endif
-#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
-#define Q_ATOMIC_INT_TEST_AND_SET_IS_SOMETIMES_NATIVE
-#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
-#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
+/* Attempt to detect whether the atomic operations exist in hardware
+ * or whether they are emulated by way of a lock.
+ *
+ * C++11 29.4 [atomics.lockfree] p1 says
+ *
+ * The ATOMIC_..._LOCK_FREE macros indicate the lock-free property of the
+ * corresponding atomic types, with the signed and unsigned variants grouped
+ * together. The properties also apply to the corresponding (partial)
+ * specializations of the atomic template. A value of 0 indicates that the
+ * types are never lock-free. A value of 1 indicates that the types are
+ * sometimes lock-free. A value of 2 indicates that the types are always
+ * lock-free.
+ *
+ * We have a problem when the value is 1: we'd need to check at runtime, but
+ * QAtomicInteger requires a constexpr answer (defect introduced in Qt 5.0). So
+ * we'll err in the side of caution and say it isn't.
+ */
+
+// ### Qt 6: make non-constexpr (see above)
+template <int N> struct QAtomicTraits
+{ static Q_DECL_CONSTEXPR inline bool isLockFree() Q_DECL_NOTHROW; };
#define Q_ATOMIC_INT32_IS_SUPPORTED
-#define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
-#define Q_ATOMIC_INT32_TEST_AND_SET_IS_SOMETIMES_NATIVE
-#define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
-#define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
+#if ATOMIC_INT_LOCK_FREE == 2
+# define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
+# define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
+# define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+# define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+# define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
+# define Q_ATOMIC_INT32_TEST_AND_SET_IS_ALWAYS_NATIVE
+# define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+# define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+
+template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<4>::isLockFree() Q_DECL_NOTHROW
+{ return true; }
+#elif ATOMIC_INT_LOCK_FREE == 1
+# define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
+# define Q_ATOMIC_INT_TEST_AND_SET_IS_SOMETIMES_NATIVE
+# define Q_ATOMIC_INT_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
+# define Q_ATOMIC_INT_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
+# define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
+# define Q_ATOMIC_INT32_TEST_AND_SET_IS_SOMETIMES_NATIVE
+# define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
+# define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
+
+template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<4>::isLockFree() Q_DECL_NOTHROW
+{ return false; }
+#else
+# define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NEVER_NATIVE
+# define Q_ATOMIC_INT_TEST_AND_SET_IS_NEVER_NATIVE
+# define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NEVER_NATIVE
+# define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NEVER_NATIVE
+# define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_NEVER_NATIVE
+# define Q_ATOMIC_INT32_TEST_AND_SET_IS_NEVER_NATIVE
+# define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_NEVER_NATIVE
+# define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_NEVER_NATIVE
+
+template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<4>::isLockFree() Q_DECL_NOTHROW
+{ return false; }
+#endif
-#define Q_ATOMIC_POINTER_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
-#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE
-#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
-#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
+#if ATOMIC_POINTER_LOCK_FREE == 2
+# define Q_ATOMIC_POINTER_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
+# define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
+# define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+# define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+#elif ATOMIC_POINTER_LOCK_FREE == 1
+# define Q_ATOMIC_POINTER_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
+# define Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE
+# define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
+# define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
+#else
+# define Q_ATOMIC_POINTER_REFERENCE_COUNTING_IS_NEVER_NATIVE
+# define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NEVER_NATIVE
+# define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NEVER_NATIVE
+# define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NEVER_NATIVE
+#endif
template<> struct QAtomicOpsSupport<1> { enum { IsSupported = 1 }; };
-template<> struct QAtomicOpsSupport<2> { enum { IsSupported = 1 }; };
-template<> struct QAtomicOpsSupport<8> { enum { IsSupported = 1 }; };
-
#define Q_ATOMIC_INT8_IS_SUPPORTED
-#define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
-#define Q_ATOMIC_INT8_TEST_AND_SET_IS_ALWAYS_NATIVE
-#define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_ALWAYS_NATIVE
-#define Q_ATOMIC_INT8_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+#if ATOMIC_CHAR_LOCK_FREE == 2
+# define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
+# define Q_ATOMIC_INT8_TEST_AND_SET_IS_ALWAYS_NATIVE
+# define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+# define Q_ATOMIC_INT8_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+
+template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<1>::isLockFree() Q_DECL_NOTHROW
+{ return true; }
+#elif ATOMIC_CHAR_LOCK_FREE == 1
+# define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
+# define Q_ATOMIC_INT8_TEST_AND_SET_IS_SOMETIMES_NATIVE
+# define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
+# define Q_ATOMIC_INT8_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
+
+template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<1>::isLockFree() Q_DECL_NOTHROW
+{ return false; }
+#else
+# define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_NEVER_NATIVE
+# define Q_ATOMIC_INT8_TEST_AND_SET_IS_NEVER_NATIVE
+# define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_NEVER_NATIVE
+# define Q_ATOMIC_INT8_FETCH_AND_ADD_IS_NEVER_NATIVE
+template <> Q_DECL_CONSTEXPR bool QAtomicTraits<1>::isLockFree() Q_DECL_NOTHROW
+{ return false; }
+#endif
+
+template<> struct QAtomicOpsSupport<2> { enum { IsSupported = 1 }; };
#define Q_ATOMIC_INT16_IS_SUPPORTED
-#define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
-#define Q_ATOMIC_INT16_TEST_AND_SET_IS_ALWAYS_NATIVE
-#define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_ALWAYS_NATIVE
-#define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+#if ATOMIC_SHORT_LOCK_FREE == 2
+# define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
+# define Q_ATOMIC_INT16_TEST_AND_SET_IS_ALWAYS_NATIVE
+# define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+# define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+
+template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<2>::isLockFree() Q_DECL_NOTHROW
+{ return false; }
+#elif ATOMIC_SHORT_LOCK_FREE == 1
+# define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
+# define Q_ATOMIC_INT16_TEST_AND_SET_IS_SOMETIMES_NATIVE
+# define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
+# define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
+
+template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<2>::isLockFree() Q_DECL_NOTHROW
+{ return false; }
+#else
+# define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_NEVER_NATIVE
+# define Q_ATOMIC_INT16_TEST_AND_SET_IS_NEVER_NATIVE
+# define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_NEVER_NATIVE
+# define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_NEVER_NATIVE
+
+template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<2>::isLockFree() Q_DECL_NOTHROW
+{ return false; }
+#endif
#ifndef QT_NO_STD_ATOMIC64
+template<> struct QAtomicOpsSupport<8> { enum { IsSupported = 1 }; };
# define Q_ATOMIC_INT64_IS_SUPPORTED
-# define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
-# define Q_ATOMIC_INT64_TEST_AND_SET_IS_ALWAYS_NATIVE
-# define Q_ATOMIC_INT64_FETCH_AND_STORE_IS_ALWAYS_NATIVE
-# define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+# if ATOMIC_LLONG_LOCK_FREE == 2
+# define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
+# define Q_ATOMIC_INT16_TEST_AND_SET_IS_ALWAYS_NATIVE
+# define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+# define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+
+template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<8>::isLockFree() Q_DECL_NOTHROW
+{ return true; }
+# elif ATOMIC_LLONG_LOCK_FREE == 1
+# define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
+# define Q_ATOMIC_INT16_TEST_AND_SET_IS_SOMETIMES_NATIVE
+# define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
+# define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
+
+template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<8>::isLockFree() Q_DECL_NOTHROW
+{ return false; }
+# else
+# define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_NEVER_NATIVE
+# define Q_ATOMIC_INT16_TEST_AND_SET_IS_NEVER_NATIVE
+# define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_NEVER_NATIVE
+# define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_NEVER_NATIVE
+
+template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<8>::isLockFree() Q_DECL_NOTHROW
+{ return false; }
+# endif
#endif
template <typename X> struct QAtomicOps
@@ -133,7 +257,7 @@ template <typename X> struct QAtomicOps
_q_value.store(newValue, std::memory_order_release);
}
- static inline Q_DECL_CONSTEXPR bool isReferenceCountingNative() Q_DECL_NOTHROW { return true; }
+ static inline Q_DECL_CONSTEXPR bool isReferenceCountingNative() Q_DECL_NOTHROW { return isTestAndSetNative(); }
static inline Q_DECL_CONSTEXPR bool isReferenceCountingWaitFree() Q_DECL_NOTHROW { return false; }
template <typename T>
static inline bool ref(std::atomic<T> &_q_value)
@@ -147,7 +271,8 @@ template <typename X> struct QAtomicOps
return --_q_value != 0;
}
- static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW { return false; }
+ static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW
+ { return QAtomicTraits<sizeof(X)>::isLockFree(); }
static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return false; }
template <typename T>
@@ -186,7 +311,7 @@ template <typename X> struct QAtomicOps
return tmp;
}
- static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return false; }
+ static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return isTestAndSetNative(); }
static inline Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() Q_DECL_NOTHROW { return false; }
template <typename T>
@@ -213,7 +338,7 @@ template <typename X> struct QAtomicOps
return _q_value.exchange(newValue, std::memory_order_acq_rel);
}
- static inline Q_DECL_CONSTEXPR bool isFetchAndAddNative() Q_DECL_NOTHROW { return false; }
+ static inline Q_DECL_CONSTEXPR bool isFetchAndAddNative() Q_DECL_NOTHROW { return isTestAndSetNative(); }
static inline Q_DECL_CONSTEXPR bool isFetchAndAddWaitFree() Q_DECL_NOTHROW { return false; }
template <typename T> static inline