summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/thread')
-rw-r--r--src/corelib/thread/qatomic.cpp75
-rw-r--r--src/corelib/thread/qatomic.h24
-rw-r--r--src/corelib/thread/qatomic_bootstrap.h10
-rw-r--r--src/corelib/thread/qatomic_cxx11.h106
-rw-r--r--src/corelib/thread/qatomic_msvc.h94
-rw-r--r--src/corelib/thread/qbasicatomic.h206
-rw-r--r--src/corelib/thread/qfutex_p.h32
-rw-r--r--src/corelib/thread/qfuture.h82
-rw-r--r--src/corelib/thread/qfutureinterface.cpp42
-rw-r--r--src/corelib/thread/qfutureinterface_p.h4
-rw-r--r--src/corelib/thread/qfuturewatcher.cpp8
-rw-r--r--src/corelib/thread/qgenericatomic.h120
-rw-r--r--src/corelib/thread/qmutex.cpp58
-rw-r--r--src/corelib/thread/qmutex.h56
-rw-r--r--src/corelib/thread/qmutex_linux.cpp12
-rw-r--r--src/corelib/thread/qmutex_mac.cpp2
-rw-r--r--src/corelib/thread/qmutex_p.h14
-rw-r--r--src/corelib/thread/qmutex_unix.cpp6
-rw-r--r--src/corelib/thread/qmutex_win.cpp2
-rw-r--r--src/corelib/thread/qmutexpool.cpp6
-rw-r--r--src/corelib/thread/qmutexpool_p.h2
-rw-r--r--src/corelib/thread/qorderedmutexlocker_p.h62
-rw-r--r--src/corelib/thread/qreadwritelock.cpp12
-rw-r--r--src/corelib/thread/qreadwritelock.h36
-rw-r--r--src/corelib/thread/qresultstore.cpp15
-rw-r--r--src/corelib/thread/qresultstore.h6
-rw-r--r--src/corelib/thread/qsemaphore.cpp10
-rw-r--r--src/corelib/thread/qsemaphore.h14
-rw-r--r--src/corelib/thread/qthread.cpp14
-rw-r--r--src/corelib/thread/qthread.h6
-rw-r--r--src/corelib/thread/qthread_p.h23
-rw-r--r--src/corelib/thread/qthread_unix.cpp48
-rw-r--r--src/corelib/thread/qthread_win.cpp20
-rw-r--r--src/corelib/thread/qthreadpool_p.h2
-rw-r--r--src/corelib/thread/qthreadstorage.cpp6
-rw-r--r--src/corelib/thread/qthreadstorage.h4
-rw-r--r--src/corelib/thread/qwaitcondition_unix.cpp2
37 files changed, 741 insertions, 500 deletions
diff --git a/src/corelib/thread/qatomic.cpp b/src/corelib/thread/qatomic.cpp
index c161bec537..b1a7edad91 100644
--- a/src/corelib/thread/qatomic.cpp
+++ b/src/corelib/thread/qatomic.cpp
@@ -258,12 +258,26 @@
/*!
\fn template <typename T> T QAtomicInteger<T>::load() const
+ \obsolete
+
+ Use loadRelaxed() instead.
Atomically loads the value of this QAtomicInteger using relaxed memory
ordering. The value is not modified in any way, but note that there's no
guarantee that it remains so.
- \sa store(), loadAcquire()
+ \sa storeRelaxed(), loadAcquire()
+*/
+
+/*!
+ \fn template <typename T> T QAtomicInteger<T>::loadRelaxed() const
+ \since 5.14
+
+ Atomically loads the value of this QAtomicInteger using relaxed memory
+ ordering. The value is not modified in any way, but note that there's no
+ guarantee that it remains so.
+
+ \sa storeRelaxed(), loadAcquire()
*/
/*!
@@ -273,16 +287,29 @@
ordering. The value is not modified in any way, but note that there's no
guarantee that it remains so.
- \sa store(), load()
+ \sa storeRelaxed(), loadRelaxed()
*/
/*!
\fn template <typename T> void QAtomicInteger<T>::store(T newValue)
+ \obsolete
+
+ Use storeRelaxed() instead.
Atomically stores the \a newValue value into this atomic type, using
relaxed memory ordering.
- \sa storeRelease(), load()
+ \sa storeRelease(), loadRelaxed()
+*/
+
+/*!
+ \fn template <typename T> void QAtomicInteger<T>::storeRelaxed(T newValue)
+ \since 5.14
+
+ Atomically stores the \a newValue value into this atomic type, using
+ relaxed memory ordering.
+
+ \sa storeRelease(), loadRelaxed()
*/
/*!
@@ -291,7 +318,7 @@
Atomically stores the \a newValue value into this atomic type, using
the "Release" memory ordering.
- \sa store(), load()
+ \sa store(), loadAcquire()
*/
/*!
@@ -303,7 +330,7 @@
value is not modified in any way, but note that there's no guarantee that
it remains so.
- \sa load(), loadAcquire()
+ \sa loadRelaxed(), loadAcquire()
*/
/*!
@@ -314,7 +341,7 @@
sequentially consistent memory ordering if possible; or "Release" ordering
if not. This function returns a reference to this object.
- \sa store(), storeRelease()
+ \sa storeRelaxed(), storeRelease()
*/
/*! \fn template <typename T> bool QAtomicInteger<T>::isReferenceCountingNative()
@@ -1278,31 +1305,59 @@
/*!
\fn template <typename T> T *QAtomicPointer<T>::load() const
+ \obsolete
+
+ Use loadRelaxed() instead.
Atomically loads the value of this QAtomicPointer using relaxed memory
ordering. The value is not modified in any way, but note that there's no
guarantee that it remains so.
- \sa store(), loadAcquire()
+ \sa storeRelaxed(), loadAcquire()
*/
/*!
+ \fn template <typename T> T *QAtomicPointer<T>::loadRelaxed() const
+ \since 5.14
+
+ Atomically loads the value of this QAtomicPointer using relaxed memory
+ ordering. The value is not modified in any way, but note that there's no
+ guarantee that it remains so.
+
+ \sa storeRelaxed(), loadAcquire()
+*/
+
+
+/*!
\fn template <typename T> T *QAtomicPointer<T>::loadAcquire() const
Atomically loads the value of this QAtomicPointer using the "Acquire" memory
ordering. The value is not modified in any way, but note that there's no
guarantee that it remains so.
- \sa store(), load()
+ \sa storeRelease(), loadRelaxed()
*/
/*!
\fn template <typename T> void QAtomicPointer<T>::store(T *newValue)
+ \obsolete
+
+ Use storeRelaxed() instead.
+
+ Atomically stores the \a newValue value into this atomic type, using
+ relaxed memory ordering.
+
+ \sa storeRelease(), loadRelaxed()
+*/
+
+/*!
+ \fn template <typename T> void QAtomicPointer<T>::storeRelaxed(T *newValue)
+ \since 5.14
Atomically stores the \a newValue value into this atomic type, using
relaxed memory ordering.
- \sa storeRelease(), load()
+ \sa storeRelease(), loadRelaxed()
*/
/*!
@@ -1311,7 +1366,7 @@
Atomically stores the \a newValue value into this atomic type, using
the "Release" memory ordering.
- \sa store(), load()
+ \sa storeRelaxed(), loadRelaxed()
*/
/*! \fn template <typename T> bool QAtomicPointer<T>::isTestAndSetNative()
diff --git a/src/corelib/thread/qatomic.h b/src/corelib/thread/qatomic.h
index f842534c38..a3b9be0729 100644
--- a/src/corelib/thread/qatomic.h
+++ b/src/corelib/thread/qatomic.h
@@ -57,15 +57,15 @@ class QAtomicInteger : public QBasicAtomicInteger<T>
public:
// Non-atomic API
#ifdef QT_BASIC_ATOMIC_HAS_CONSTRUCTORS
- constexpr QAtomicInteger(T value = 0) Q_DECL_NOTHROW : QBasicAtomicInteger<T>(value) {}
+ constexpr QAtomicInteger(T value = 0) noexcept : QBasicAtomicInteger<T>(value) {}
#else
- inline QAtomicInteger(T value = 0) Q_DECL_NOTHROW
+ inline QAtomicInteger(T value = 0) noexcept
{
this->_q_value = value;
}
#endif
- inline QAtomicInteger(const QAtomicInteger &other) Q_DECL_NOTHROW
+ inline QAtomicInteger(const QAtomicInteger &other) noexcept
#ifdef QT_BASIC_ATOMIC_HAS_CONSTRUCTORS
: QBasicAtomicInteger<T>()
#endif
@@ -73,7 +73,7 @@ public:
this->storeRelease(other.loadAcquire());
}
- inline QAtomicInteger &operator=(const QAtomicInteger &other) Q_DECL_NOTHROW
+ inline QAtomicInteger &operator=(const QAtomicInteger &other) noexcept
{
this->storeRelease(other.loadAcquire());
return *this;
@@ -81,8 +81,10 @@ public:
#ifdef Q_CLANG_QDOC
T load() const;
+ T loadRelaxed() const;
T loadAcquire() const;
void store(T newValue);
+ void storeRelaxed(T newValue);
void storeRelease(T newValue);
operator T() const;
@@ -159,7 +161,7 @@ public:
#ifdef QT_BASIC_ATOMIC_HAS_CONSTRUCTORS
constexpr
#endif
- QAtomicInt(int value = 0) Q_DECL_NOTHROW : QAtomicInteger<int>(value) {}
+ QAtomicInt(int value = 0) noexcept : QAtomicInteger<int>(value) {}
};
// High-level atomic pointer operations
@@ -168,14 +170,14 @@ class QAtomicPointer : public QBasicAtomicPointer<T>
{
public:
#ifdef QT_BASIC_ATOMIC_HAS_CONSTRUCTORS
- constexpr QAtomicPointer(T *value = nullptr) Q_DECL_NOTHROW : QBasicAtomicPointer<T>(value) {}
+ constexpr QAtomicPointer(T *value = nullptr) noexcept : QBasicAtomicPointer<T>(value) {}
#else
- inline QAtomicPointer(T *value = nullptr) Q_DECL_NOTHROW
+ inline QAtomicPointer(T *value = nullptr) noexcept
{
- this->store(value);
+ this->storeRelaxed(value);
}
#endif
- inline QAtomicPointer(const QAtomicPointer<T> &other) Q_DECL_NOTHROW
+ inline QAtomicPointer(const QAtomicPointer<T> &other) noexcept
#ifdef QT_BASIC_ATOMIC_HAS_CONSTRUCTORS
: QBasicAtomicPointer<T>()
#endif
@@ -183,7 +185,7 @@ public:
this->storeRelease(other.loadAcquire());
}
- inline QAtomicPointer<T> &operator=(const QAtomicPointer<T> &other) Q_DECL_NOTHROW
+ inline QAtomicPointer<T> &operator=(const QAtomicPointer<T> &other) noexcept
{
this->storeRelease(other.loadAcquire());
return *this;
@@ -255,7 +257,7 @@ inline void qAtomicAssign(T *&d, T *x)
template <typename T>
inline void qAtomicDetach(T *&d)
{
- if (d->ref.load() == 1)
+ if (d->ref.loadRelaxed() == 1)
return;
T *x = d;
d = new T(*d);
diff --git a/src/corelib/thread/qatomic_bootstrap.h b/src/corelib/thread/qatomic_bootstrap.h
index b463f817bd..c4279ee7b1 100644
--- a/src/corelib/thread/qatomic_bootstrap.h
+++ b/src/corelib/thread/qatomic_bootstrap.h
@@ -56,16 +56,16 @@ template <typename T> struct QAtomicOps: QGenericAtomicOps<QAtomicOps<T> >
{
typedef T Type;
- static bool ref(T &_q_value) Q_DECL_NOTHROW
+ static bool ref(T &_q_value) noexcept
{
return ++_q_value != 0;
}
- static bool deref(T &_q_value) Q_DECL_NOTHROW
+ static bool deref(T &_q_value) noexcept
{
return --_q_value != 0;
}
- static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue = 0) Q_DECL_NOTHROW
+ static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue = nullptr) noexcept
{
if (currentValue)
*currentValue = _q_value;
@@ -76,7 +76,7 @@ template <typename T> struct QAtomicOps: QGenericAtomicOps<QAtomicOps<T> >
return false;
}
- static T fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW
+ static T fetchAndStoreRelaxed(T &_q_value, T newValue) noexcept
{
T tmp = _q_value;
_q_value = newValue;
@@ -84,7 +84,7 @@ template <typename T> struct QAtomicOps: QGenericAtomicOps<QAtomicOps<T> >
}
template <typename AdditiveType> static
- T fetchAndAddRelaxed(T &_q_value, AdditiveType valueToAdd) Q_DECL_NOTHROW
+ T fetchAndAddRelaxed(T &_q_value, AdditiveType valueToAdd) noexcept
{
T returnValue = _q_value;
_q_value += valueToAdd;
diff --git a/src/corelib/thread/qatomic_cxx11.h b/src/corelib/thread/qatomic_cxx11.h
index 2fc0bf5419..7386aee126 100644
--- a/src/corelib/thread/qatomic_cxx11.h
+++ b/src/corelib/thread/qatomic_cxx11.h
@@ -222,43 +222,61 @@ template <typename X> struct QAtomicOps
typedef std::atomic<X> Type;
template <typename T> static inline
- T load(const std::atomic<T> &_q_value) Q_DECL_NOTHROW
+ T load(const std::atomic<T> &_q_value) noexcept
{
return _q_value.load(std::memory_order_relaxed);
}
template <typename T> static inline
- T load(const volatile std::atomic<T> &_q_value) Q_DECL_NOTHROW
+ T load(const volatile std::atomic<T> &_q_value) noexcept
{
return _q_value.load(std::memory_order_relaxed);
}
template <typename T> static inline
- T loadAcquire(const std::atomic<T> &_q_value) Q_DECL_NOTHROW
+ T loadRelaxed(const std::atomic<T> &_q_value) noexcept
+ {
+ return _q_value.load(std::memory_order_relaxed);
+ }
+
+ template <typename T> static inline
+ T loadRelaxed(const volatile std::atomic<T> &_q_value) noexcept
+ {
+ return _q_value.load(std::memory_order_relaxed);
+ }
+
+ template <typename T> static inline
+ T loadAcquire(const std::atomic<T> &_q_value) noexcept
{
return _q_value.load(std::memory_order_acquire);
}
template <typename T> static inline
- T loadAcquire(const volatile std::atomic<T> &_q_value) Q_DECL_NOTHROW
+ T loadAcquire(const volatile std::atomic<T> &_q_value) noexcept
{
return _q_value.load(std::memory_order_acquire);
}
template <typename T> static inline
- void store(std::atomic<T> &_q_value, T newValue) Q_DECL_NOTHROW
+ void store(std::atomic<T> &_q_value, T newValue) noexcept
+ {
+ _q_value.store(newValue, std::memory_order_relaxed);
+ }
+
+ template <typename T> static inline
+ void storeRelaxed(std::atomic<T> &_q_value, T newValue) noexcept
{
_q_value.store(newValue, std::memory_order_relaxed);
}
template <typename T> static inline
- void storeRelease(std::atomic<T> &_q_value, T newValue) Q_DECL_NOTHROW
+ void storeRelease(std::atomic<T> &_q_value, T newValue) noexcept
{
_q_value.store(newValue, std::memory_order_release);
}
- static inline Q_DECL_CONSTEXPR bool isReferenceCountingNative() Q_DECL_NOTHROW { return isTestAndSetNative(); }
- static inline Q_DECL_CONSTEXPR bool isReferenceCountingWaitFree() Q_DECL_NOTHROW { return false; }
+ static inline Q_DECL_CONSTEXPR bool isReferenceCountingNative() noexcept { return isTestAndSetNative(); }
+ static inline Q_DECL_CONSTEXPR bool isReferenceCountingWaitFree() noexcept { return false; }
template <typename T>
static inline bool ref(std::atomic<T> &_q_value)
{
@@ -266,17 +284,17 @@ template <typename X> struct QAtomicOps
}
template <typename T>
- static inline bool deref(std::atomic<T> &_q_value) Q_DECL_NOTHROW
+ static inline bool deref(std::atomic<T> &_q_value) noexcept
{
return --_q_value != 0;
}
- static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW
+ static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() noexcept
{ return QAtomicTraits<sizeof(X)>::isLockFree(); }
- static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return false; }
+ static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() noexcept { return false; }
template <typename T>
- static bool testAndSetRelaxed(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = nullptr) Q_DECL_NOTHROW
+ static bool testAndSetRelaxed(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = nullptr) noexcept
{
bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_relaxed, std::memory_order_relaxed);
if (currentValue)
@@ -285,7 +303,7 @@ template <typename X> struct QAtomicOps
}
template <typename T>
- static bool testAndSetAcquire(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = nullptr) Q_DECL_NOTHROW
+ static bool testAndSetAcquire(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = nullptr) noexcept
{
bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acquire, std::memory_order_acquire);
if (currentValue)
@@ -294,7 +312,7 @@ template <typename X> struct QAtomicOps
}
template <typename T>
- static bool testAndSetRelease(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = nullptr) Q_DECL_NOTHROW
+ static bool testAndSetRelease(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = nullptr) noexcept
{
bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_release, std::memory_order_relaxed);
if (currentValue)
@@ -303,7 +321,7 @@ template <typename X> struct QAtomicOps
}
template <typename T>
- static bool testAndSetOrdered(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = nullptr) Q_DECL_NOTHROW
+ static bool testAndSetOrdered(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = nullptr) noexcept
{
bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acq_rel, std::memory_order_acquire);
if (currentValue)
@@ -311,158 +329,158 @@ template <typename X> struct QAtomicOps
return tmp;
}
- static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return isTestAndSetNative(); }
- static inline Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() Q_DECL_NOTHROW { return false; }
+ static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() noexcept { return isTestAndSetNative(); }
+ static inline Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() noexcept { return false; }
template <typename T>
- static T fetchAndStoreRelaxed(std::atomic<T> &_q_value, T newValue) Q_DECL_NOTHROW
+ static T fetchAndStoreRelaxed(std::atomic<T> &_q_value, T newValue) noexcept
{
return _q_value.exchange(newValue, std::memory_order_relaxed);
}
template <typename T>
- static T fetchAndStoreAcquire(std::atomic<T> &_q_value, T newValue) Q_DECL_NOTHROW
+ static T fetchAndStoreAcquire(std::atomic<T> &_q_value, T newValue) noexcept
{
return _q_value.exchange(newValue, std::memory_order_acquire);
}
template <typename T>
- static T fetchAndStoreRelease(std::atomic<T> &_q_value, T newValue) Q_DECL_NOTHROW
+ static T fetchAndStoreRelease(std::atomic<T> &_q_value, T newValue) noexcept
{
return _q_value.exchange(newValue, std::memory_order_release);
}
template <typename T>
- static T fetchAndStoreOrdered(std::atomic<T> &_q_value, T newValue) Q_DECL_NOTHROW
+ static T fetchAndStoreOrdered(std::atomic<T> &_q_value, T newValue) noexcept
{
return _q_value.exchange(newValue, std::memory_order_acq_rel);
}
- static inline Q_DECL_CONSTEXPR bool isFetchAndAddNative() Q_DECL_NOTHROW { return isTestAndSetNative(); }
- static inline Q_DECL_CONSTEXPR bool isFetchAndAddWaitFree() Q_DECL_NOTHROW { return false; }
+ static inline Q_DECL_CONSTEXPR bool isFetchAndAddNative() noexcept { return isTestAndSetNative(); }
+ static inline Q_DECL_CONSTEXPR bool isFetchAndAddWaitFree() noexcept { return false; }
template <typename T> static inline
- T fetchAndAddRelaxed(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+ T fetchAndAddRelaxed(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
{
return _q_value.fetch_add(valueToAdd, std::memory_order_relaxed);
}
template <typename T> static inline
- T fetchAndAddAcquire(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+ T fetchAndAddAcquire(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
{
return _q_value.fetch_add(valueToAdd, std::memory_order_acquire);
}
template <typename T> static inline
- T fetchAndAddRelease(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+ T fetchAndAddRelease(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
{
return _q_value.fetch_add(valueToAdd, std::memory_order_release);
}
template <typename T> static inline
- T fetchAndAddOrdered(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+ T fetchAndAddOrdered(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
{
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
+ T fetchAndSubRelaxed(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
{
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
+ T fetchAndSubAcquire(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
{
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
+ T fetchAndSubRelease(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
{
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
+ T fetchAndSubOrdered(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
{
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
+ T fetchAndAndRelaxed(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
{
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
+ T fetchAndAndAcquire(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
{
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
+ T fetchAndAndRelease(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
{
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
+ T fetchAndAndOrdered(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
{
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
+ T fetchAndOrRelaxed(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
{
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
+ T fetchAndOrAcquire(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
{
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
+ T fetchAndOrRelease(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
{
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
+ T fetchAndOrOrdered(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
{
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
+ T fetchAndXorRelaxed(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
{
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
+ T fetchAndXorAcquire(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
{
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
+ T fetchAndXorRelease(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
{
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
+ T fetchAndXorOrdered(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
{
return _q_value.fetch_xor(valueToAdd, std::memory_order_acq_rel);
}
};
-#if defined(Q_COMPILER_CONSTEXPR) && defined(Q_COMPILER_DEFAULT_MEMBERS) && defined(Q_COMPILER_DELETE_MEMBERS)
+#if defined(Q_COMPILER_CONSTEXPR)
# define Q_BASIC_ATOMIC_INITIALIZER(a) { a }
#else
# define Q_BASIC_ATOMIC_INITIALIZER(a) { ATOMIC_VAR_INIT(a) }
diff --git a/src/corelib/thread/qatomic_msvc.h b/src/corelib/thread/qatomic_msvc.h
index 5eae2bdc48..67b5224cd7 100644
--- a/src/corelib/thread/qatomic_msvc.h
+++ b/src/corelib/thread/qatomic_msvc.h
@@ -269,24 +269,24 @@ template <> struct QAtomicWindowsType<4> { typedef long Type; };
template <int N> struct QAtomicOpsBySize : QGenericAtomicOps<QAtomicOpsBySize<N> >
{
- static inline Q_DECL_CONSTEXPR bool isReferenceCountingNative() Q_DECL_NOTHROW { return true; }
- static inline Q_DECL_CONSTEXPR bool isReferenceCountingWaitFree() Q_DECL_NOTHROW { return true; }
- template <typename T> static bool ref(T &_q_value) Q_DECL_NOTHROW;
- template <typename T> static bool deref(T &_q_value) Q_DECL_NOTHROW;
-
- static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW { return true; }
- static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return true; }
- template <typename T> static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW;
+ static inline Q_DECL_CONSTEXPR bool isReferenceCountingNative() noexcept { return true; }
+ static inline Q_DECL_CONSTEXPR bool isReferenceCountingWaitFree() noexcept { return true; }
+ template <typename T> static bool ref(T &_q_value) noexcept;
+ template <typename T> static bool deref(T &_q_value) noexcept;
+
+ static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() noexcept { return true; }
+ static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() noexcept { return true; }
+ template <typename T> static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) noexcept;
template <typename T>
- static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW;
+ static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) noexcept;
- static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return true; }
- static inline Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() Q_DECL_NOTHROW { return true; }
- template <typename T> static T fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW;
+ static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() noexcept { return true; }
+ static inline Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() noexcept { return true; }
+ template <typename T> static T fetchAndStoreRelaxed(T &_q_value, T newValue) noexcept;
- static inline Q_DECL_CONSTEXPR bool isFetchAndAddNative() Q_DECL_NOTHROW { return true; }
- static inline Q_DECL_CONSTEXPR bool isFetchAndAddWaitFree() Q_DECL_NOTHROW { return true; }
- template <typename T> static T fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW;
+ static inline Q_DECL_CONSTEXPR bool isFetchAndAddNative() noexcept { return true; }
+ static inline Q_DECL_CONSTEXPR bool isFetchAndAddWaitFree() noexcept { return true; }
+ template <typename T> static T fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept;
private:
typedef typename QAtomicWindowsType<N>::Type Type;
@@ -303,76 +303,76 @@ struct QAtomicOps : QAtomicOpsBySize<sizeof(T)>
};
template<> template<typename T>
-inline bool QAtomicOpsBySize<4>::ref(T &_q_value) Q_DECL_NOTHROW
+inline bool QAtomicOpsBySize<4>::ref(T &_q_value) noexcept
{
return QT_INTERLOCKED_FUNCTION(Increment)(atomic(&_q_value)) != 0;
}
template<> template<typename T>
-inline bool QAtomicOpsBySize<4>::deref(T &_q_value) Q_DECL_NOTHROW
+inline bool QAtomicOpsBySize<4>::deref(T &_q_value) noexcept
{
return QT_INTERLOCKED_FUNCTION(Decrement)(atomic(&_q_value)) != 0;
}
template<> template<typename T>
-inline bool QAtomicOpsBySize<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW
+inline bool QAtomicOpsBySize<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) noexcept
{
return QT_INTERLOCKED_FUNCTION(CompareExchange)(atomic(&_q_value), value(newValue), value(expectedValue)) == value(expectedValue);
}
template<> template <typename T>
-inline bool QAtomicOpsBySize<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW
+inline bool QAtomicOpsBySize<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) noexcept
{
*currentValue = T(QT_INTERLOCKED_FUNCTION(CompareExchange)(atomic(&_q_value), newValue, expectedValue));
return *currentValue == expectedValue;
}
template<> template<typename T>
-inline T QAtomicOpsBySize<4>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW
+inline T QAtomicOpsBySize<4>::fetchAndStoreRelaxed(T &_q_value, T newValue) noexcept
{
return QT_INTERLOCKED_FUNCTION(Exchange)(atomic(&_q_value), value(newValue));
}
template<> template<typename T>
-inline T QAtomicOpsBySize<4>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+inline T QAtomicOpsBySize<4>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
{
return QT_INTERLOCKED_FUNCTION(ExchangeAdd)(atomic(&_q_value), value<T>(valueToAdd * QAtomicAdditiveType<T>::AddScale));
}
#ifdef Q_ATOMIC_INT16_IS_SUPPORTED
template<> template<typename T>
-inline bool QAtomicOpsBySize<2>::ref(T &_q_value) Q_DECL_NOTHROW
+inline bool QAtomicOpsBySize<2>::ref(T &_q_value) noexcept
{
return QT_INTERLOCKED_FUNCTION(Increment16)(atomic(&_q_value)) != 0;
}
template<> template<typename T>
-inline bool QAtomicOpsBySize<2>::deref(T &_q_value) Q_DECL_NOTHROW
+inline bool QAtomicOpsBySize<2>::deref(T &_q_value) noexcept
{
return QT_INTERLOCKED_FUNCTION(Decrement16)(atomic(&_q_value)) != 0;
}
template<> template<typename T>
-inline bool QAtomicOpsBySize<2>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW
+inline bool QAtomicOpsBySize<2>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) noexcept
{
return QT_INTERLOCKED_FUNCTION(CompareExchange16)(atomic(&_q_value), value(newValue), value(expectedValue)) == value(expectedValue);
}
template<> template <typename T>
-inline bool QAtomicOpsBySize<2>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW
+inline bool QAtomicOpsBySize<2>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) noexcept
{
*currentValue = T(QT_INTERLOCKED_FUNCTION(CompareExchange16)(atomic(&_q_value), newValue, expectedValue));
return *currentValue == expectedValue;
}
template<> template<typename T>
-inline T QAtomicOpsBySize<2>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW
+inline T QAtomicOpsBySize<2>::fetchAndStoreRelaxed(T &_q_value, T newValue) noexcept
{
return QT_INTERLOCKED_FUNCTION(Exchange16)(atomic(&_q_value), value(newValue));
}
template<> template<typename T>
-inline T QAtomicOpsBySize<2>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+inline T QAtomicOpsBySize<2>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
{
return QT_INTERLOCKED_FUNCTION(ExchangeAdd16)(atomic(&_q_value), value<T>(valueToAdd * QAtomicAdditiveType<T>::AddScale));
}
@@ -380,38 +380,38 @@ inline T QAtomicOpsBySize<2>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAd
#ifdef Q_ATOMIC_INT64_IS_SUPPORTED
template<> template<typename T>
-inline bool QAtomicOpsBySize<8>::ref(T &_q_value) Q_DECL_NOTHROW
+inline bool QAtomicOpsBySize<8>::ref(T &_q_value) noexcept
{
return QT_INTERLOCKED_FUNCTION(Increment64)(atomic(&_q_value)) != 0;
}
template<> template<typename T>
-inline bool QAtomicOpsBySize<8>::deref(T &_q_value) Q_DECL_NOTHROW
+inline bool QAtomicOpsBySize<8>::deref(T &_q_value) noexcept
{
return QT_INTERLOCKED_FUNCTION(Decrement64)(atomic(&_q_value)) != 0;
}
template<> template<typename T>
-inline bool QAtomicOpsBySize<8>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW
+inline bool QAtomicOpsBySize<8>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) noexcept
{
return QT_INTERLOCKED_FUNCTION(CompareExchange64)(atomic(&_q_value), value(newValue), value(expectedValue)) == value(expectedValue);
}
template<> template <typename T>
-inline bool QAtomicOpsBySize<8>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW
+inline bool QAtomicOpsBySize<8>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) noexcept
{
*currentValue = T(QT_INTERLOCKED_FUNCTION(CompareExchange64)(atomic(&_q_value), newValue, expectedValue));
return *currentValue == expectedValue;
}
template<> template<typename T>
-inline T QAtomicOpsBySize<8>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW
+inline T QAtomicOpsBySize<8>::fetchAndStoreRelaxed(T &_q_value, T newValue) noexcept
{
return QT_INTERLOCKED_FUNCTION(Exchange64)(atomic(&_q_value), value(newValue));
}
template<> template<typename T>
-inline T QAtomicOpsBySize<8>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+inline T QAtomicOpsBySize<8>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
{
return QT_INTERLOCKED_FUNCTION(ExchangeAdd64)(atomic(&_q_value), value<T>(valueToAdd * QAtomicAdditiveType<T>::AddScale));
}
@@ -423,41 +423,41 @@ struct QAtomicOps<T *> : QGenericAtomicOps<QAtomicOps<T *> >
{
typedef T *Type;
- static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW { return true; }
- static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return true; }
- static bool testAndSetRelaxed(T *&_q_value, T *expectedValue, T *newValue) Q_DECL_NOTHROW;
- static bool testAndSetRelaxed(T *&_q_value, T *expectedValue, T *newValue, T **currentValue) Q_DECL_NOTHROW;
+ static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() noexcept { return true; }
+ static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() noexcept { return true; }
+ static bool testAndSetRelaxed(T *&_q_value, T *expectedValue, T *newValue) noexcept;
+ static bool testAndSetRelaxed(T *&_q_value, T *expectedValue, T *newValue, T **currentValue) noexcept;
- static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return true; }
- static inline Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() Q_DECL_NOTHROW { return true; }
- static T *fetchAndStoreRelaxed(T *&_q_value, T *newValue) Q_DECL_NOTHROW;
+ static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() noexcept { return true; }
+ static inline Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() noexcept { return true; }
+ static T *fetchAndStoreRelaxed(T *&_q_value, T *newValue) noexcept;
- static inline Q_DECL_CONSTEXPR bool isFetchAndAddNative() Q_DECL_NOTHROW { return true; }
- static inline Q_DECL_CONSTEXPR bool isFetchAndAddWaitFree() Q_DECL_NOTHROW { return true; }
- static T *fetchAndAddRelaxed(T *&_q_value, qptrdiff valueToAdd) Q_DECL_NOTHROW;
+ static inline Q_DECL_CONSTEXPR bool isFetchAndAddNative() noexcept { return true; }
+ static inline Q_DECL_CONSTEXPR bool isFetchAndAddWaitFree() noexcept { return true; }
+ static T *fetchAndAddRelaxed(T *&_q_value, qptrdiff valueToAdd) noexcept;
};
template <typename T>
-inline bool QAtomicOps<T *>::testAndSetRelaxed(T *&_q_value, T *expectedValue, T *newValue) Q_DECL_NOTHROW
+inline bool QAtomicOps<T *>::testAndSetRelaxed(T *&_q_value, T *expectedValue, T *newValue) noexcept
{
return QT_INTERLOCKED_COMPARE_EXCHANGE_POINTER(&_q_value, newValue, expectedValue) == expectedValue;
}
template <typename T>
-inline bool QAtomicOps<T *>::testAndSetRelaxed(T *&_q_value, T *expectedValue, T *newValue, T **currentValue) Q_DECL_NOTHROW
+inline bool QAtomicOps<T *>::testAndSetRelaxed(T *&_q_value, T *expectedValue, T *newValue, T **currentValue) noexcept
{
*currentValue = reinterpret_cast<T *>(QT_INTERLOCKED_COMPARE_EXCHANGE_POINTER(&_q_value, newValue, expectedValue));
return *currentValue == expectedValue;
}
template <typename T>
-inline T *QAtomicOps<T *>::fetchAndStoreRelaxed(T *&_q_value, T *newValue) Q_DECL_NOTHROW
+inline T *QAtomicOps<T *>::fetchAndStoreRelaxed(T *&_q_value, T *newValue) noexcept
{
return reinterpret_cast<T *>(QT_INTERLOCKED_EXCHANGE_POINTER(&_q_value, newValue));
}
template <typename T>
-inline T *QAtomicOps<T *>::fetchAndAddRelaxed(T *&_q_value, qptrdiff valueToAdd) Q_DECL_NOTHROW
+inline T *QAtomicOps<T *>::fetchAndAddRelaxed(T *&_q_value, qptrdiff valueToAdd) noexcept
{
return reinterpret_cast<T *>(QT_INTERLOCKED_EXCHANGE_ADD_POINTER(&_q_value, valueToAdd * sizeof(T)));
}
diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h
index 6b6ac10713..9804e60119 100644
--- a/src/corelib/thread/qbasicatomic.h
+++ b/src/corelib/thread/qbasicatomic.h
@@ -75,7 +75,7 @@ QT_END_NAMESPACE
// New atomics
-#if defined(Q_COMPILER_CONSTEXPR) && defined(Q_COMPILER_DEFAULT_MEMBERS) && defined(Q_COMPILER_DELETE_MEMBERS)
+#if defined(Q_COMPILER_CONSTEXPR)
# if defined(Q_CC_CLANG) && Q_CC_CLANG < 303
/*
Do not define QT_BASIC_ATOMIC_HAS_CONSTRUCTORS for Clang before version 3.3.
@@ -99,126 +99,130 @@ public:
typename Ops::Type _q_value;
// Everything below is either implemented in ../arch/qatomic_XXX.h or (as fallback) in qgenericatomic.h
+#if QT_DEPRECATED_SINCE(5, 14)
+ QT_DEPRECATED_VERSION_X_5_14("Use loadRelaxed") T load() const noexcept { return loadRelaxed(); }
+ QT_DEPRECATED_VERSION_X_5_14("Use storeRelaxed") void store(T newValue) noexcept { storeRelaxed(newValue); }
+#endif
- T load() const Q_DECL_NOTHROW { return Ops::load(_q_value); }
- void store(T newValue) Q_DECL_NOTHROW { Ops::store(_q_value, newValue); }
+ T loadRelaxed() const noexcept { return Ops::loadRelaxed(_q_value); }
+ void storeRelaxed(T newValue) noexcept { Ops::storeRelaxed(_q_value, newValue); }
- T loadAcquire() const Q_DECL_NOTHROW { return Ops::loadAcquire(_q_value); }
- void storeRelease(T newValue) Q_DECL_NOTHROW { Ops::storeRelease(_q_value, newValue); }
- operator T() const Q_DECL_NOTHROW { return loadAcquire(); }
- T operator=(T newValue) Q_DECL_NOTHROW { storeRelease(newValue); return newValue; }
+ T loadAcquire() const noexcept { return Ops::loadAcquire(_q_value); }
+ void storeRelease(T newValue) noexcept { Ops::storeRelease(_q_value, newValue); }
+ operator T() const noexcept { return loadAcquire(); }
+ T operator=(T newValue) noexcept { storeRelease(newValue); return newValue; }
- static Q_DECL_CONSTEXPR bool isReferenceCountingNative() Q_DECL_NOTHROW { return Ops::isReferenceCountingNative(); }
- static Q_DECL_CONSTEXPR bool isReferenceCountingWaitFree() Q_DECL_NOTHROW { return Ops::isReferenceCountingWaitFree(); }
+ static Q_DECL_CONSTEXPR bool isReferenceCountingNative() noexcept { return Ops::isReferenceCountingNative(); }
+ static Q_DECL_CONSTEXPR bool isReferenceCountingWaitFree() noexcept { return Ops::isReferenceCountingWaitFree(); }
- bool ref() Q_DECL_NOTHROW { return Ops::ref(_q_value); }
- bool deref() Q_DECL_NOTHROW { return Ops::deref(_q_value); }
+ bool ref() noexcept { return Ops::ref(_q_value); }
+ bool deref() noexcept { return Ops::deref(_q_value); }
- static Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW { return Ops::isTestAndSetNative(); }
- static Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return Ops::isTestAndSetWaitFree(); }
+ static Q_DECL_CONSTEXPR bool isTestAndSetNative() noexcept { return Ops::isTestAndSetNative(); }
+ static Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() noexcept { return Ops::isTestAndSetWaitFree(); }
- bool testAndSetRelaxed(T expectedValue, T newValue) Q_DECL_NOTHROW
+ bool testAndSetRelaxed(T expectedValue, T newValue) noexcept
{ return Ops::testAndSetRelaxed(_q_value, expectedValue, newValue); }
- bool testAndSetAcquire(T expectedValue, T newValue) Q_DECL_NOTHROW
+ bool testAndSetAcquire(T expectedValue, T newValue) noexcept
{ return Ops::testAndSetAcquire(_q_value, expectedValue, newValue); }
- bool testAndSetRelease(T expectedValue, T newValue) Q_DECL_NOTHROW
+ bool testAndSetRelease(T expectedValue, T newValue) noexcept
{ return Ops::testAndSetRelease(_q_value, expectedValue, newValue); }
- bool testAndSetOrdered(T expectedValue, T newValue) Q_DECL_NOTHROW
+ bool testAndSetOrdered(T expectedValue, T newValue) noexcept
{ return Ops::testAndSetOrdered(_q_value, expectedValue, newValue); }
- bool testAndSetRelaxed(T expectedValue, T newValue, T &currentValue) Q_DECL_NOTHROW
+ bool testAndSetRelaxed(T expectedValue, T newValue, T &currentValue) noexcept
{ return Ops::testAndSetRelaxed(_q_value, expectedValue, newValue, &currentValue); }
- bool testAndSetAcquire(T expectedValue, T newValue, T &currentValue) Q_DECL_NOTHROW
+ bool testAndSetAcquire(T expectedValue, T newValue, T &currentValue) noexcept
{ return Ops::testAndSetAcquire(_q_value, expectedValue, newValue, &currentValue); }
- bool testAndSetRelease(T expectedValue, T newValue, T &currentValue) Q_DECL_NOTHROW
+ bool testAndSetRelease(T expectedValue, T newValue, T &currentValue) noexcept
{ return Ops::testAndSetRelease(_q_value, expectedValue, newValue, &currentValue); }
- bool testAndSetOrdered(T expectedValue, T newValue, T &currentValue) Q_DECL_NOTHROW
+ bool testAndSetOrdered(T expectedValue, T newValue, T &currentValue) noexcept
{ return Ops::testAndSetOrdered(_q_value, expectedValue, newValue, &currentValue); }
- static Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return Ops::isFetchAndStoreNative(); }
- static Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() Q_DECL_NOTHROW { return Ops::isFetchAndStoreWaitFree(); }
+ static Q_DECL_CONSTEXPR bool isFetchAndStoreNative() noexcept { return Ops::isFetchAndStoreNative(); }
+ static Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() noexcept { return Ops::isFetchAndStoreWaitFree(); }
- T fetchAndStoreRelaxed(T newValue) Q_DECL_NOTHROW
+ T fetchAndStoreRelaxed(T newValue) noexcept
{ return Ops::fetchAndStoreRelaxed(_q_value, newValue); }
- T fetchAndStoreAcquire(T newValue) Q_DECL_NOTHROW
+ T fetchAndStoreAcquire(T newValue) noexcept
{ return Ops::fetchAndStoreAcquire(_q_value, newValue); }
- T fetchAndStoreRelease(T newValue) Q_DECL_NOTHROW
+ T fetchAndStoreRelease(T newValue) noexcept
{ return Ops::fetchAndStoreRelease(_q_value, newValue); }
- T fetchAndStoreOrdered(T newValue) Q_DECL_NOTHROW
+ T fetchAndStoreOrdered(T newValue) noexcept
{ return Ops::fetchAndStoreOrdered(_q_value, newValue); }
- static Q_DECL_CONSTEXPR bool isFetchAndAddNative() Q_DECL_NOTHROW { return Ops::isFetchAndAddNative(); }
- static Q_DECL_CONSTEXPR bool isFetchAndAddWaitFree() Q_DECL_NOTHROW { return Ops::isFetchAndAddWaitFree(); }
+ static Q_DECL_CONSTEXPR bool isFetchAndAddNative() noexcept { return Ops::isFetchAndAddNative(); }
+ static Q_DECL_CONSTEXPR bool isFetchAndAddWaitFree() noexcept { return Ops::isFetchAndAddWaitFree(); }
- T fetchAndAddRelaxed(T valueToAdd) Q_DECL_NOTHROW
+ T fetchAndAddRelaxed(T valueToAdd) noexcept
{ return Ops::fetchAndAddRelaxed(_q_value, valueToAdd); }
- T fetchAndAddAcquire(T valueToAdd) Q_DECL_NOTHROW
+ T fetchAndAddAcquire(T valueToAdd) noexcept
{ return Ops::fetchAndAddAcquire(_q_value, valueToAdd); }
- T fetchAndAddRelease(T valueToAdd) Q_DECL_NOTHROW
+ T fetchAndAddRelease(T valueToAdd) noexcept
{ return Ops::fetchAndAddRelease(_q_value, valueToAdd); }
- T fetchAndAddOrdered(T valueToAdd) Q_DECL_NOTHROW
+ T fetchAndAddOrdered(T valueToAdd) noexcept
{ return Ops::fetchAndAddOrdered(_q_value, valueToAdd); }
- T fetchAndSubRelaxed(T valueToAdd) Q_DECL_NOTHROW
+ T fetchAndSubRelaxed(T valueToAdd) noexcept
{ return Ops::fetchAndSubRelaxed(_q_value, valueToAdd); }
- T fetchAndSubAcquire(T valueToAdd) Q_DECL_NOTHROW
+ T fetchAndSubAcquire(T valueToAdd) noexcept
{ return Ops::fetchAndSubAcquire(_q_value, valueToAdd); }
- T fetchAndSubRelease(T valueToAdd) Q_DECL_NOTHROW
+ T fetchAndSubRelease(T valueToAdd) noexcept
{ return Ops::fetchAndSubRelease(_q_value, valueToAdd); }
- T fetchAndSubOrdered(T valueToAdd) Q_DECL_NOTHROW
+ T fetchAndSubOrdered(T valueToAdd) noexcept
{ return Ops::fetchAndSubOrdered(_q_value, valueToAdd); }
- T fetchAndAndRelaxed(T valueToAdd) Q_DECL_NOTHROW
+ T fetchAndAndRelaxed(T valueToAdd) noexcept
{ return Ops::fetchAndAndRelaxed(_q_value, valueToAdd); }
- T fetchAndAndAcquire(T valueToAdd) Q_DECL_NOTHROW
+ T fetchAndAndAcquire(T valueToAdd) noexcept
{ return Ops::fetchAndAndAcquire(_q_value, valueToAdd); }
- T fetchAndAndRelease(T valueToAdd) Q_DECL_NOTHROW
+ T fetchAndAndRelease(T valueToAdd) noexcept
{ return Ops::fetchAndAndRelease(_q_value, valueToAdd); }
- T fetchAndAndOrdered(T valueToAdd) Q_DECL_NOTHROW
+ T fetchAndAndOrdered(T valueToAdd) noexcept
{ return Ops::fetchAndAndOrdered(_q_value, valueToAdd); }
- T fetchAndOrRelaxed(T valueToAdd) Q_DECL_NOTHROW
+ T fetchAndOrRelaxed(T valueToAdd) noexcept
{ return Ops::fetchAndOrRelaxed(_q_value, valueToAdd); }
- T fetchAndOrAcquire(T valueToAdd) Q_DECL_NOTHROW
+ T fetchAndOrAcquire(T valueToAdd) noexcept
{ return Ops::fetchAndOrAcquire(_q_value, valueToAdd); }
- T fetchAndOrRelease(T valueToAdd) Q_DECL_NOTHROW
+ T fetchAndOrRelease(T valueToAdd) noexcept
{ return Ops::fetchAndOrRelease(_q_value, valueToAdd); }
- T fetchAndOrOrdered(T valueToAdd) Q_DECL_NOTHROW
+ T fetchAndOrOrdered(T valueToAdd) noexcept
{ return Ops::fetchAndOrOrdered(_q_value, valueToAdd); }
- T fetchAndXorRelaxed(T valueToAdd) Q_DECL_NOTHROW
+ T fetchAndXorRelaxed(T valueToAdd) noexcept
{ return Ops::fetchAndXorRelaxed(_q_value, valueToAdd); }
- T fetchAndXorAcquire(T valueToAdd) Q_DECL_NOTHROW
+ T fetchAndXorAcquire(T valueToAdd) noexcept
{ return Ops::fetchAndXorAcquire(_q_value, valueToAdd); }
- T fetchAndXorRelease(T valueToAdd) Q_DECL_NOTHROW
+ T fetchAndXorRelease(T valueToAdd) noexcept
{ return Ops::fetchAndXorRelease(_q_value, valueToAdd); }
- T fetchAndXorOrdered(T valueToAdd) Q_DECL_NOTHROW
+ T fetchAndXorOrdered(T valueToAdd) noexcept
{ return Ops::fetchAndXorOrdered(_q_value, valueToAdd); }
- T operator++() Q_DECL_NOTHROW
+ T operator++() noexcept
{ return fetchAndAddOrdered(1) + 1; }
- T operator++(int) Q_DECL_NOTHROW
+ T operator++(int) noexcept
{ return fetchAndAddOrdered(1); }
- T operator--() Q_DECL_NOTHROW
+ T operator--() noexcept
{ return fetchAndSubOrdered(1) - 1; }
- T operator--(int) Q_DECL_NOTHROW
+ T operator--(int) noexcept
{ return fetchAndSubOrdered(1); }
- T operator+=(T v) Q_DECL_NOTHROW
+ T operator+=(T v) noexcept
{ return fetchAndAddOrdered(v) + v; }
- T operator-=(T v) Q_DECL_NOTHROW
+ T operator-=(T v) noexcept
{ return fetchAndSubOrdered(v) - v; }
- T operator&=(T v) Q_DECL_NOTHROW
+ T operator&=(T v) noexcept
{ return fetchAndAndOrdered(v) & v; }
- T operator|=(T v) Q_DECL_NOTHROW
+ T operator|=(T v) noexcept
{ return fetchAndOrOrdered(v) | v; }
- T operator^=(T v) Q_DECL_NOTHROW
+ T operator^=(T v) noexcept
{ return fetchAndXorOrdered(v) ^ v; }
#ifdef QT_BASIC_ATOMIC_HAS_CONSTRUCTORS
QBasicAtomicInteger() = default;
- constexpr QBasicAtomicInteger(T value) Q_DECL_NOTHROW : _q_value(value) {}
+ constexpr QBasicAtomicInteger(T value) noexcept : _q_value(value) {}
QBasicAtomicInteger(const QBasicAtomicInteger &) = delete;
QBasicAtomicInteger &operator=(const QBasicAtomicInteger &) = delete;
QBasicAtomicInteger &operator=(const QBasicAtomicInteger &) volatile = delete;
@@ -236,85 +240,91 @@ public:
AtomicType _q_value;
- Type load() const Q_DECL_NOTHROW { return Ops::load(_q_value); }
- void store(Type newValue) Q_DECL_NOTHROW { Ops::store(_q_value, newValue); }
- operator Type() const Q_DECL_NOTHROW { return loadAcquire(); }
- Type operator=(Type newValue) Q_DECL_NOTHROW { storeRelease(newValue); return newValue; }
+#if QT_DEPRECATED_SINCE(5, 14)
+ QT_DEPRECATED_VERSION_X_5_14("Use loadRelaxed") Type load() const noexcept { return loadRelaxed(); }
+ QT_DEPRECATED_VERSION_X_5_14("Use storeRelaxed") void store(Type newValue) noexcept { storeRelaxed(newValue); }
+#endif
+
+ Type loadRelaxed() const noexcept { return Ops::loadRelaxed(_q_value); }
+ void storeRelaxed(Type newValue) noexcept { Ops::storeRelaxed(_q_value, newValue); }
+
+ operator Type() const noexcept { return loadAcquire(); }
+ Type operator=(Type newValue) noexcept { storeRelease(newValue); return newValue; }
// Atomic API, implemented in qatomic_XXX.h
- Type loadAcquire() const Q_DECL_NOTHROW { return Ops::loadAcquire(_q_value); }
- void storeRelease(Type newValue) Q_DECL_NOTHROW { Ops::storeRelease(_q_value, newValue); }
+ Type loadAcquire() const noexcept { return Ops::loadAcquire(_q_value); }
+ void storeRelease(Type newValue) noexcept { Ops::storeRelease(_q_value, newValue); }
- static Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW { return Ops::isTestAndSetNative(); }
- static Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return Ops::isTestAndSetWaitFree(); }
+ static Q_DECL_CONSTEXPR bool isTestAndSetNative() noexcept { return Ops::isTestAndSetNative(); }
+ static Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() noexcept { return Ops::isTestAndSetWaitFree(); }
- bool testAndSetRelaxed(Type expectedValue, Type newValue) Q_DECL_NOTHROW
+ bool testAndSetRelaxed(Type expectedValue, Type newValue) noexcept
{ return Ops::testAndSetRelaxed(_q_value, expectedValue, newValue); }
- bool testAndSetAcquire(Type expectedValue, Type newValue) Q_DECL_NOTHROW
+ bool testAndSetAcquire(Type expectedValue, Type newValue) noexcept
{ return Ops::testAndSetAcquire(_q_value, expectedValue, newValue); }
- bool testAndSetRelease(Type expectedValue, Type newValue) Q_DECL_NOTHROW
+ bool testAndSetRelease(Type expectedValue, Type newValue) noexcept
{ return Ops::testAndSetRelease(_q_value, expectedValue, newValue); }
- bool testAndSetOrdered(Type expectedValue, Type newValue) Q_DECL_NOTHROW
+ bool testAndSetOrdered(Type expectedValue, Type newValue) noexcept
{ return Ops::testAndSetOrdered(_q_value, expectedValue, newValue); }
- bool testAndSetRelaxed(Type expectedValue, Type newValue, Type &currentValue) Q_DECL_NOTHROW
+ bool testAndSetRelaxed(Type expectedValue, Type newValue, Type &currentValue) noexcept
{ return Ops::testAndSetRelaxed(_q_value, expectedValue, newValue, &currentValue); }
- bool testAndSetAcquire(Type expectedValue, Type newValue, Type &currentValue) Q_DECL_NOTHROW
+ bool testAndSetAcquire(Type expectedValue, Type newValue, Type &currentValue) noexcept
{ return Ops::testAndSetAcquire(_q_value, expectedValue, newValue, &currentValue); }
- bool testAndSetRelease(Type expectedValue, Type newValue, Type &currentValue) Q_DECL_NOTHROW
+ bool testAndSetRelease(Type expectedValue, Type newValue, Type &currentValue) noexcept
{ return Ops::testAndSetRelease(_q_value, expectedValue, newValue, &currentValue); }
- bool testAndSetOrdered(Type expectedValue, Type newValue, Type &currentValue) Q_DECL_NOTHROW
+ bool testAndSetOrdered(Type expectedValue, Type newValue, Type &currentValue) noexcept
{ return Ops::testAndSetOrdered(_q_value, expectedValue, newValue, &currentValue); }
- static Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return Ops::isFetchAndStoreNative(); }
- static Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() Q_DECL_NOTHROW { return Ops::isFetchAndStoreWaitFree(); }
+ static Q_DECL_CONSTEXPR bool isFetchAndStoreNative() noexcept { return Ops::isFetchAndStoreNative(); }
+ static Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() noexcept { return Ops::isFetchAndStoreWaitFree(); }
- Type fetchAndStoreRelaxed(Type newValue) Q_DECL_NOTHROW
+ Type fetchAndStoreRelaxed(Type newValue) noexcept
{ return Ops::fetchAndStoreRelaxed(_q_value, newValue); }
- Type fetchAndStoreAcquire(Type newValue) Q_DECL_NOTHROW
+ Type fetchAndStoreAcquire(Type newValue) noexcept
{ return Ops::fetchAndStoreAcquire(_q_value, newValue); }
- Type fetchAndStoreRelease(Type newValue) Q_DECL_NOTHROW
+ Type fetchAndStoreRelease(Type newValue) noexcept
{ return Ops::fetchAndStoreRelease(_q_value, newValue); }
- Type fetchAndStoreOrdered(Type newValue) Q_DECL_NOTHROW
+ Type fetchAndStoreOrdered(Type newValue) noexcept
{ return Ops::fetchAndStoreOrdered(_q_value, newValue); }
- static Q_DECL_CONSTEXPR bool isFetchAndAddNative() Q_DECL_NOTHROW { return Ops::isFetchAndAddNative(); }
- static Q_DECL_CONSTEXPR bool isFetchAndAddWaitFree() Q_DECL_NOTHROW { return Ops::isFetchAndAddWaitFree(); }
+ static Q_DECL_CONSTEXPR bool isFetchAndAddNative() noexcept { return Ops::isFetchAndAddNative(); }
+ static Q_DECL_CONSTEXPR bool isFetchAndAddWaitFree() noexcept { return Ops::isFetchAndAddWaitFree(); }
- Type fetchAndAddRelaxed(qptrdiff valueToAdd) Q_DECL_NOTHROW
+ Type fetchAndAddRelaxed(qptrdiff valueToAdd) noexcept
{ return Ops::fetchAndAddRelaxed(_q_value, valueToAdd); }
- Type fetchAndAddAcquire(qptrdiff valueToAdd) Q_DECL_NOTHROW
+ Type fetchAndAddAcquire(qptrdiff valueToAdd) noexcept
{ return Ops::fetchAndAddAcquire(_q_value, valueToAdd); }
- Type fetchAndAddRelease(qptrdiff valueToAdd) Q_DECL_NOTHROW
+ Type fetchAndAddRelease(qptrdiff valueToAdd) noexcept
{ return Ops::fetchAndAddRelease(_q_value, valueToAdd); }
- Type fetchAndAddOrdered(qptrdiff valueToAdd) Q_DECL_NOTHROW
+ Type fetchAndAddOrdered(qptrdiff valueToAdd) noexcept
{ return Ops::fetchAndAddOrdered(_q_value, valueToAdd); }
- Type fetchAndSubRelaxed(qptrdiff valueToAdd) Q_DECL_NOTHROW
+ Type fetchAndSubRelaxed(qptrdiff valueToAdd) noexcept
{ return Ops::fetchAndSubRelaxed(_q_value, valueToAdd); }
- Type fetchAndSubAcquire(qptrdiff valueToAdd) Q_DECL_NOTHROW
+ Type fetchAndSubAcquire(qptrdiff valueToAdd) noexcept
{ return Ops::fetchAndSubAcquire(_q_value, valueToAdd); }
- Type fetchAndSubRelease(qptrdiff valueToAdd) Q_DECL_NOTHROW
+ Type fetchAndSubRelease(qptrdiff valueToAdd) noexcept
{ return Ops::fetchAndSubRelease(_q_value, valueToAdd); }
- Type fetchAndSubOrdered(qptrdiff valueToAdd) Q_DECL_NOTHROW
+ Type fetchAndSubOrdered(qptrdiff valueToAdd) noexcept
{ return Ops::fetchAndSubOrdered(_q_value, valueToAdd); }
- Type operator++() Q_DECL_NOTHROW
+ Type operator++() noexcept
{ return fetchAndAddOrdered(1) + 1; }
- Type operator++(int) Q_DECL_NOTHROW
+ Type operator++(int) noexcept
{ return fetchAndAddOrdered(1); }
- Type operator--() Q_DECL_NOTHROW
+ Type operator--() noexcept
{ return fetchAndSubOrdered(1) - 1; }
- Type operator--(int) Q_DECL_NOTHROW
+ Type operator--(int) noexcept
{ return fetchAndSubOrdered(1); }
- Type operator+=(qptrdiff valueToAdd) Q_DECL_NOTHROW
+ Type operator+=(qptrdiff valueToAdd) noexcept
{ return fetchAndAddOrdered(valueToAdd) + valueToAdd; }
- Type operator-=(qptrdiff valueToSub) Q_DECL_NOTHROW
+ Type operator-=(qptrdiff valueToSub) noexcept
{ return fetchAndSubOrdered(valueToSub) - valueToSub; }
#ifdef QT_BASIC_ATOMIC_HAS_CONSTRUCTORS
QBasicAtomicPointer() = default;
- constexpr QBasicAtomicPointer(Type value) Q_DECL_NOTHROW : _q_value(value) {}
+ constexpr QBasicAtomicPointer(Type value) noexcept : _q_value(value) {}
QBasicAtomicPointer(const QBasicAtomicPointer &) = delete;
QBasicAtomicPointer &operator=(const QBasicAtomicPointer &) = delete;
QBasicAtomicPointer &operator=(const QBasicAtomicPointer &) volatile = delete;
diff --git a/src/corelib/thread/qfutex_p.h b/src/corelib/thread/qfutex_p.h
index 483664c783..7bec4554b7 100644
--- a/src/corelib/thread/qfutex_p.h
+++ b/src/corelib/thread/qfutex_p.h
@@ -81,15 +81,43 @@ QT_END_NAMESPACE
// if not defined in linux/futex.h
# define FUTEX_PRIVATE_FLAG 128 // added in v2.6.22
+# if QT_HAS_FEATURE(thread_sanitizer) || defined(__SANITIZE_THREAD__)
+# include <sanitizer/tsan_interface.h>
+inline void _q_tsan_acquire(void *addr, void *addr2)
+{
+ __tsan_acquire(addr);
+ if (addr2)
+ __tsan_acquire(addr2);
+}
+inline void _q_tsan_release(void *addr, void *addr2)
+{
+ if (addr2)
+ __tsan_release(addr2);
+ __tsan_release(addr);
+}
+# else
+inline void _q_tsan_acquire(void *, void *) {}
+inline void _q_tsan_release(void *, void *) {}
+# endif // QT_HAS_FEATURE(thread_sanitizer) || defined(__SANITIZE_THREAD__)
+
QT_BEGIN_NAMESPACE
namespace QtLinuxFutex {
constexpr inline bool futexAvailable() { return true; }
inline int _q_futex(int *addr, int op, int val, quintptr val2 = 0,
- int *addr2 = nullptr, int val3 = 0) Q_DECL_NOTHROW
+ int *addr2 = nullptr, int val3 = 0) noexcept
{
+ // A futex call ensures total ordering on the futex words
+ // (in either success or failure of the call). Instruct TSAN accordingly,
+ // as TSAN does not understand the futex(2) syscall.
+ _q_tsan_release(addr, addr2);
+
// we use __NR_futex because some libcs (like Android's bionic) don't
// provide SYS_futex etc.
- return syscall(__NR_futex, addr, op | FUTEX_PRIVATE_FLAG, val, val2, addr2, val3);
+ int result = syscall(__NR_futex, addr, op | FUTEX_PRIVATE_FLAG, val, val2, addr2, val3);
+
+ _q_tsan_acquire(addr, addr2);
+
+ return result;
}
template <typename T> int *addr(T *ptr)
{
diff --git a/src/corelib/thread/qfuture.h b/src/corelib/thread/qfuture.h
index a456dd9139..d3135510b3 100644
--- a/src/corelib/thread/qfuture.h
+++ b/src/corelib/thread/qfuture.h
@@ -111,33 +111,79 @@ public:
typedef const T &reference;
inline const_iterator() {}
- inline const_iterator(QFuture const * const _future, int _index) : future(_future), index(_index) {}
+ inline const_iterator(QFuture const * const _future, int _index)
+ : future(_future), index(advanceIndex(_index, 0)) { }
inline const_iterator(const const_iterator &o) : future(o.future), index(o.index) {}
inline const_iterator &operator=(const const_iterator &o)
{ future = o.future; index = o.index; return *this; }
inline const T &operator*() const { return future->d.resultReference(index); }
inline const T *operator->() const { return future->d.resultPointer(index); }
-
- inline bool operator!=(const const_iterator &other) const
+ inline bool operator!=(const const_iterator &other) const { return index != other.index; }
+ inline bool operator==(const const_iterator &o) const { return !operator!=(o); }
+ inline const_iterator &operator++()
+ { index = advanceIndex(index, 1); return *this; }
+ inline const_iterator &operator--()
+ { index = advanceIndex(index, -1); return *this; }
+ inline const_iterator operator++(int)
+ {
+ const_iterator r = *this;
+ index = advanceIndex(index, 1);
+ return r;
+ }
+ inline const_iterator operator--(int)
{
- if (index == -1 && other.index == -1) // comparing end != end?
- return false;
- if (other.index == -1)
- return (future->isRunning() || (index < future->resultCount()));
- return (index != other.index);
+ const_iterator r = *this;
+ index = advanceIndex(index, -1);
+ return r;
}
+ inline const_iterator operator+(int j) const
+ { return const_iterator(future, advanceIndex(index, j)); }
+ inline const_iterator operator-(int j) const
+ { return const_iterator(future, advanceIndex(index, -j)); }
+ inline const_iterator &operator+=(int j)
+ { index = advanceIndex(index, j); return *this; }
+ inline const_iterator &operator-=(int j)
+ { index = advanceIndex(index, -j); return *this; }
+ friend inline const_iterator operator+(int j, const_iterator k)
+ { return const_iterator(k.future, k.advanceIndex(k.index, j)); }
- inline bool operator==(const const_iterator &o) const { return !operator!=(o); }
- inline const_iterator &operator++() { ++index; return *this; }
- inline const_iterator operator++(int) { const_iterator r = *this; ++index; return r; }
- inline const_iterator &operator--() { --index; return *this; }
- inline const_iterator operator--(int) { const_iterator r = *this; --index; return r; }
- inline const_iterator operator+(int j) const { return const_iterator(future, index + j); }
- inline const_iterator operator-(int j) const { return const_iterator(future, index - j); }
- inline const_iterator &operator+=(int j) { index += j; return *this; }
- inline const_iterator &operator-=(int j) { index -= j; return *this; }
- friend inline const_iterator operator+(int j, const_iterator k) { return k + j; }
private:
+ /*! \internal
+
+ Advances the iterator index \a idx \a n steps, waits for the
+ result at the target index, and returns the target index.
+
+ The index may be -1, indicating the end iterator, either
+ as the argument or as the return value. The end iterator
+ may be decremented.
+
+ The caller is responsible for not advancing the iterator
+ before begin() or past end(), with the exception that
+ attempting to advance a non-end iterator past end() for
+ a running future is allowed and will return the end iterator.
+
+ Note that n == 0 is valid and will wait for the result
+ at the given index.
+ */
+ int advanceIndex(int idx, int n) const
+ {
+ // The end iterator can be decremented, leave as-is for other cases
+ if (idx == -1 && n >= 0)
+ return idx;
+
+ // Special case for decrementing the end iterator: wait for
+ // finished to get the total result count.
+ if (idx == -1 && future->isRunning())
+ future->d.waitForFinished();
+
+ // Wait for result at target index
+ const int targetIndex = (idx == -1) ? future->resultCount() + n : idx + n;
+ future->d.waitForResult(targetIndex);
+
+ // After waiting there is either a result or the end was reached
+ return (targetIndex < future->resultCount()) ? targetIndex : -1;
+ }
+
QFuture const * future;
int index;
};
diff --git a/src/corelib/thread/qfutureinterface.cpp b/src/corelib/thread/qfutureinterface.cpp
index dfbed5fb0f..8f4cae8816 100644
--- a/src/corelib/thread/qfutureinterface.cpp
+++ b/src/corelib/thread/qfutureinterface.cpp
@@ -97,7 +97,7 @@ static inline int switch_off(QAtomicInt &a, int which)
static inline int switch_from_to(QAtomicInt &a, int from, int to)
{
int newValue;
- int expected = a.load();
+ int expected = a.loadRelaxed();
do {
newValue = (expected & ~from) | to;
} while (!a.testAndSetRelaxed(expected, newValue, expected));
@@ -107,7 +107,7 @@ static inline int switch_from_to(QAtomicInt &a, int from, int to)
void QFutureInterfaceBase::cancel()
{
QMutexLocker locker(&d->m_mutex);
- if (d->state.load() & Canceled)
+ if (d->state.loadRelaxed() & Canceled)
return;
switch_from_to(d->state, Paused, Canceled);
@@ -132,7 +132,7 @@ void QFutureInterfaceBase::setPaused(bool paused)
void QFutureInterfaceBase::togglePaused()
{
QMutexLocker locker(&d->m_mutex);
- if (d->state.load() & Paused) {
+ if (d->state.loadRelaxed() & Paused) {
switch_off(d->state, Paused);
d->pausedWaitCondition.wakeAll();
d->sendCallOut(QFutureCallOutEvent(QFutureCallOutEvent::Resumed));
@@ -149,7 +149,7 @@ void QFutureInterfaceBase::setThrottled(bool enable)
switch_on(d->state, Throttled);
} else {
switch_off(d->state, Throttled);
- if (!(d->state.load() & Paused))
+ if (!(d->state.loadRelaxed() & Paused))
d->pausedWaitCondition.wakeAll();
}
}
@@ -201,13 +201,13 @@ void QFutureInterfaceBase::waitForResume()
{
// return early if possible to avoid taking the mutex lock.
{
- const int state = d->state.load();
+ const int state = d->state.loadRelaxed();
if (!(state & Paused) || (state & Canceled))
return;
}
QMutexLocker lock(&d->m_mutex);
- const int state = d->state.load();
+ const int state = d->state.loadRelaxed();
if (!(state & Paused) || (state & Canceled))
return;
@@ -256,7 +256,7 @@ bool QFutureInterfaceBase::isProgressUpdateNeeded() const
void QFutureInterfaceBase::reportStarted()
{
QMutexLocker locker(&d->m_mutex);
- if (d->state.load() & (Started|Canceled|Finished))
+ if (d->state.loadRelaxed() & (Started|Canceled|Finished))
return;
d->setState(State(Started | Running));
@@ -272,7 +272,7 @@ void QFutureInterfaceBase::reportCanceled()
void QFutureInterfaceBase::reportException(const QException &exception)
{
QMutexLocker locker(&d->m_mutex);
- if (d->state.load() & (Canceled|Finished))
+ if (d->state.loadRelaxed() & (Canceled|Finished))
return;
d->m_exceptionStore.setException(exception);
@@ -307,7 +307,7 @@ int QFutureInterfaceBase::expectedResultCount()
bool QFutureInterfaceBase::queryState(State state) const
{
- return d->state.load() & state;
+ return d->state.loadRelaxed() & state;
}
void QFutureInterfaceBase::waitForResult(int resultIndex)
@@ -352,7 +352,7 @@ void QFutureInterfaceBase::waitForFinished()
void QFutureInterfaceBase::reportResultsReady(int beginIndex, int endIndex)
{
- if (beginIndex == endIndex || (d->state.load() & (Canceled|Finished)))
+ if (beginIndex == endIndex || (d->state.loadRelaxed() & (Canceled|Finished)))
return;
d->waitCondition.wakeAll();
@@ -414,7 +414,7 @@ void QFutureInterfaceBase::setProgressValueAndText(int progressValue,
if (d->m_progressValue >= progressValue)
return;
- if (d->state.load() & (Canceled|Finished))
+ if (d->state.loadRelaxed() & (Canceled|Finished))
return;
if (d->internal_updateProgress(progressValue, progressText)) {
@@ -486,10 +486,10 @@ bool QFutureInterfaceBasePrivate::internal_waitForNextResult()
if (m_results.hasNextResult())
return true;
- while ((state.load() & QFutureInterfaceBase::Running) && m_results.hasNextResult() == false)
+ while ((state.loadRelaxed() & QFutureInterfaceBase::Running) && m_results.hasNextResult() == false)
waitCondition.wait(&m_mutex);
- return !(state.load() & QFutureInterfaceBase::Canceled) && m_results.hasNextResult();
+ return !(state.loadRelaxed() & QFutureInterfaceBase::Canceled) && m_results.hasNextResult();
}
bool QFutureInterfaceBasePrivate::internal_updateProgress(int progress,
@@ -512,8 +512,8 @@ bool QFutureInterfaceBasePrivate::internal_updateProgress(int progress,
void QFutureInterfaceBasePrivate::internal_setThrottled(bool enable)
{
// bail out if we are not changing the state
- if ((enable && (state.load() & QFutureInterfaceBase::Throttled))
- || (!enable && !(state.load() & QFutureInterfaceBase::Throttled)))
+ if ((enable && (state.loadRelaxed() & QFutureInterfaceBase::Throttled))
+ || (!enable && !(state.loadRelaxed() & QFutureInterfaceBase::Throttled)))
return;
// change the state
@@ -521,7 +521,7 @@ void QFutureInterfaceBasePrivate::internal_setThrottled(bool enable)
switch_on(state, QFutureInterfaceBase::Throttled);
} else {
switch_off(state, QFutureInterfaceBase::Throttled);
- if (!(state.load() & QFutureInterfaceBase::Paused))
+ if (!(state.loadRelaxed() & QFutureInterfaceBase::Paused))
pausedWaitCondition.wakeAll();
}
}
@@ -556,7 +556,7 @@ void QFutureInterfaceBasePrivate::connectOutputInterface(QFutureCallOutInterface
{
QMutexLocker locker(&m_mutex);
- if (state.load() & QFutureInterfaceBase::Started) {
+ if (state.loadRelaxed() & QFutureInterfaceBase::Started) {
interface->postCallOutEvent(QFutureCallOutEvent(QFutureCallOutEvent::Started));
interface->postCallOutEvent(QFutureCallOutEvent(QFutureCallOutEvent::ProgressRange,
m_progressMinimum,
@@ -576,13 +576,13 @@ void QFutureInterfaceBasePrivate::connectOutputInterface(QFutureCallOutInterface
it.batchedAdvance();
}
- if (state.load() & QFutureInterfaceBase::Paused)
+ if (state.loadRelaxed() & QFutureInterfaceBase::Paused)
interface->postCallOutEvent(QFutureCallOutEvent(QFutureCallOutEvent::Paused));
- if (state.load() & QFutureInterfaceBase::Canceled)
+ if (state.loadRelaxed() & QFutureInterfaceBase::Canceled)
interface->postCallOutEvent(QFutureCallOutEvent(QFutureCallOutEvent::Canceled));
- if (state.load() & QFutureInterfaceBase::Finished)
+ if (state.loadRelaxed() & QFutureInterfaceBase::Finished)
interface->postCallOutEvent(QFutureCallOutEvent(QFutureCallOutEvent::Finished));
outputConnections.append(interface);
@@ -601,7 +601,7 @@ void QFutureInterfaceBasePrivate::disconnectOutputInterface(QFutureCallOutInterf
void QFutureInterfaceBasePrivate::setState(QFutureInterfaceBase::State newState)
{
- state.store(newState);
+ state.storeRelaxed(newState);
}
QT_END_NAMESPACE
diff --git a/src/corelib/thread/qfutureinterface_p.h b/src/corelib/thread/qfutureinterface_p.h
index 63e534464f..b297dff633 100644
--- a/src/corelib/thread/qfutureinterface_p.h
+++ b/src/corelib/thread/qfutureinterface_p.h
@@ -144,11 +144,11 @@ public:
// Default ref counter for QFIBP
inline bool ref() { return m_refCount.ref(); }
inline bool deref() { return m_refCount.deref(); }
- inline int load() const { return m_refCount.load(); }
+ inline int load() const { return m_refCount.loadRelaxed(); }
// Ref counter for type T
inline bool refT() { return m_refCountT.ref(); }
inline bool derefT() { return m_refCountT.deref(); }
- inline int loadT() const { return m_refCountT.load(); }
+ inline int loadT() const { return m_refCountT.loadRelaxed(); }
private:
QAtomicInt m_refCount;
diff --git a/src/corelib/thread/qfuturewatcher.cpp b/src/corelib/thread/qfuturewatcher.cpp
index 8e90d043ef..06bc4740f9 100644
--- a/src/corelib/thread/qfuturewatcher.cpp
+++ b/src/corelib/thread/qfuturewatcher.cpp
@@ -402,7 +402,7 @@ void QFutureWatcherBase::disconnectOutputInterface(bool pendingAssignment)
{
if (pendingAssignment) {
Q_D(QFutureWatcherBase);
- d->pendingResultsReady.store(0);
+ d->pendingResultsReady.storeRelaxed(0);
qDeleteAll(d->pendingCallOutEvents);
d->pendingCallOutEvents.clear();
d->finished = false; /* May soon be amended, during connectOutputInterface() */
@@ -441,7 +441,7 @@ void QFutureWatcherBasePrivate::sendCallOutEvent(QFutureCallOutEvent *event)
emit q->finished();
break;
case QFutureCallOutEvent::Canceled:
- pendingResultsReady.store(0);
+ pendingResultsReady.storeRelaxed(0);
emit q->canceled();
break;
case QFutureCallOutEvent::Paused:
@@ -466,7 +466,7 @@ void QFutureWatcherBasePrivate::sendCallOutEvent(QFutureCallOutEvent *event)
emit q->resultsReadyAt(beginIndex, endIndex);
- if (resultAtConnected.load() <= 0)
+ if (resultAtConnected.loadRelaxed() <= 0)
break;
for (int i = beginIndex; i < endIndex; ++i)
@@ -479,7 +479,7 @@ void QFutureWatcherBasePrivate::sendCallOutEvent(QFutureCallOutEvent *event)
emit q->progressValueChanged(event->index1);
if (!event->text.isNull()) // ###
- q->progressTextChanged(event->text);
+ emit q->progressTextChanged(event->text);
break;
case QFutureCallOutEvent::ProgressRange:
emit q->progressRangeChanged(event->index1, event->index2);
diff --git a/src/corelib/thread/qgenericatomic.h b/src/corelib/thread/qgenericatomic.h
index 89c4fe9a11..e9e5f3c74b 100644
--- a/src/corelib/thread/qgenericatomic.h
+++ b/src/corelib/thread/qgenericatomic.h
@@ -72,32 +72,44 @@ template <typename BaseClass> struct QGenericAtomicOps
{
template <typename T> struct AtomicType { typedef T Type; typedef T *PointerType; };
- template <typename T> static void acquireMemoryFence(const T &_q_value) Q_DECL_NOTHROW
+ template <typename T> static void acquireMemoryFence(const T &_q_value) noexcept
{
BaseClass::orderedMemoryFence(_q_value);
}
- template <typename T> static void releaseMemoryFence(const T &_q_value) Q_DECL_NOTHROW
+ template <typename T> static void releaseMemoryFence(const T &_q_value) noexcept
{
BaseClass::orderedMemoryFence(_q_value);
}
- template <typename T> static void orderedMemoryFence(const T &) Q_DECL_NOTHROW
+ template <typename T> static void orderedMemoryFence(const T &) noexcept
{
}
template <typename T> static Q_ALWAYS_INLINE
- T load(const T &_q_value) Q_DECL_NOTHROW
+ T load(const T &_q_value) noexcept
{
return _q_value;
}
template <typename T, typename X> static Q_ALWAYS_INLINE
- void store(T &_q_value, X newValue) Q_DECL_NOTHROW
+ void store(T &_q_value, X newValue) noexcept
{
_q_value = newValue;
}
template <typename T> static Q_ALWAYS_INLINE
- T loadAcquire(const T &_q_value) Q_DECL_NOTHROW
+ T loadRelaxed(const T &_q_value) noexcept
+ {
+ return _q_value;
+ }
+
+ template <typename T, typename X> static Q_ALWAYS_INLINE
+ void storeRelaxed(T &_q_value, X newValue) noexcept
+ {
+ _q_value = newValue;
+ }
+
+ template <typename T> static Q_ALWAYS_INLINE
+ T loadAcquire(const T &_q_value) noexcept
{
T tmp = *static_cast<const volatile T *>(&_q_value);
BaseClass::acquireMemoryFence(_q_value);
@@ -105,24 +117,24 @@ template <typename BaseClass> struct QGenericAtomicOps
}
template <typename T, typename X> static Q_ALWAYS_INLINE
- void storeRelease(T &_q_value, X newValue) Q_DECL_NOTHROW
+ void storeRelease(T &_q_value, X newValue) noexcept
{
BaseClass::releaseMemoryFence(_q_value);
*static_cast<volatile T *>(&_q_value) = newValue;
}
- static inline Q_DECL_CONSTEXPR bool isReferenceCountingNative() Q_DECL_NOTHROW
+ static inline Q_DECL_CONSTEXPR bool isReferenceCountingNative() noexcept
{ return BaseClass::isFetchAndAddNative(); }
- static inline Q_DECL_CONSTEXPR bool isReferenceCountingWaitFree() Q_DECL_NOTHROW
+ static inline Q_DECL_CONSTEXPR bool isReferenceCountingWaitFree() noexcept
{ return BaseClass::isFetchAndAddWaitFree(); }
template <typename T> static Q_ALWAYS_INLINE
- bool ref(T &_q_value) Q_DECL_NOTHROW
+ bool ref(T &_q_value) noexcept
{
return BaseClass::fetchAndAddRelaxed(_q_value, 1) != T(-1);
}
template <typename T> static Q_ALWAYS_INLINE
- bool deref(T &_q_value) Q_DECL_NOTHROW
+ bool deref(T &_q_value) noexcept
{
return BaseClass::fetchAndAddRelaxed(_q_value, -1) != 1;
}
@@ -130,16 +142,16 @@ template <typename BaseClass> struct QGenericAtomicOps
#if 0
// These functions have no default implementation
// Archictectures must implement them
- static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW;
- static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW;
+ static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() noexcept;
+ static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() noexcept;
template <typename T, typename X> static inline
- bool testAndSetRelaxed(T &_q_value, X expectedValue, X newValue) Q_DECL_NOTHROW;
+ bool testAndSetRelaxed(T &_q_value, X expectedValue, X newValue) noexcept;
template <typename T, typename X> static inline
- bool testAndSetRelaxed(T &_q_value, X expectedValue, X newValue, X *currentValue) Q_DECL_NOTHROW;
+ bool testAndSetRelaxed(T &_q_value, X expectedValue, X newValue, X *currentValue) noexcept;
#endif
template <typename T, typename X> static Q_ALWAYS_INLINE
- bool testAndSetAcquire(T &_q_value, X expectedValue, X newValue) Q_DECL_NOTHROW
+ bool testAndSetAcquire(T &_q_value, X expectedValue, X newValue) noexcept
{
bool tmp = BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue);
BaseClass::acquireMemoryFence(_q_value);
@@ -147,21 +159,21 @@ template <typename BaseClass> struct QGenericAtomicOps
}
template <typename T, typename X> static Q_ALWAYS_INLINE
- bool testAndSetRelease(T &_q_value, X expectedValue, X newValue) Q_DECL_NOTHROW
+ bool testAndSetRelease(T &_q_value, X expectedValue, X newValue) noexcept
{
BaseClass::releaseMemoryFence(_q_value);
return BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue);
}
template <typename T, typename X> static Q_ALWAYS_INLINE
- bool testAndSetOrdered(T &_q_value, X expectedValue, X newValue) Q_DECL_NOTHROW
+ bool testAndSetOrdered(T &_q_value, X expectedValue, X newValue) noexcept
{
BaseClass::orderedMemoryFence(_q_value);
return BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue);
}
template <typename T, typename X> static Q_ALWAYS_INLINE
- bool testAndSetAcquire(T &_q_value, X expectedValue, X newValue, X *currentValue) Q_DECL_NOTHROW
+ bool testAndSetAcquire(T &_q_value, X expectedValue, X newValue, X *currentValue) noexcept
{
bool tmp = BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue, currentValue);
BaseClass::acquireMemoryFence(_q_value);
@@ -169,35 +181,35 @@ template <typename BaseClass> struct QGenericAtomicOps
}
template <typename T, typename X> static Q_ALWAYS_INLINE
- bool testAndSetRelease(T &_q_value, X expectedValue, X newValue, X *currentValue) Q_DECL_NOTHROW
+ bool testAndSetRelease(T &_q_value, X expectedValue, X newValue, X *currentValue) noexcept
{
BaseClass::releaseMemoryFence(_q_value);
return BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue, currentValue);
}
template <typename T, typename X> static Q_ALWAYS_INLINE
- bool testAndSetOrdered(T &_q_value, X expectedValue, X newValue, X *currentValue) Q_DECL_NOTHROW
+ bool testAndSetOrdered(T &_q_value, X expectedValue, X newValue, X *currentValue) noexcept
{
BaseClass::orderedMemoryFence(_q_value);
return BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue, currentValue);
}
- static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return false; }
- static inline Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() Q_DECL_NOTHROW { return false; }
+ static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() noexcept { return false; }
+ static inline Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() noexcept { return false; }
template <typename T, typename X> static Q_ALWAYS_INLINE
- T fetchAndStoreRelaxed(T &_q_value, X newValue) Q_DECL_NOTHROW
+ T fetchAndStoreRelaxed(T &_q_value, X newValue) noexcept
{
// implement fetchAndStore on top of testAndSet
Q_FOREVER {
- T tmp = load(_q_value);
+ T tmp = loadRelaxed(_q_value);
if (BaseClass::testAndSetRelaxed(_q_value, tmp, newValue))
return tmp;
}
}
template <typename T, typename X> static Q_ALWAYS_INLINE
- T fetchAndStoreAcquire(T &_q_value, X newValue) Q_DECL_NOTHROW
+ T fetchAndStoreAcquire(T &_q_value, X newValue) noexcept
{
T tmp = BaseClass::fetchAndStoreRelaxed(_q_value, newValue);
BaseClass::acquireMemoryFence(_q_value);
@@ -205,34 +217,34 @@ template <typename BaseClass> struct QGenericAtomicOps
}
template <typename T, typename X> static Q_ALWAYS_INLINE
- T fetchAndStoreRelease(T &_q_value, X newValue) Q_DECL_NOTHROW
+ T fetchAndStoreRelease(T &_q_value, X newValue) noexcept
{
BaseClass::releaseMemoryFence(_q_value);
return BaseClass::fetchAndStoreRelaxed(_q_value, newValue);
}
template <typename T, typename X> static Q_ALWAYS_INLINE
- T fetchAndStoreOrdered(T &_q_value, X newValue) Q_DECL_NOTHROW
+ T fetchAndStoreOrdered(T &_q_value, X newValue) noexcept
{
BaseClass::orderedMemoryFence(_q_value);
return BaseClass::fetchAndStoreRelaxed(_q_value, newValue);
}
- static inline Q_DECL_CONSTEXPR bool isFetchAndAddNative() Q_DECL_NOTHROW { return false; }
- static inline Q_DECL_CONSTEXPR bool isFetchAndAddWaitFree() Q_DECL_NOTHROW { return false; }
+ static inline Q_DECL_CONSTEXPR bool isFetchAndAddNative() noexcept { return false; }
+ static inline Q_DECL_CONSTEXPR bool isFetchAndAddWaitFree() noexcept { return false; }
template <typename T> static Q_ALWAYS_INLINE
- T fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+ T fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
{
// implement fetchAndAdd on top of testAndSet
Q_FOREVER {
- T tmp = BaseClass::load(_q_value);
+ T tmp = BaseClass::loadRelaxed(_q_value);
if (BaseClass::testAndSetRelaxed(_q_value, tmp, T(tmp + valueToAdd)))
return tmp;
}
}
template <typename T> static Q_ALWAYS_INLINE
- T fetchAndAddAcquire(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+ T fetchAndAddAcquire(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
{
T tmp = BaseClass::fetchAndAddRelaxed(_q_value, valueToAdd);
BaseClass::acquireMemoryFence(_q_value);
@@ -240,14 +252,14 @@ template <typename BaseClass> struct QGenericAtomicOps
}
template <typename T> static Q_ALWAYS_INLINE
- T fetchAndAddRelease(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+ T fetchAndAddRelease(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
{
BaseClass::releaseMemoryFence(_q_value);
return BaseClass::fetchAndAddRelaxed(_q_value, valueToAdd);
}
template <typename T> static Q_ALWAYS_INLINE
- T fetchAndAddOrdered(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+ T fetchAndAddOrdered(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
{
BaseClass::orderedMemoryFence(_q_value);
return BaseClass::fetchAndAddRelaxed(_q_value, valueToAdd);
@@ -256,7 +268,7 @@ template <typename BaseClass> struct QGenericAtomicOps
QT_WARNING_PUSH
QT_WARNING_DISABLE_MSVC(4146) // unary minus operator applied to unsigned type, result still unsigned
template <typename T> static Q_ALWAYS_INLINE
- T fetchAndSubRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) Q_DECL_NOTHROW
+ T fetchAndSubRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) noexcept
{
// implement fetchAndSub on top of fetchAndAdd
return fetchAndAddRelaxed(_q_value, -operand);
@@ -264,7 +276,7 @@ QT_WARNING_DISABLE_MSVC(4146) // unary minus operator applied to unsigned type
QT_WARNING_POP
template <typename T> static Q_ALWAYS_INLINE
- T fetchAndSubAcquire(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) Q_DECL_NOTHROW
+ T fetchAndSubAcquire(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) noexcept
{
T tmp = BaseClass::fetchAndSubRelaxed(_q_value, operand);
BaseClass::acquireMemoryFence(_q_value);
@@ -272,24 +284,24 @@ QT_WARNING_POP
}
template <typename T> static Q_ALWAYS_INLINE
- T fetchAndSubRelease(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) Q_DECL_NOTHROW
+ T fetchAndSubRelease(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) noexcept
{
BaseClass::releaseMemoryFence(_q_value);
return BaseClass::fetchAndSubRelaxed(_q_value, operand);
}
template <typename T> static Q_ALWAYS_INLINE
- T fetchAndSubOrdered(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) Q_DECL_NOTHROW
+ T fetchAndSubOrdered(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) noexcept
{
BaseClass::orderedMemoryFence(_q_value);
return BaseClass::fetchAndSubRelaxed(_q_value, operand);
}
template <typename T> static Q_ALWAYS_INLINE
- T fetchAndAndRelaxed(T &_q_value, typename std::enable_if<QTypeInfo<T>::isIntegral, T>::type operand) Q_DECL_NOTHROW
+ T fetchAndAndRelaxed(T &_q_value, typename std::enable_if<QTypeInfo<T>::isIntegral, T>::type operand) noexcept
{
// implement fetchAndAnd on top of testAndSet
- T tmp = BaseClass::load(_q_value);
+ T tmp = BaseClass::loadRelaxed(_q_value);
Q_FOREVER {
if (BaseClass::testAndSetRelaxed(_q_value, tmp, T(tmp & operand), &tmp))
return tmp;
@@ -297,7 +309,7 @@ QT_WARNING_POP
}
template <typename T> static Q_ALWAYS_INLINE
- T fetchAndAndAcquire(T &_q_value, typename std::enable_if<QTypeInfo<T>::isIntegral, T>::type operand) Q_DECL_NOTHROW
+ T fetchAndAndAcquire(T &_q_value, typename std::enable_if<QTypeInfo<T>::isIntegral, T>::type operand) noexcept
{
T tmp = BaseClass::fetchAndAndRelaxed(_q_value, operand);
BaseClass::acquireMemoryFence(_q_value);
@@ -305,24 +317,24 @@ QT_WARNING_POP
}
template <typename T> static Q_ALWAYS_INLINE
- T fetchAndAndRelease(T &_q_value, typename std::enable_if<QTypeInfo<T>::isIntegral, T>::type operand) Q_DECL_NOTHROW
+ T fetchAndAndRelease(T &_q_value, typename std::enable_if<QTypeInfo<T>::isIntegral, T>::type operand) noexcept
{
BaseClass::releaseMemoryFence(_q_value);
return BaseClass::fetchAndAndRelaxed(_q_value, operand);
}
template <typename T> static Q_ALWAYS_INLINE
- T fetchAndAndOrdered(T &_q_value, typename std::enable_if<QTypeInfo<T>::isIntegral, T>::type operand) Q_DECL_NOTHROW
+ T fetchAndAndOrdered(T &_q_value, typename std::enable_if<QTypeInfo<T>::isIntegral, T>::type operand) noexcept
{
BaseClass::orderedMemoryFence(_q_value);
return BaseClass::fetchAndAndRelaxed(_q_value, operand);
}
template <typename T> static Q_ALWAYS_INLINE
- T fetchAndOrRelaxed(T &_q_value, typename std::enable_if<QTypeInfo<T>::isIntegral, T>::type operand) Q_DECL_NOTHROW
+ T fetchAndOrRelaxed(T &_q_value, typename std::enable_if<QTypeInfo<T>::isIntegral, T>::type operand) noexcept
{
// implement fetchAndOr on top of testAndSet
- T tmp = BaseClass::load(_q_value);
+ T tmp = BaseClass::loadRelaxed(_q_value);
Q_FOREVER {
if (BaseClass::testAndSetRelaxed(_q_value, tmp, T(tmp | operand), &tmp))
return tmp;
@@ -330,7 +342,7 @@ QT_WARNING_POP
}
template <typename T> static Q_ALWAYS_INLINE
- T fetchAndOrAcquire(T &_q_value, typename std::enable_if<QTypeInfo<T>::isIntegral, T>::type operand) Q_DECL_NOTHROW
+ T fetchAndOrAcquire(T &_q_value, typename std::enable_if<QTypeInfo<T>::isIntegral, T>::type operand) noexcept
{
T tmp = BaseClass::fetchAndOrRelaxed(_q_value, operand);
BaseClass::acquireMemoryFence(_q_value);
@@ -338,24 +350,24 @@ QT_WARNING_POP
}
template <typename T> static Q_ALWAYS_INLINE
- T fetchAndOrRelease(T &_q_value, typename std::enable_if<QTypeInfo<T>::isIntegral, T>::type operand) Q_DECL_NOTHROW
+ T fetchAndOrRelease(T &_q_value, typename std::enable_if<QTypeInfo<T>::isIntegral, T>::type operand) noexcept
{
BaseClass::releaseMemoryFence(_q_value);
return BaseClass::fetchAndOrRelaxed(_q_value, operand);
}
template <typename T> static Q_ALWAYS_INLINE
- T fetchAndOrOrdered(T &_q_value, typename std::enable_if<QTypeInfo<T>::isIntegral, T>::type operand) Q_DECL_NOTHROW
+ T fetchAndOrOrdered(T &_q_value, typename std::enable_if<QTypeInfo<T>::isIntegral, T>::type operand) noexcept
{
BaseClass::orderedMemoryFence(_q_value);
return BaseClass::fetchAndOrRelaxed(_q_value, operand);
}
template <typename T> static Q_ALWAYS_INLINE
- T fetchAndXorRelaxed(T &_q_value, typename std::enable_if<QTypeInfo<T>::isIntegral, T>::type operand) Q_DECL_NOTHROW
+ T fetchAndXorRelaxed(T &_q_value, typename std::enable_if<QTypeInfo<T>::isIntegral, T>::type operand) noexcept
{
// implement fetchAndXor on top of testAndSet
- T tmp = BaseClass::load(_q_value);
+ T tmp = BaseClass::loadRelaxed(_q_value);
Q_FOREVER {
if (BaseClass::testAndSetRelaxed(_q_value, tmp, T(tmp ^ operand), &tmp))
return tmp;
@@ -363,7 +375,7 @@ QT_WARNING_POP
}
template <typename T> static Q_ALWAYS_INLINE
- T fetchAndXorAcquire(T &_q_value, typename std::enable_if<QTypeInfo<T>::isIntegral, T>::type operand) Q_DECL_NOTHROW
+ T fetchAndXorAcquire(T &_q_value, typename std::enable_if<QTypeInfo<T>::isIntegral, T>::type operand) noexcept
{
T tmp = BaseClass::fetchAndXorRelaxed(_q_value, operand);
BaseClass::acquireMemoryFence(_q_value);
@@ -371,14 +383,14 @@ QT_WARNING_POP
}
template <typename T> static Q_ALWAYS_INLINE
- T fetchAndXorRelease(T &_q_value, typename std::enable_if<QTypeInfo<T>::isIntegral, T>::type operand) Q_DECL_NOTHROW
+ T fetchAndXorRelease(T &_q_value, typename std::enable_if<QTypeInfo<T>::isIntegral, T>::type operand) noexcept
{
BaseClass::releaseMemoryFence(_q_value);
return BaseClass::fetchAndXorRelaxed(_q_value, operand);
}
template <typename T> static Q_ALWAYS_INLINE
- T fetchAndXorOrdered(T &_q_value, typename std::enable_if<QTypeInfo<T>::isIntegral, T>::type operand) Q_DECL_NOTHROW
+ T fetchAndXorOrdered(T &_q_value, typename std::enable_if<QTypeInfo<T>::isIntegral, T>::type operand) noexcept
{
BaseClass::orderedMemoryFence(_q_value);
return BaseClass::fetchAndXorRelaxed(_q_value, operand);
diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp
index 3881ac017e..bd3a0fa7ba 100644
--- a/src/corelib/thread/qmutex.cpp
+++ b/src/corelib/thread/qmutex.cpp
@@ -82,7 +82,7 @@ public:
QMutex mutex;
bool lock(int timeout) QT_MUTEX_LOCK_NOEXCEPT;
- void unlock() Q_DECL_NOTHROW;
+ void unlock() noexcept;
};
/*
@@ -179,7 +179,7 @@ public:
*/
QMutex::QMutex(RecursionMode mode)
{
- d_ptr.store(mode == Recursive ? new QRecursiveMutexPrivate : 0);
+ d_ptr.storeRelaxed(mode == Recursive ? new QRecursiveMutexPrivate : 0);
}
/*!
@@ -189,12 +189,12 @@ QMutex::QMutex(RecursionMode mode)
*/
QMutex::~QMutex()
{
- QMutexData *d = d_ptr.load();
+ QMutexData *d = d_ptr.loadRelaxed();
if (isRecursive()) {
delete static_cast<QRecursiveMutexPrivate *>(d);
} else if (d) {
#ifndef QT_LINUX_FUTEX
- if (d != dummyLocked() && static_cast<QMutexPrivate *>(d)->possiblyUnlocked.load()
+ if (d != dummyLocked() && static_cast<QMutexPrivate *>(d)->possiblyUnlocked.loadRelaxed()
&& tryLock()) {
unlock();
return;
@@ -329,7 +329,7 @@ bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
\sa lock()
*/
-void QMutex::unlock() Q_DECL_NOTHROW
+void QMutex::unlock() noexcept
{
QMutexData *current;
if (fastTryUnlock(current))
@@ -348,7 +348,7 @@ void QMutex::unlock() Q_DECL_NOTHROW
Returns \c true if the mutex is recursive.
*/
-bool QBasicMutex::isRecursive() Q_DECL_NOTHROW
+bool QBasicMutex::isRecursive() noexcept
{
return QT_PREPEND_NAMESPACE(isRecursive)(d_ptr.loadAcquire());
}
@@ -358,7 +358,7 @@ bool QBasicMutex::isRecursive() Q_DECL_NOTHROW
Returns \c true if the mutex is recursive.
*/
-bool QBasicMutex::isRecursive() const Q_DECL_NOTHROW
+bool QBasicMutex::isRecursive() const noexcept
{
return QT_PREPEND_NAMESPACE(isRecursive)(d_ptr.loadAcquire());
}
@@ -517,7 +517,7 @@ bool QBasicMutex::lockInternal(int timeout) QT_MUTEX_LOCK_NOEXCEPT
}
QMutexPrivate *d = static_cast<QMutexPrivate *>(copy);
- if (timeout == 0 && !d->possiblyUnlocked.load())
+ if (timeout == 0 && !d->possiblyUnlocked.loadRelaxed())
return false;
// At this point we have a pointer to a QMutexPrivate. But the other thread
@@ -541,7 +541,7 @@ bool QBasicMutex::lockInternal(int timeout) QT_MUTEX_LOCK_NOEXCEPT
// is set to the BigNumber magic value set in unlockInternal()
int old_waiters;
do {
- old_waiters = d->waiters.load();
+ old_waiters = d->waiters.loadRelaxed();
if (old_waiters == -QMutexPrivate::BigNumber) {
// we are unlocking, and the thread that unlocks is about to change d to 0
// we try to acquire the mutex by changing to dummyLocked()
@@ -550,7 +550,7 @@ bool QBasicMutex::lockInternal(int timeout) QT_MUTEX_LOCK_NOEXCEPT
d->deref();
return true;
} else {
- Q_ASSERT(d != d_ptr.load()); //else testAndSetAcquire should have succeeded
+ Q_ASSERT(d != d_ptr.loadRelaxed()); //else testAndSetAcquire should have succeeded
// Mutex is likely to bo 0, we should continue the outer-loop,
// set old_waiters to the magic value of BigNumber
old_waiters = QMutexPrivate::BigNumber;
@@ -563,7 +563,7 @@ bool QBasicMutex::lockInternal(int timeout) QT_MUTEX_LOCK_NOEXCEPT
// The mutex was unlocked before we incremented waiters.
if (old_waiters != QMutexPrivate::BigNumber) {
//we did not break the previous loop
- Q_ASSERT(d->waiters.load() >= 1);
+ Q_ASSERT(d->waiters.loadRelaxed() >= 1);
d->waiters.deref();
}
d->deref();
@@ -572,11 +572,11 @@ bool QBasicMutex::lockInternal(int timeout) QT_MUTEX_LOCK_NOEXCEPT
if (d->wait(timeout)) {
// reset the possiblyUnlocked flag if needed (and deref its corresponding reference)
- if (d->possiblyUnlocked.load() && d->possiblyUnlocked.testAndSetRelaxed(true, false))
+ if (d->possiblyUnlocked.loadRelaxed() && d->possiblyUnlocked.testAndSetRelaxed(true, false))
d->deref();
d->derefWaiters(1);
//we got the lock. (do not deref)
- Q_ASSERT(d == d_ptr.load());
+ Q_ASSERT(d == d_ptr.loadRelaxed());
return true;
} else {
Q_ASSERT(timeout >= 0);
@@ -593,14 +593,14 @@ bool QBasicMutex::lockInternal(int timeout) QT_MUTEX_LOCK_NOEXCEPT
return false;
}
}
- Q_ASSERT(d_ptr.load() != 0);
+ Q_ASSERT(d_ptr.loadRelaxed() != 0);
return true;
}
/*!
\internal
*/
-void QBasicMutex::unlockInternal() Q_DECL_NOTHROW
+void QBasicMutex::unlockInternal() noexcept
{
QMutexData *copy = d_ptr.loadAcquire();
Q_ASSERT(copy); //we must be locked
@@ -618,7 +618,7 @@ void QBasicMutex::unlockInternal() Q_DECL_NOTHROW
//there is no one waiting on this mutex anymore, set the mutex as unlocked (d = 0)
if (d_ptr.testAndSetRelease(d, 0)) {
// reset the possiblyUnlocked flag if needed (and deref its corresponding reference)
- if (d->possiblyUnlocked.load() && d->possiblyUnlocked.testAndSetRelaxed(true, false))
+ if (d->possiblyUnlocked.loadRelaxed() && d->possiblyUnlocked.testAndSetRelaxed(true, false))
d->deref();
}
d->derefWaiters(0);
@@ -657,30 +657,30 @@ QMutexPrivate *QMutexPrivate::allocate()
int i = freelist()->next();
QMutexPrivate *d = &(*freelist())[i];
d->id = i;
- Q_ASSERT(d->refCount.load() == 0);
+ Q_ASSERT(d->refCount.loadRelaxed() == 0);
Q_ASSERT(!d->recursive);
- Q_ASSERT(!d->possiblyUnlocked.load());
- Q_ASSERT(d->waiters.load() == 0);
- d->refCount.store(1);
+ Q_ASSERT(!d->possiblyUnlocked.loadRelaxed());
+ Q_ASSERT(d->waiters.loadRelaxed() == 0);
+ d->refCount.storeRelaxed(1);
return d;
}
void QMutexPrivate::release()
{
Q_ASSERT(!recursive);
- Q_ASSERT(refCount.load() == 0);
- Q_ASSERT(!possiblyUnlocked.load());
- Q_ASSERT(waiters.load() == 0);
+ Q_ASSERT(refCount.loadRelaxed() == 0);
+ Q_ASSERT(!possiblyUnlocked.loadRelaxed());
+ Q_ASSERT(waiters.loadRelaxed() == 0);
freelist()->release(id);
}
// atomically subtract "value" to the waiters, and remove the QMutexPrivate::BigNumber flag
-void QMutexPrivate::derefWaiters(int value) Q_DECL_NOTHROW
+void QMutexPrivate::derefWaiters(int value) noexcept
{
int old_waiters;
int new_waiters;
do {
- old_waiters = waiters.load();
+ old_waiters = waiters.loadRelaxed();
new_waiters = old_waiters;
if (new_waiters < 0) {
new_waiters += QMutexPrivate::BigNumber;
@@ -696,7 +696,7 @@ void QMutexPrivate::derefWaiters(int value) Q_DECL_NOTHROW
inline bool QRecursiveMutexPrivate::lock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
{
Qt::HANDLE self = QThread::currentThreadId();
- if (owner.load() == self) {
+ if (owner.loadRelaxed() == self) {
++count;
Q_ASSERT_X(count != 0, "QMutex::lock", "Overflow in recursion counter");
return true;
@@ -709,19 +709,19 @@ inline bool QRecursiveMutexPrivate::lock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
}
if (success)
- owner.store(self);
+ owner.storeRelaxed(self);
return success;
}
/*!
\internal
*/
-inline void QRecursiveMutexPrivate::unlock() Q_DECL_NOTHROW
+inline void QRecursiveMutexPrivate::unlock() noexcept
{
if (count > 0) {
count--;
} else {
- owner.store(0);
+ owner.storeRelaxed(0);
mutex.QBasicMutex::unlock();
}
}
diff --git a/src/corelib/thread/qmutex.h b/src/corelib/thread/qmutex.h
index 837355a602..0de0869cb2 100644
--- a/src/corelib/thread/qmutex.h
+++ b/src/corelib/thread/qmutex.h
@@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE
#if QT_CONFIG(thread) || defined(Q_CLANG_QDOC)
#ifdef Q_OS_LINUX
-# define QT_MUTEX_LOCK_NOEXCEPT Q_DECL_NOTHROW
+# define QT_MUTEX_LOCK_NOEXCEPT noexcept
#else
# define QT_MUTEX_LOCK_NOEXCEPT
#endif
@@ -80,39 +80,39 @@ public:
}
// BasicLockable concept
- inline void unlock() Q_DECL_NOTHROW {
- Q_ASSERT(d_ptr.load()); //mutex must be locked
+ inline void unlock() noexcept {
+ Q_ASSERT(d_ptr.loadRelaxed()); //mutex must be locked
if (!fastTryUnlock())
unlockInternal();
}
- bool tryLock() Q_DECL_NOTHROW {
+ bool tryLock() noexcept {
return fastTryLock();
}
// Lockable concept
- bool try_lock() Q_DECL_NOTHROW { return tryLock(); }
+ bool try_lock() noexcept { return tryLock(); }
- bool isRecursive() Q_DECL_NOTHROW; //### Qt6: remove me
- bool isRecursive() const Q_DECL_NOTHROW;
+ bool isRecursive() noexcept; //### Qt6: remove me
+ bool isRecursive() const noexcept;
private:
- inline bool fastTryLock() Q_DECL_NOTHROW {
+ inline bool fastTryLock() noexcept {
return d_ptr.testAndSetAcquire(nullptr, dummyLocked());
}
- inline bool fastTryUnlock() Q_DECL_NOTHROW {
+ inline bool fastTryUnlock() noexcept {
return d_ptr.testAndSetRelease(dummyLocked(), nullptr);
}
- inline bool fastTryLock(QMutexData *&current) Q_DECL_NOTHROW {
+ inline bool fastTryLock(QMutexData *&current) noexcept {
return d_ptr.testAndSetAcquire(nullptr, dummyLocked(), current);
}
- inline bool fastTryUnlock(QMutexData *&current) Q_DECL_NOTHROW {
+ inline bool fastTryUnlock(QMutexData *&current) noexcept {
return d_ptr.testAndSetRelease(dummyLocked(), nullptr, current);
}
void lockInternal() QT_MUTEX_LOCK_NOEXCEPT;
bool lockInternal(int timeout) QT_MUTEX_LOCK_NOEXCEPT;
- void unlockInternal() Q_DECL_NOTHROW;
+ void unlockInternal() noexcept;
QBasicAtomicPointer<QMutexData> d_ptr;
static inline QMutexData *dummyLocked() {
@@ -134,7 +134,7 @@ public:
void lock() QT_MUTEX_LOCK_NOEXCEPT;
bool tryLock(int timeout = 0) QT_MUTEX_LOCK_NOEXCEPT;
// BasicLockable concept
- void unlock() Q_DECL_NOTHROW;
+ void unlock() noexcept;
// Lockable concept
bool try_lock() QT_MUTEX_LOCK_NOEXCEPT { return tryLock(); }
@@ -158,7 +158,7 @@ public:
}
#endif
- bool isRecursive() const Q_DECL_NOTHROW
+ bool isRecursive() const noexcept
{ return QBasicMutex::isRecursive(); }
private:
@@ -212,7 +212,7 @@ public:
#endif
inline ~QMutexLocker() { unlock(); }
- inline void unlock() Q_DECL_NOTHROW
+ inline void unlock() noexcept
{
if ((val & quintptr(1u)) == quintptr(1u)) {
val &= ~quintptr(1u);
@@ -257,24 +257,24 @@ class Q_CORE_EXPORT QMutex
public:
enum RecursionMode { NonRecursive, Recursive };
- inline Q_DECL_CONSTEXPR explicit QMutex(RecursionMode = NonRecursive) Q_DECL_NOTHROW { }
+ inline Q_DECL_CONSTEXPR explicit QMutex(RecursionMode = NonRecursive) noexcept { }
- inline void lock() Q_DECL_NOTHROW {}
- inline bool tryLock(int timeout = 0) Q_DECL_NOTHROW { Q_UNUSED(timeout); return true; }
- inline bool try_lock() Q_DECL_NOTHROW { return true; }
- inline void unlock() Q_DECL_NOTHROW {}
- inline bool isRecursive() const Q_DECL_NOTHROW { return true; }
+ inline void lock() noexcept {}
+ inline bool tryLock(int timeout = 0) noexcept { Q_UNUSED(timeout); return true; }
+ inline bool try_lock() noexcept { return true; }
+ inline void unlock() noexcept {}
+ inline bool isRecursive() const noexcept { return true; }
#if QT_HAS_INCLUDE(<chrono>)
template <class Rep, class Period>
- inline bool try_lock_for(std::chrono::duration<Rep, Period> duration) Q_DECL_NOTHROW
+ inline bool try_lock_for(std::chrono::duration<Rep, Period> duration) noexcept
{
Q_UNUSED(duration);
return true;
}
template<class Clock, class Duration>
- inline bool try_lock_until(std::chrono::time_point<Clock, Duration> timePoint) Q_DECL_NOTHROW
+ inline bool try_lock_until(std::chrono::time_point<Clock, Duration> timePoint) noexcept
{
Q_UNUSED(timePoint);
return true;
@@ -288,12 +288,12 @@ private:
class Q_CORE_EXPORT QMutexLocker
{
public:
- inline explicit QMutexLocker(QMutex *) Q_DECL_NOTHROW {}
- inline ~QMutexLocker() Q_DECL_NOTHROW {}
+ inline explicit QMutexLocker(QMutex *) noexcept {}
+ inline ~QMutexLocker() noexcept {}
- inline void unlock() Q_DECL_NOTHROW {}
- void relock() Q_DECL_NOTHROW {}
- inline QMutex *mutex() const Q_DECL_NOTHROW { return nullptr; }
+ inline void unlock() noexcept {}
+ void relock() noexcept {}
+ inline QMutex *mutex() const noexcept { return nullptr; }
private:
Q_DISABLE_COPY(QMutexLocker)
diff --git a/src/corelib/thread/qmutex_linux.cpp b/src/corelib/thread/qmutex_linux.cpp
index 507e72cb76..3270875471 100644
--- a/src/corelib/thread/qmutex_linux.cpp
+++ b/src/corelib/thread/qmutex_linux.cpp
@@ -106,7 +106,7 @@ static inline QMutexData *dummyFutexValue()
}
template <bool IsTimed> static inline
-bool lockInternal_helper(QBasicAtomicPointer<QMutexData> &d_ptr, int timeout = -1, QElapsedTimer *elapsedTimer = 0) Q_DECL_NOTHROW
+bool lockInternal_helper(QBasicAtomicPointer<QMutexData> &d_ptr, int timeout = -1, QElapsedTimer *elapsedTimer = 0) noexcept
{
if (!IsTimed)
timeout = -1;
@@ -149,17 +149,17 @@ bool lockInternal_helper(QBasicAtomicPointer<QMutexData> &d_ptr, int timeout = -
}
}
- Q_ASSERT(d_ptr.load());
+ Q_ASSERT(d_ptr.loadRelaxed());
return true;
}
-void QBasicMutex::lockInternal() Q_DECL_NOTHROW
+void QBasicMutex::lockInternal() noexcept
{
Q_ASSERT(!isRecursive());
lockInternal_helper<false>(d_ptr);
}
-bool QBasicMutex::lockInternal(int timeout) Q_DECL_NOTHROW
+bool QBasicMutex::lockInternal(int timeout) noexcept
{
Q_ASSERT(!isRecursive());
QElapsedTimer elapsedTimer;
@@ -167,9 +167,9 @@ bool QBasicMutex::lockInternal(int timeout) Q_DECL_NOTHROW
return lockInternal_helper<true>(d_ptr, timeout, &elapsedTimer);
}
-void QBasicMutex::unlockInternal() Q_DECL_NOTHROW
+void QBasicMutex::unlockInternal() noexcept
{
- QMutexData *d = d_ptr.load();
+ QMutexData *d = d_ptr.loadRelaxed();
Q_ASSERT(d); //we must be locked
Q_ASSERT(d != dummyLocked()); // testAndSetRelease(dummyLocked(), 0) failed
Q_UNUSED(d);
diff --git a/src/corelib/thread/qmutex_mac.cpp b/src/corelib/thread/qmutex_mac.cpp
index 9a8d9bc750..923f89f697 100644
--- a/src/corelib/thread/qmutex_mac.cpp
+++ b/src/corelib/thread/qmutex_mac.cpp
@@ -79,7 +79,7 @@ bool QMutexPrivate::wait(int timeout)
return (r == KERN_SUCCESS);
}
-void QMutexPrivate::wakeUp() Q_DECL_NOTHROW
+void QMutexPrivate::wakeUp() noexcept
{
semaphore_signal(mach_semaphore);
}
diff --git a/src/corelib/thread/qmutex_p.h b/src/corelib/thread/qmutex_p.h
index ec9bfc1152..048d8707c4 100644
--- a/src/corelib/thread/qmutex_p.h
+++ b/src/corelib/thread/qmutex_p.h
@@ -92,28 +92,28 @@ public:
QMutexPrivate();
bool wait(int timeout = -1);
- void wakeUp() Q_DECL_NOTHROW;
+ void wakeUp() noexcept;
// Control the lifetime of the privates
QAtomicInt refCount;
int id;
bool ref() {
- Q_ASSERT(refCount.load() >= 0);
+ Q_ASSERT(refCount.loadRelaxed() >= 0);
int c;
do {
- c = refCount.load();
+ c = refCount.loadRelaxed();
if (c == 0)
return false;
} while (!refCount.testAndSetRelaxed(c, c + 1));
- Q_ASSERT(refCount.load() >= 0);
+ Q_ASSERT(refCount.loadRelaxed() >= 0);
return true;
}
void deref() {
- Q_ASSERT(refCount.load() >= 0);
+ Q_ASSERT(refCount.loadRelaxed() >= 0);
if (!refCount.deref())
release();
- Q_ASSERT(refCount.load() >= 0);
+ Q_ASSERT(refCount.loadRelaxed() >= 0);
}
void release();
static QMutexPrivate *allocate();
@@ -125,7 +125,7 @@ public:
when the mutex is unlocked.
*/
enum { BigNumber = 0x100000 }; //Must be bigger than the possible number of waiters (number of threads)
- void derefWaiters(int value) Q_DECL_NOTHROW;
+ void derefWaiters(int value) noexcept;
//platform specific stuff
#if defined(Q_OS_MAC)
diff --git a/src/corelib/thread/qmutex_unix.cpp b/src/corelib/thread/qmutex_unix.cpp
index 3ee24a292c..df2f606a23 100644
--- a/src/corelib/thread/qmutex_unix.cpp
+++ b/src/corelib/thread/qmutex_unix.cpp
@@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE
static void report_error(int code, const char *where, const char *what)
{
if (code != 0)
- qWarning("%s: %s failure: %s", where, what, qPrintable(qt_error_string(code)));
+ qErrnoWarning(code, "%s: %s failure", where, what);
}
#ifdef QT_UNIX_SEMAPHORE
@@ -99,7 +99,7 @@ bool QMutexPrivate::wait(int timeout)
return true;
}
-void QMutexPrivate::wakeUp() Q_DECL_NOTHROW
+void QMutexPrivate::wakeUp() noexcept
{
report_error(sem_post(&semaphore), "QMutex::unlock", "sem_post");
}
@@ -146,7 +146,7 @@ bool QMutexPrivate::wait(int timeout)
return ret;
}
-void QMutexPrivate::wakeUp() Q_DECL_NOTHROW
+void QMutexPrivate::wakeUp() noexcept
{
report_error(pthread_mutex_lock(&mutex), "QMutex::unlock", "mutex lock");
wakeup = true;
diff --git a/src/corelib/thread/qmutex_win.cpp b/src/corelib/thread/qmutex_win.cpp
index 3c314a4c0c..e221bc89cb 100644
--- a/src/corelib/thread/qmutex_win.cpp
+++ b/src/corelib/thread/qmutex_win.cpp
@@ -64,7 +64,7 @@ bool QMutexPrivate::wait(int timeout)
return (WaitForSingleObjectEx(event, timeout < 0 ? INFINITE : timeout, FALSE) == WAIT_OBJECT_0);
}
-void QMutexPrivate::wakeUp() Q_DECL_NOTHROW
+void QMutexPrivate::wakeUp() noexcept
{ SetEvent(event); }
QT_END_NAMESPACE
diff --git a/src/corelib/thread/qmutexpool.cpp b/src/corelib/thread/qmutexpool.cpp
index 3f9e8da942..2a02197859 100644
--- a/src/corelib/thread/qmutexpool.cpp
+++ b/src/corelib/thread/qmutexpool.cpp
@@ -93,7 +93,7 @@ QMutexPool::QMutexPool(QMutex::RecursionMode recursionMode, int size)
: mutexes(size), recursionMode(recursionMode)
{
for (int index = 0; index < mutexes.count(); ++index) {
- mutexes[index].store(0);
+ mutexes[index].storeRelaxed(0);
}
}
@@ -104,7 +104,7 @@ QMutexPool::QMutexPool(QMutex::RecursionMode recursionMode, int size)
QMutexPool::~QMutexPool()
{
for (int index = 0; index < mutexes.count(); ++index)
- delete mutexes[index].load();
+ delete mutexes[index].loadRelaxed();
}
/*!
@@ -131,7 +131,7 @@ QMutex *QMutexPool::createMutex(int index)
QMutex *newMutex = new QMutex(recursionMode);
if (!mutexes[index].testAndSetRelease(0, newMutex))
delete newMutex;
- return mutexes[index].load();
+ return mutexes[index].loadRelaxed();
}
/*!
diff --git a/src/corelib/thread/qmutexpool_p.h b/src/corelib/thread/qmutexpool_p.h
index 89d006ac29..1a47231abc 100644
--- a/src/corelib/thread/qmutexpool_p.h
+++ b/src/corelib/thread/qmutexpool_p.h
@@ -68,7 +68,7 @@ public:
inline QMutex *get(const void *address) {
int index = uint(quintptr(address)) % mutexes.count();
- QMutex *m = mutexes[index].load();
+ QMutex *m = mutexes[index].loadRelaxed();
if (m)
return m;
else
diff --git a/src/corelib/thread/qorderedmutexlocker_p.h b/src/corelib/thread/qorderedmutexlocker_p.h
index ded102d32d..e0a67388d4 100644
--- a/src/corelib/thread/qorderedmutexlocker_p.h
+++ b/src/corelib/thread/qorderedmutexlocker_p.h
@@ -58,6 +58,8 @@
QT_BEGIN_NAMESPACE
+#if QT_CONFIG(thread)
+
/*
Locks 2 mutexes in a defined order, avoiding a recursive lock if
we're trying to lock the same mutex twice.
@@ -65,9 +67,9 @@ QT_BEGIN_NAMESPACE
class QOrderedMutexLocker
{
public:
- QOrderedMutexLocker(QMutex *m1, QMutex *m2)
- : mtx1((m1 == m2) ? m1 : (std::less<QMutex *>()(m1, m2) ? m1 : m2)),
- mtx2((m1 == m2) ? 0 : (std::less<QMutex *>()(m1, m2) ? m2 : m1)),
+ QOrderedMutexLocker(QBasicMutex *m1, QBasicMutex *m2)
+ : mtx1((m1 == m2) ? m1 : (std::less<QBasicMutex *>()(m1, m2) ? m1 : m2)),
+ mtx2((m1 == m2) ? 0 : (std::less<QBasicMutex *>()(m1, m2) ? m2 : m1)),
locked(false)
{
relock();
@@ -95,12 +97,12 @@ public:
}
}
- static bool relock(QMutex *mtx1, QMutex *mtx2)
+ static bool relock(QBasicMutex *mtx1, QBasicMutex *mtx2)
{
// mtx1 is already locked, mtx2 not... do we need to unlock and relock?
if (mtx1 == mtx2)
return false;
- if (std::less<QMutex *>()(mtx1, mtx2)) {
+ if (std::less<QBasicMutex *>()(mtx1, mtx2)) {
mtx2->lock();
return true;
}
@@ -113,10 +115,58 @@ public:
}
private:
- QMutex *mtx1, *mtx2;
+ QBasicMutex *mtx1, *mtx2;
bool locked;
};
+class QBasicMutexLocker
+{
+public:
+ inline explicit QBasicMutexLocker(QBasicMutex *m) QT_MUTEX_LOCK_NOEXCEPT
+ : m(m), isLocked(true)
+ {
+ m->lock();
+ }
+ inline ~QBasicMutexLocker() { if (isLocked) unlock(); }
+
+ inline void unlock() noexcept
+ {
+ isLocked = false;
+ m->unlock();
+ }
+
+ inline void relock() QT_MUTEX_LOCK_NOEXCEPT
+ {
+ isLocked = true;
+ m->lock();
+ }
+
+private:
+ Q_DISABLE_COPY(QBasicMutexLocker)
+
+ QBasicMutex *m;
+ bool isLocked;
+};
+
+#else
+
+class QOrderedMutexLocker
+{
+public:
+ QOrderedMutexLocker(QBasicMutex *, QBasicMutex *) {}
+ ~QOrderedMutexLocker() {}
+
+ void relock() {}
+ void unlock() {}
+
+ static bool relock(QBasicMutex *, QBasicMutex *) {}
+};
+
+using QBasicMutexLocker = QMutexLocker;
+
+#endif
+
+
QT_END_NAMESPACE
#endif
diff --git a/src/corelib/thread/qreadwritelock.cpp b/src/corelib/thread/qreadwritelock.cpp
index d7cf7a7284..30e9b95a52 100644
--- a/src/corelib/thread/qreadwritelock.cpp
+++ b/src/corelib/thread/qreadwritelock.cpp
@@ -143,7 +143,7 @@ inline bool isUncontendedLocked(const QReadWriteLockPrivate *d)
QReadWriteLock::QReadWriteLock(RecursionMode recursionMode)
: d_ptr(recursionMode == Recursive ? new QReadWriteLockPrivate(true) : nullptr)
{
- Q_ASSERT_X(!(quintptr(d_ptr.load()) & StateMask), "QReadWriteLock::QReadWriteLock", "bad d_ptr alignment");
+ Q_ASSERT_X(!(quintptr(d_ptr.loadRelaxed()) & StateMask), "QReadWriteLock::QReadWriteLock", "bad d_ptr alignment");
}
/*!
@@ -154,7 +154,7 @@ QReadWriteLock::QReadWriteLock(RecursionMode recursionMode)
*/
QReadWriteLock::~QReadWriteLock()
{
- auto d = d_ptr.load();
+ auto d = d_ptr.loadRelaxed();
if (isUncontendedLocked(d)) {
qWarning("QReadWriteLock: destroying locked QReadWriteLock");
return;
@@ -263,7 +263,7 @@ bool QReadWriteLock::tryLockForRead(int timeout)
return d->recursiveLockForRead(timeout);
QMutexLocker lock(&d->mutex);
- if (d != d_ptr.load()) {
+ if (d != d_ptr.loadRelaxed()) {
// d_ptr has changed: this QReadWriteLock was unlocked before we had
// time to lock d->mutex.
// We are holding a lock to a mutex within a QReadWriteLockPrivate
@@ -370,7 +370,7 @@ bool QReadWriteLock::tryLockForWrite(int timeout)
return d->recursiveLockForWrite(timeout);
QMutexLocker lock(&d->mutex);
- if (d != d_ptr.load()) {
+ if (d != d_ptr.loadRelaxed()) {
// The mutex was unlocked before we had time to lock the mutex.
// We are holding to a mutex within a QReadWriteLockPrivate that is already released
// (or even is already re-used) but that's ok because the QFreeList never frees them.
@@ -433,7 +433,7 @@ void QReadWriteLock::unlock()
if (d->waitingReaders || d->waitingWriters) {
d->unlock();
} else {
- Q_ASSERT(d_ptr.load() == d); // should not change when we still hold the mutex
+ Q_ASSERT(d_ptr.loadRelaxed() == d); // should not change when we still hold the mutex
d_ptr.storeRelease(nullptr);
d->release();
}
@@ -444,7 +444,7 @@ void QReadWriteLock::unlock()
/*! \internal Helper for QWaitCondition::wait */
QReadWriteLock::StateForWaitCondition QReadWriteLock::stateForWaitCondition() const
{
- QReadWriteLockPrivate *d = d_ptr.load();
+ QReadWriteLockPrivate *d = d_ptr.loadRelaxed();
switch (quintptr(d) & StateMask) {
case StateLockedForRead: return LockedForRead;
case StateLockedForWrite: return LockedForWrite;
diff --git a/src/corelib/thread/qreadwritelock.h b/src/corelib/thread/qreadwritelock.h
index 65fa76fd6d..139fde9214 100644
--- a/src/corelib/thread/qreadwritelock.h
+++ b/src/corelib/thread/qreadwritelock.h
@@ -180,18 +180,18 @@ class Q_CORE_EXPORT QReadWriteLock
{
public:
enum RecursionMode { NonRecursive, Recursive };
- inline explicit QReadWriteLock(RecursionMode = NonRecursive) Q_DECL_NOTHROW { }
+ inline explicit QReadWriteLock(RecursionMode = NonRecursive) noexcept { }
inline ~QReadWriteLock() { }
- static inline void lockForRead() Q_DECL_NOTHROW { }
- static inline bool tryLockForRead() Q_DECL_NOTHROW { return true; }
- static inline bool tryLockForRead(int timeout) Q_DECL_NOTHROW { Q_UNUSED(timeout); return true; }
+ static inline void lockForRead() noexcept { }
+ static inline bool tryLockForRead() noexcept { return true; }
+ static inline bool tryLockForRead(int timeout) noexcept { Q_UNUSED(timeout); return true; }
- static inline void lockForWrite() Q_DECL_NOTHROW { }
- static inline bool tryLockForWrite() Q_DECL_NOTHROW { return true; }
- static inline bool tryLockForWrite(int timeout) Q_DECL_NOTHROW { Q_UNUSED(timeout); return true; }
+ static inline void lockForWrite() noexcept { }
+ static inline bool tryLockForWrite() noexcept { return true; }
+ static inline bool tryLockForWrite(int timeout) noexcept { Q_UNUSED(timeout); return true; }
- static inline void unlock() Q_DECL_NOTHROW { }
+ static inline void unlock() noexcept { }
private:
Q_DISABLE_COPY(QReadWriteLock)
@@ -200,12 +200,12 @@ private:
class Q_CORE_EXPORT QReadLocker
{
public:
- inline QReadLocker(QReadWriteLock *) Q_DECL_NOTHROW { }
- inline ~QReadLocker() Q_DECL_NOTHROW { }
+ inline QReadLocker(QReadWriteLock *) noexcept { }
+ inline ~QReadLocker() noexcept { }
- static inline void unlock() Q_DECL_NOTHROW { }
- static inline void relock() Q_DECL_NOTHROW { }
- static inline QReadWriteLock *readWriteLock() Q_DECL_NOTHROW { return nullptr; }
+ static inline void unlock() noexcept { }
+ static inline void relock() noexcept { }
+ static inline QReadWriteLock *readWriteLock() noexcept { return nullptr; }
private:
Q_DISABLE_COPY(QReadLocker)
@@ -214,12 +214,12 @@ private:
class Q_CORE_EXPORT QWriteLocker
{
public:
- inline explicit QWriteLocker(QReadWriteLock *) Q_DECL_NOTHROW { }
- inline ~QWriteLocker() Q_DECL_NOTHROW { }
+ inline explicit QWriteLocker(QReadWriteLock *) noexcept { }
+ inline ~QWriteLocker() noexcept { }
- static inline void unlock() Q_DECL_NOTHROW { }
- static inline void relock() Q_DECL_NOTHROW { }
- static inline QReadWriteLock *readWriteLock() Q_DECL_NOTHROW { return nullptr; }
+ static inline void unlock() noexcept { }
+ static inline void relock() noexcept { }
+ static inline QReadWriteLock *readWriteLock() noexcept { return nullptr; }
private:
Q_DISABLE_COPY(QWriteLocker)
diff --git a/src/corelib/thread/qresultstore.cpp b/src/corelib/thread/qresultstore.cpp
index e0ce1b4b78..1b3bc20eca 100644
--- a/src/corelib/thread/qresultstore.cpp
+++ b/src/corelib/thread/qresultstore.cpp
@@ -43,6 +43,21 @@ QT_BEGIN_NAMESPACE
namespace QtPrivate {
+/*!
+ \class QtPrivate::ResultItem
+ \internal
+ */
+
+/*!
+ \class QtPrivate::ResultIteratorBase
+ \internal
+ */
+
+/*!
+ \class QtPrivate::ResultStoreBase
+ \internal
+ */
+
ResultIteratorBase::ResultIteratorBase()
: mapIterator(QMap<int, ResultItem>::const_iterator()), m_vectorIndex(0) { }
ResultIteratorBase::ResultIteratorBase(QMap<int, ResultItem>::const_iterator _mapIterator, int _vectorIndex)
diff --git a/src/corelib/thread/qresultstore.h b/src/corelib/thread/qresultstore.h
index 39f0a6d1bb..7a65089396 100644
--- a/src/corelib/thread/qresultstore.h
+++ b/src/corelib/thread/qresultstore.h
@@ -56,7 +56,6 @@ QT_BEGIN_NAMESPACE
either individually or in batches.
*/
-#ifndef Q_QDOC
namespace QtPrivate {
@@ -143,7 +142,7 @@ public:
template <typename T>
int addResult(int index, const T *result)
{
- if (result == 0)
+ if (result == nullptr)
return addResult(index, static_cast<void *>(nullptr));
else
return addResult(index, static_cast<void *>(new T(*result)));
@@ -159,7 +158,7 @@ public:
int addResults(int index, const QVector<T> *results, int totalCount)
{
if (m_filterMode == true && results->count() != totalCount && 0 == results->count())
- return addResults(index, 0, 0, totalCount);
+ return addResults(index, nullptr, 0, totalCount);
else
return addResults(index, new QVector<T>(*results), results->count(), totalCount);
}
@@ -196,7 +195,6 @@ public:
Q_DECLARE_TYPEINFO(QtPrivate::ResultItem, Q_PRIMITIVE_TYPE);
-#endif //Q_QDOC
QT_END_NAMESPACE
diff --git a/src/corelib/thread/qsemaphore.cpp b/src/corelib/thread/qsemaphore.cpp
index aa04fb10ff..d4fb756b94 100644
--- a/src/corelib/thread/qsemaphore.cpp
+++ b/src/corelib/thread/qsemaphore.cpp
@@ -264,7 +264,7 @@ template <bool IsTimed> bool futexSemaphoreTryAcquire(QBasicAtomicInteger<quintp
if (futexHasWaiterCount) {
// decrement the number of threads waiting
- Q_ASSERT(futexHigh32(&u)->load() & 0x7fffffffU);
+ Q_ASSERT(futexHigh32(&u)->loadRelaxed() & 0x7fffffffU);
u.fetchAndSubRelaxed(oneWaiter);
}
return false;
@@ -293,7 +293,7 @@ QSemaphore::QSemaphore(int n)
quintptr nn = unsigned(n);
if (futexHasWaiterCount)
nn |= quint64(nn) << 32; // token count replicated in high word
- u.store(nn);
+ u.storeRelaxed(nn);
} else {
d = new QSemaphorePrivate(n);
}
@@ -425,7 +425,7 @@ void QSemaphore::release(int n)
int QSemaphore::available() const
{
if (futexAvailable())
- return futexAvailCounter(u.load());
+ return futexAvailCounter(u.loadRelaxed());
QMutexLocker locker(&d->mutex);
return d->avail;
@@ -606,7 +606,7 @@ bool QSemaphore::tryAcquire(int n, int timeout)
\fn QSemaphoreReleaser::semaphore() const
Returns a pointer to the QSemaphore object provided to the constructor,
- or by the last move assignment, if any. Otherwise, returns \c nullptr.
+ or by the last move assignment, if any. Otherwise, returns \nullptr.
*/
/*!
@@ -614,7 +614,7 @@ bool QSemaphore::tryAcquire(int n, int timeout)
Cancels this QSemaphoreReleaser such that the destructor will no longer
call \c{semaphore()->release()}. Returns the value of semaphore()
- before this call. After this call, semaphore() will return \c nullptr.
+ before this call. After this call, semaphore() will return \nullptr.
To enable again, assign a new QSemaphoreReleaser:
diff --git a/src/corelib/thread/qsemaphore.h b/src/corelib/thread/qsemaphore.h
index b830ff1bfd..58c12997ad 100644
--- a/src/corelib/thread/qsemaphore.h
+++ b/src/corelib/thread/qsemaphore.h
@@ -75,14 +75,14 @@ class QSemaphoreReleaser
{
public:
QSemaphoreReleaser() = default;
- explicit QSemaphoreReleaser(QSemaphore &sem, int n = 1) Q_DECL_NOTHROW
+ explicit QSemaphoreReleaser(QSemaphore &sem, int n = 1) noexcept
: m_sem(&sem), m_n(n) {}
- explicit QSemaphoreReleaser(QSemaphore *sem, int n = 1) Q_DECL_NOTHROW
+ explicit QSemaphoreReleaser(QSemaphore *sem, int n = 1) noexcept
: m_sem(sem), m_n(n) {}
- QSemaphoreReleaser(QSemaphoreReleaser &&other) Q_DECL_NOTHROW
+ QSemaphoreReleaser(QSemaphoreReleaser &&other) noexcept
: m_sem(other.m_sem), m_n(other.m_n)
{ other.m_sem = nullptr; }
- QSemaphoreReleaser &operator=(QSemaphoreReleaser &&other) Q_DECL_NOTHROW
+ QSemaphoreReleaser &operator=(QSemaphoreReleaser &&other) noexcept
{ QSemaphoreReleaser moved(std::move(other)); swap(moved); return *this; }
~QSemaphoreReleaser()
@@ -91,16 +91,16 @@ public:
m_sem->release(m_n);
}
- void swap(QSemaphoreReleaser &other) Q_DECL_NOTHROW
+ void swap(QSemaphoreReleaser &other) noexcept
{
qSwap(m_sem, other.m_sem);
qSwap(m_n, other.m_n);
}
- QSemaphore *semaphore() const Q_DECL_NOTHROW
+ QSemaphore *semaphore() const noexcept
{ return m_sem; }
- QSemaphore *cancel() Q_DECL_NOTHROW
+ QSemaphore *cancel() noexcept
{
QSemaphore *old = m_sem;
m_sem = nullptr;
diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp
index 9f60de1f87..1eac7db11d 100644
--- a/src/corelib/thread/qthread.cpp
+++ b/src/corelib/thread/qthread.cpp
@@ -65,7 +65,7 @@ QThreadData::QThreadData(int initialRefCount)
QThreadData::~QThreadData()
{
- Q_ASSERT(_ref.load() == 0);
+ Q_ASSERT(_ref.loadRelaxed() == 0);
// In the odd case that Qt is running on a secondary thread, the main
// thread instance will have been dereffed asunder because of the deref in
@@ -105,7 +105,7 @@ void QThreadData::ref()
{
#if QT_CONFIG(thread)
(void) _ref.ref();
- Q_ASSERT(_ref.load() != 0);
+ Q_ASSERT(_ref.loadRelaxed() != 0);
#endif
}
@@ -839,7 +839,7 @@ bool QThread::event(QEvent* event)
return QObject::event(event);
}
-Qt::HANDLE QThread::currentThreadId() Q_DECL_NOTHROW
+Qt::HANDLE QThread::currentThreadId() noexcept
{
return Qt::HANDLE(currentThread());
}
@@ -849,7 +849,7 @@ QThread *QThread::currentThread()
return QThreadData::current()->thread;
}
-int QThread::idealThreadCount() Q_DECL_NOTHROW
+int QThread::idealThreadCount() noexcept
{
return 1;
}
@@ -878,11 +878,11 @@ QThreadData *QThreadData::current(bool createIfNecessary)
if (!data && createIfNecessary) {
data = new QThreadData;
data->thread = new QAdoptedThread(data);
- data->threadId.store(Qt::HANDLE(data->thread));
+ data->threadId.storeRelaxed(Qt::HANDLE(data->thread));
data->deref();
data->isAdopted = true;
if (!QCoreApplicationPrivate::theMainThread)
- QCoreApplicationPrivate::theMainThread = data->thread.load();
+ QCoreApplicationPrivate::theMainThread = data->thread.loadRelaxed();
}
return data;
}
@@ -925,7 +925,7 @@ QThreadPrivate::~QThreadPrivate()
QAbstractEventDispatcher *QThread::eventDispatcher() const
{
Q_D(const QThread);
- return d->data->eventDispatcher.load();
+ return d->data->eventDispatcher.loadRelaxed();
}
/*!
diff --git a/src/corelib/thread/qthread.h b/src/corelib/thread/qthread.h
index b6c5bf47d0..c7a6dc8f1a 100644
--- a/src/corelib/thread/qthread.h
+++ b/src/corelib/thread/qthread.h
@@ -70,9 +70,9 @@ class Q_CORE_EXPORT QThread : public QObject
{
Q_OBJECT
public:
- static Qt::HANDLE currentThreadId() Q_DECL_NOTHROW Q_DECL_PURE_FUNCTION;
+ static Qt::HANDLE currentThreadId() noexcept Q_DECL_PURE_FUNCTION;
static QThread *currentThread();
- static int idealThreadCount() Q_DECL_NOTHROW;
+ static int idealThreadCount() noexcept;
static void yieldCurrentThread();
explicit QThread(QObject *parent = nullptr);
@@ -209,7 +209,6 @@ struct Callable
{
}
-#if defined(Q_COMPILER_DEFAULT_MEMBERS) && defined(Q_COMPILER_DELETE_MEMBERS)
// Apply the same semantics of a lambda closure type w.r.t. the special
// member functions, if possible: delete the copy assignment operator,
// bring back all the others as per the RO5 (cf. ยง8.1.5.1/11 [expr.prim.lambda.closure])
@@ -218,7 +217,6 @@ struct Callable
Callable(Callable &&) = default;
Callable &operator=(const Callable &) = delete;
Callable &operator=(Callable &&) = default;
-#endif
void operator()()
{
diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h
index 7d9442ab79..b2d1628e6e 100644
--- a/src/corelib/thread/qthread_p.h
+++ b/src/corelib/thread/qthread_p.h
@@ -89,7 +89,7 @@ public:
QEvent *event;
int priority;
inline QPostEvent()
- : receiver(0), event(0), priority(0)
+ : receiver(nullptr), event(nullptr), priority(0)
{ }
inline QPostEvent(QObject *r, QEvent *e, int p)
: receiver(r), event(e), priority(p)
@@ -148,7 +148,7 @@ private:
class Q_CORE_EXPORT QDaemonThread : public QThread
{
public:
- QDaemonThread(QObject *parent = 0);
+ QDaemonThread(QObject *parent = nullptr);
~QDaemonThread();
};
@@ -157,7 +157,7 @@ class QThreadPrivate : public QObjectPrivate
Q_DECLARE_PUBLIC(QThread)
public:
- QThreadPrivate(QThreadData *d = 0);
+ QThreadPrivate(QThreadData *d = nullptr);
~QThreadPrivate();
void setPriority(QThread::Priority prio);
@@ -187,14 +187,17 @@ public:
#endif // Q_OS_UNIX
#ifdef Q_OS_WIN
- static unsigned int __stdcall start(void *) Q_DECL_NOEXCEPT;
- static void finish(void *, bool lockAnyway=true) Q_DECL_NOEXCEPT;
+ static unsigned int __stdcall start(void *) noexcept;
+ static void finish(void *, bool lockAnyway=true) noexcept;
Qt::HANDLE handle;
unsigned int id;
int waiters;
bool terminationEnabled, terminatePending;
#endif // Q_OS_WIN
+#ifdef Q_OS_WASM
+ static int idealThreadCount;
+#endif
QThreadData *data;
static QAbstractEventDispatcher *createEventDispatcher(QThreadData *data);
@@ -248,17 +251,17 @@ public:
#endif
static void clearCurrentThreadData();
static QThreadData *get2(QThread *thread)
- { Q_ASSERT_X(thread != 0, "QThread", "internal error"); return thread->d_func()->data; }
+ { Q_ASSERT_X(thread != nullptr, "QThread", "internal error"); return thread->d_func()->data; }
void ref();
void deref();
inline bool hasEventDispatcher() const
- { return eventDispatcher.load() != nullptr; }
+ { return eventDispatcher.loadRelaxed() != nullptr; }
QAbstractEventDispatcher *createEventDispatcher();
QAbstractEventDispatcher *ensureEventDispatcher()
{
- QAbstractEventDispatcher *ed = eventDispatcher.load();
+ QAbstractEventDispatcher *ed = eventDispatcher.loadRelaxed();
if (Q_LIKELY(ed))
return ed;
return createEventDispatcher();
@@ -281,7 +284,7 @@ public:
public:
FlaggedDebugSignatures() : idx(0)
- { std::fill_n(locations, Count, static_cast<char*>(0)); }
+ { std::fill_n(locations, Count, static_cast<char*>(nullptr)); }
void store(const char* method)
{ locations[idx++ % Count] = method; }
@@ -328,7 +331,7 @@ class QAdoptedThread : public QThread
Q_DECLARE_PRIVATE(QThread)
public:
- QAdoptedThread(QThreadData *data = 0);
+ QAdoptedThread(QThreadData *data = nullptr);
~QAdoptedThread();
void init();
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index 695d45d8e7..89efbff6aa 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -100,7 +100,6 @@
#include <sys/neutrino.h>
#endif
-
QT_BEGIN_NAMESPACE
#if QT_CONFIG(thread)
@@ -116,6 +115,9 @@ enum { ThreadPriorityResetFlag = 0x80000000 };
#if defined(Q_CC_XLC) || defined (Q_CC_SUN)
#define HAVE_TLS
#endif
+#if defined(Q_OS_RTEMS)
+#define HAVE_TLS
+#endif
#ifdef HAVE_TLS
static __thread QThreadData *currentThreadData = 0;
@@ -250,9 +252,9 @@ QThreadData *QThreadData::current(bool createIfNecessary)
}
data->deref();
data->isAdopted = true;
- data->threadId.store(to_HANDLE(pthread_self()));
+ data->threadId.storeRelaxed(to_HANDLE(pthread_self()));
if (!QCoreApplicationPrivate::theMainThread)
- QCoreApplicationPrivate::theMainThread = data->thread.load();
+ QCoreApplicationPrivate::theMainThread = data->thread.loadRelaxed();
}
return data;
}
@@ -332,7 +334,7 @@ void *QThreadPrivate::start(void *arg)
thr->d_func()->setPriority(QThread::Priority(thr->d_func()->priority & ~ThreadPriorityResetFlag));
}
- data->threadId.store(to_HANDLE(pthread_self()));
+ data->threadId.storeRelaxed(to_HANDLE(pthread_self()));
set_thread_data(data);
data->ref();
@@ -402,7 +404,7 @@ void QThreadPrivate::finish(void *arg)
QThreadStorageData::finish((void **)data);
locker.relock();
- QAbstractEventDispatcher *eventDispatcher = d->data->eventDispatcher.load();
+ QAbstractEventDispatcher *eventDispatcher = d->data->eventDispatcher.loadRelaxed();
if (eventDispatcher) {
d->data->eventDispatcher = 0;
locker.unlock();
@@ -440,7 +442,7 @@ void QThreadPrivate::finish(void *arg)
** QThread
*************************************************************************/
-Qt::HANDLE QThread::currentThreadId() Q_DECL_NOTHROW
+Qt::HANDLE QThread::currentThreadId() noexcept
{
// requires a C cast here otherwise we run into trouble on AIX
return to_HANDLE(pthread_self());
@@ -451,7 +453,11 @@ Qt::HANDLE QThread::currentThreadId() Q_DECL_NOTHROW
# define _SC_NPROCESSORS_ONLN 84
#endif
-int QThread::idealThreadCount() Q_DECL_NOTHROW
+#ifdef Q_OS_WASM
+int QThreadPrivate::idealThreadCount = 1;
+#endif
+
+int QThread::idealThreadCount() noexcept
{
int cores = 1;
@@ -499,6 +505,8 @@ int QThread::idealThreadCount() Q_DECL_NOTHROW
// as of aug 2008 VxWorks < 6.6 only supports one single core CPU
cores = 1;
# endif
+#elif defined(Q_OS_WASM)
+ cores = QThreadPrivate::idealThreadCount;
#else
// the rest: Linux, Solaris, AIX, Tru64
cores = (int)sysconf(_SC_NPROCESSORS_ONLN);
@@ -709,8 +717,7 @@ void QThread::start(Priority priority)
#endif // _POSIX_THREAD_ATTR_STACKSIZE
if (code) {
- qWarning("QThread::start: Thread stack size error: %s",
- qPrintable(qt_error_string(code)));
+ qErrnoWarning(code, "QThread::start: Thread stack size error");
// we failed to set the stacksize, and as the documentation states,
// the thread will fail to run...
@@ -736,16 +743,16 @@ void QThread::start(Priority priority)
#endif
code = pthread_create(&threadId, &attr, QThreadPrivate::start, this);
}
- d->data->threadId.store(to_HANDLE(threadId));
+ d->data->threadId.storeRelaxed(to_HANDLE(threadId));
pthread_attr_destroy(&attr);
if (code) {
- qWarning("QThread::start: Thread creation error: %s", qPrintable(qt_error_string(code)));
+ qErrnoWarning(code, "QThread::start: Thread creation error");
d->running = false;
d->finished = false;
- d->data->threadId.store(nullptr);
+ d->data->threadId.storeRelaxed(nullptr);
}
}
@@ -755,13 +762,12 @@ void QThread::terminate()
Q_D(QThread);
QMutexLocker locker(&d->mutex);
- if (!d->data->threadId.load())
+ if (!d->data->threadId.loadRelaxed())
return;
- int code = pthread_cancel(from_HANDLE<pthread_t>(d->data->threadId.load()));
+ int code = pthread_cancel(from_HANDLE<pthread_t>(d->data->threadId.loadRelaxed()));
if (code) {
- qWarning("QThread::start: Thread termination error: %s",
- qPrintable(qt_error_string((code))));
+ qErrnoWarning(code, "QThread::start: Thread termination error");
}
#endif
}
@@ -771,7 +777,7 @@ bool QThread::wait(unsigned long time)
Q_D(QThread);
QMutexLocker locker(&d->mutex);
- if (from_HANDLE<pthread_t>(d->data->threadId.load()) == pthread_self()) {
+ if (from_HANDLE<pthread_t>(d->data->threadId.loadRelaxed()) == pthread_self()) {
qWarning("QThread::wait: Thread tried to wait on itself");
return false;
}
@@ -813,7 +819,7 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority)
int sched_policy;
sched_param param;
- if (pthread_getschedparam(from_HANDLE<pthread_t>(data->threadId.load()), &sched_policy, &param) != 0) {
+ if (pthread_getschedparam(from_HANDLE<pthread_t>(data->threadId.loadRelaxed()), &sched_policy, &param) != 0) {
// failed to get the scheduling policy, don't bother setting
// the priority
qWarning("QThread::setPriority: Cannot get scheduler parameters");
@@ -829,15 +835,15 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority)
}
param.sched_priority = prio;
- int status = pthread_setschedparam(from_HANDLE<pthread_t>(data->threadId.load()), sched_policy, &param);
+ int status = pthread_setschedparam(from_HANDLE<pthread_t>(data->threadId.loadRelaxed()), sched_policy, &param);
# ifdef SCHED_IDLE
// were we trying to set to idle priority and failed?
if (status == -1 && sched_policy == SCHED_IDLE && errno == EINVAL) {
// reset to lowest priority possible
- pthread_getschedparam(from_HANDLE<pthread_t>(data->threadId.load()), &sched_policy, &param);
+ pthread_getschedparam(from_HANDLE<pthread_t>(data->threadId.loadRelaxed()), &sched_policy, &param);
param.sched_priority = sched_get_priority_min(sched_policy);
- pthread_setschedparam(from_HANDLE<pthread_t>(data->threadId.load()), sched_policy, &param);
+ pthread_setschedparam(from_HANDLE<pthread_t>(data->threadId.loadRelaxed()), sched_policy, &param);
}
# else
Q_UNUSED(status);
diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp
index e56fe2c6ae..f8a0b0abaa 100644
--- a/src/corelib/thread/qthread_win.cpp
+++ b/src/corelib/thread/qthread_win.cpp
@@ -138,11 +138,11 @@ QThreadData *QThreadData::current(bool createIfNecessary)
}
threadData->deref();
threadData->isAdopted = true;
- threadData->threadId.store(reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId())));
+ threadData->threadId.storeRelaxed(reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId())));
#ifndef Q_OS_WINRT
if (!QCoreApplicationPrivate::theMainThread) {
- QCoreApplicationPrivate::theMainThread = threadData->thread.load();
+ QCoreApplicationPrivate::theMainThread = threadData->thread.loadRelaxed();
} else {
#else
// for winrt the main thread is set explicitly in QCoreApplication's constructor as the
@@ -184,9 +184,9 @@ void QThreadData::setMainThread()
}
threadData->deref();
threadData->isAdopted = true;
- threadData->threadId.store(reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId())));
+ threadData->threadId.storeRelaxed(reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId())));
}
- QCoreApplicationPrivate::theMainThread = threadData->thread.load();
+ QCoreApplicationPrivate::theMainThread = threadData->thread.loadRelaxed();
}
#endif
@@ -372,14 +372,14 @@ QAbstractEventDispatcher *QThreadPrivate::createEventDispatcher(QThreadData *dat
#if QT_CONFIG(thread)
-unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(void *arg) Q_DECL_NOEXCEPT
+unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(void *arg) noexcept
{
QThread *thr = reinterpret_cast<QThread *>(arg);
QThreadData *data = QThreadData::get2(thr);
qt_create_tls();
TlsSetValue(qt_current_thread_data_tls_index, data);
- data->threadId.store(reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId())));
+ data->threadId.storeRelaxed(reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId())));
QThread::setTerminationEnabled(false);
@@ -406,7 +406,7 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi
return 0;
}
-void QThreadPrivate::finish(void *arg, bool lockAnyway) Q_DECL_NOEXCEPT
+void QThreadPrivate::finish(void *arg, bool lockAnyway) noexcept
{
QThread *thr = reinterpret_cast<QThread *>(arg);
QThreadPrivate *d = thr->d_func();
@@ -421,7 +421,7 @@ void QThreadPrivate::finish(void *arg, bool lockAnyway) Q_DECL_NOEXCEPT
QThreadStorageData::finish(tls_data);
locker.relock();
- QAbstractEventDispatcher *eventDispatcher = d->data->eventDispatcher.load();
+ QAbstractEventDispatcher *eventDispatcher = d->data->eventDispatcher.loadRelaxed();
if (eventDispatcher) {
d->data->eventDispatcher = 0;
locker.unlock();
@@ -447,12 +447,12 @@ void QThreadPrivate::finish(void *arg, bool lockAnyway) Q_DECL_NOEXCEPT
** QThread
*************************************************************************/
-Qt::HANDLE QThread::currentThreadId() Q_DECL_NOTHROW
+Qt::HANDLE QThread::currentThreadId() noexcept
{
return reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId()));
}
-int QThread::idealThreadCount() Q_DECL_NOTHROW
+int QThread::idealThreadCount() noexcept
{
SYSTEM_INFO sysinfo;
#ifndef Q_OS_WINRT
diff --git a/src/corelib/thread/qthreadpool_p.h b/src/corelib/thread/qthreadpool_p.h
index 952e02ef20..01852d8366 100644
--- a/src/corelib/thread/qthreadpool_p.h
+++ b/src/corelib/thread/qthreadpool_p.h
@@ -162,7 +162,7 @@ public:
void tryToStartMoreThreads();
bool tooManyThreadsActive() const;
- void startThread(QRunnable *runnable = 0);
+ void startThread(QRunnable *runnable = nullptr);
void reset();
bool waitForDone(int msecs);
bool waitForDone(const QDeadlineTimer &timer);
diff --git a/src/corelib/thread/qthreadstorage.cpp b/src/corelib/thread/qthreadstorage.cpp
index 8b82118a5c..fdc484d2d2 100644
--- a/src/corelib/thread/qthreadstorage.cpp
+++ b/src/corelib/thread/qthreadstorage.cpp
@@ -126,7 +126,7 @@ void **QThreadStorageData::get() const
DEBUG_MSG("QThreadStorageData: Returning storage %d, data %p, for thread %p",
id,
*v,
- data->thread.load());
+ data->thread.loadRelaxed());
return *v ? v : 0;
}
@@ -148,7 +148,7 @@ void **QThreadStorageData::set(void *p)
DEBUG_MSG("QThreadStorageData: Deleting previous storage %d, data %p, for thread %p",
id,
value,
- data->thread.load());
+ data->thread.loadRelaxed());
QMutexLocker locker(&destructorsMutex);
DestructorMap *destr = destructors();
@@ -164,7 +164,7 @@ void **QThreadStorageData::set(void *p)
// store new data
value = p;
- DEBUG_MSG("QThreadStorageData: Set storage %d for thread %p to %p", id, data->thread.load(), p);
+ DEBUG_MSG("QThreadStorageData: Set storage %d for thread %p to %p", id, data->thread.loadRelaxed(), p);
return &value;
}
diff --git a/src/corelib/thread/qthreadstorage.h b/src/corelib/thread/qthreadstorage.h
index 55fc482da3..9eb8672e92 100644
--- a/src/corelib/thread/qthreadstorage.h
+++ b/src/corelib/thread/qthreadstorage.h
@@ -69,7 +69,7 @@ inline
T *&qThreadStorage_localData(QThreadStorageData &d, T **)
{
void **v = d.get();
- if (!v) v = d.set(0);
+ if (!v) v = d.set(nullptr);
return *(reinterpret_cast<T**>(v));
}
@@ -139,7 +139,7 @@ public:
inline ~QThreadStorage() { }
inline bool hasLocalData() const
- { return d.get() != 0; }
+ { return d.get() != nullptr; }
inline T& localData()
{ return qThreadStorage_localData(d, reinterpret_cast<T*>(0)); }
diff --git a/src/corelib/thread/qwaitcondition_unix.cpp b/src/corelib/thread/qwaitcondition_unix.cpp
index 0ba90763cf..dd7475cec5 100644
--- a/src/corelib/thread/qwaitcondition_unix.cpp
+++ b/src/corelib/thread/qwaitcondition_unix.cpp
@@ -72,7 +72,7 @@ __attribute__((weakref("__pthread_cond_timedwait_relative")));
static void report_error(int code, const char *where, const char *what)
{
if (code != 0)
- qWarning("%s: %s failure: %s", where, what, qPrintable(qt_error_string(code)));
+ qErrnoWarning(code, "%s: %s failure", where, what);
}
void qt_initialize_pthread_cond(pthread_cond_t *cond, const char *where)