summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/thread')
-rw-r--r--src/corelib/thread/qfutureinterface.cpp7
-rw-r--r--src/corelib/thread/qfutureinterface.h13
-rw-r--r--src/corelib/thread/qrunnable.cpp1
-rw-r--r--src/corelib/thread/qthread.cpp2
-rw-r--r--src/corelib/thread/qthread.h33
-rw-r--r--src/corelib/thread/qthread_unix.cpp28
-rw-r--r--src/corelib/thread/qthread_win.cpp2
7 files changed, 66 insertions, 20 deletions
diff --git a/src/corelib/thread/qfutureinterface.cpp b/src/corelib/thread/qfutureinterface.cpp
index f1fd40e7b6..e6380a8732 100644
--- a/src/corelib/thread/qfutureinterface.cpp
+++ b/src/corelib/thread/qfutureinterface.cpp
@@ -424,12 +424,7 @@ void QFutureInterfaceBase::setProgressValueAndText(int progressValue,
}
}
-QMutex *QFutureInterfaceBase::mutex() const
-{
- return &d->m_mutex;
-}
-
-QMutex &QFutureInterfaceBase::mutex(int) const
+QMutex &QFutureInterfaceBase::mutex() const
{
return d->m_mutex;
}
diff --git a/src/corelib/thread/qfutureinterface.h b/src/corelib/thread/qfutureinterface.h
index bcdae24833..43dfd6bac4 100644
--- a/src/corelib/thread/qfutureinterface.h
+++ b/src/corelib/thread/qfutureinterface.h
@@ -119,8 +119,7 @@ public:
void waitForResult(int resultIndex);
void waitForResume();
- QMutex *mutex() const;
- QMutex &mutex(int) const;
+ QMutex &mutex() const;
QtPrivate::ExceptionStore &exceptionStore();
QtPrivate::ResultStoreBase &resultStoreBase();
const QtPrivate::ResultStoreBase &resultStoreBase() const;
@@ -191,7 +190,7 @@ public:
template <typename T>
inline void QFutureInterface<T>::reportResult(const T *result, int index)
{
- std::lock_guard<QMutex> locker(mutex(0));
+ std::lock_guard<QMutex> locker{mutex()};
if (this->queryState(Canceled) || this->queryState(Finished)) {
return;
}
@@ -217,7 +216,7 @@ inline void QFutureInterface<T>::reportResult(const T &result, int index)
template <typename T>
inline void QFutureInterface<T>::reportResults(const QVector<T> &_results, int beginIndex, int count)
{
- std::lock_guard<QMutex> locker(mutex(0));
+ std::lock_guard<QMutex> locker{mutex()};
if (this->queryState(Canceled) || this->queryState(Finished)) {
return;
}
@@ -245,14 +244,14 @@ inline void QFutureInterface<T>::reportFinished(const T *result)
template <typename T>
inline const T &QFutureInterface<T>::resultReference(int index) const
{
- std::lock_guard<QMutex> locker(mutex(0));
+ std::lock_guard<QMutex> locker{mutex()};
return resultStoreBase().resultAt(index).template value<T>();
}
template <typename T>
inline const T *QFutureInterface<T>::resultPointer(int index) const
{
- std::lock_guard<QMutex> locker(mutex(0));
+ std::lock_guard<QMutex> locker{mutex()};
return resultStoreBase().resultAt(index).template pointer<T>();
}
@@ -266,7 +265,7 @@ inline QList<T> QFutureInterface<T>::results()
QFutureInterfaceBase::waitForResult(-1);
QList<T> res;
- std::lock_guard<QMutex> locker(mutex(0));
+ std::lock_guard<QMutex> locker{mutex()};
QtPrivate::ResultIteratorBase it = resultStoreBase().begin();
while (it != resultStoreBase().end()) {
diff --git a/src/corelib/thread/qrunnable.cpp b/src/corelib/thread/qrunnable.cpp
index 58a764d407..5b883a05da 100644
--- a/src/corelib/thread/qrunnable.cpp
+++ b/src/corelib/thread/qrunnable.cpp
@@ -43,7 +43,6 @@ QT_BEGIN_NAMESPACE
QRunnable::~QRunnable()
{
- // Must be empty until ### Qt 6
}
/*!
diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp
index d18056063f..155bff1758 100644
--- a/src/corelib/thread/qthread.cpp
+++ b/src/corelib/thread/qthread.cpp
@@ -853,7 +853,7 @@ bool QThread::event(QEvent* event)
return QObject::event(event);
}
-Qt::HANDLE QThread::currentThreadId() noexcept
+Qt::HANDLE QThread::currentThreadIdImpl() noexcept
{
return Qt::HANDLE(currentThread());
}
diff --git a/src/corelib/thread/qthread.h b/src/corelib/thread/qthread.h
index 2072e22340..635dd94522 100644
--- a/src/corelib/thread/qthread.h
+++ b/src/corelib/thread/qthread.h
@@ -161,6 +161,7 @@ private:
#if QT_CONFIG(cxx11_future)
static QThread *createThreadImpl(std::future<void> &&future);
#endif
+ static Qt::HANDLE currentThreadIdImpl() noexcept Q_DECL_PURE_FUNCTION;
friend class QCoreApplication;
friend class QThreadData;
@@ -236,6 +237,38 @@ QThread *QThread::create(Function &&f)
#endif // QT_CONFIG(cxx11_future)
+/*
+ On architectures and platforms we know, interpret the thread control
+ block (TCB) as a unique identifier for a thread within a process. Otherwise,
+ fall back to a slower but safe implementation.
+
+ As per the documentation of currentThreadId, we return an opaque handle
+ as a thread identifier, and application code is not supposed to use that
+ value for anything. In Qt we use the handle to check if threads are identical,
+ for which the TCB is sufficient.
+
+ So we use the fastest possible way, rathern than spend time on returning
+ some pseudo-interoperable value.
+*/
+inline Qt::HANDLE QThread::currentThreadId() noexcept
+{
+ Qt::HANDLE tid; // typedef to void*
+ Q_STATIC_ASSERT(sizeof(tid) == sizeof(void*));
+ // See https://akkadia.org/drepper/tls.pdf for x86 ABI
+#if defined(Q_PROCESSOR_X86_32) && defined(Q_OS_LINUX) // x86 32-bit always uses GS
+ __asm__("movl %%gs:0, %0" : "=r" (tid) : : );
+#elif defined(Q_PROCESSOR_X86_64) && defined(Q_OS_DARWIN64)
+ // 64bit macOS uses GS, see https://github.com/apple/darwin-xnu/blob/master/libsyscall/os/tsd.h
+ __asm__("movq %%gs:0, %0" : "=r" (tid) : : );
+#elif defined(Q_PROCESSOR_X86_64) && (defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD))
+ // x86_64 Linux, BSD uses FS
+ __asm__("movq %%fs:0, %0" : "=r" (tid) : : );
+#else
+ tid = currentThreadIdImpl();
+#endif
+ return tid;
+}
+
QT_END_NAMESPACE
#endif // QTHREAD_H
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index 1da68b3130..727d72a334 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -415,16 +415,36 @@ void QThreadPrivate::finish(void *arg)
}
-
-
/**************************************************************************
** QThread
*************************************************************************/
-Qt::HANDLE QThread::currentThreadId() noexcept
+/*
+ Since each thread is guaranteed to have its own copy of
+ currenThreadData, the address is guaranteed to be unique for each
+ running thread (but likely to be reused for newly started threads).
+
+ CI tests fails on ARM architectures if we try to use the assembler,
+ or the address of the thread_local (even with a recent gcc version), so
+ stick to the pthread version there. The assembler would be
+
+ // http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0344k/Babeihid.html
+ asm volatile ("mrc p15, 0, %0, c13, c0, 3" : "=r" (tid));
+
+ and
+
+ // see glibc/sysdeps/aarch64/nptl/tls.h
+ asm volatile ("mrs %0, tpidr_el0" : "=r" (tid));
+
+ for 32 and 64bit versions, respectively.
+*/
+Qt::HANDLE QThread::currentThreadIdImpl() noexcept
{
- // requires a C cast here otherwise we run into trouble on AIX
+#if defined(Q_PROCESSOR_ARM)
return to_HANDLE(pthread_self());
+#else
+ return &currentThreadData;
+#endif
}
#if defined(QT_LINUXBASE) && !defined(_SC_NPROCESSORS_ONLN)
diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp
index bc70e3178a..00d67b3a00 100644
--- a/src/corelib/thread/qthread_win.cpp
+++ b/src/corelib/thread/qthread_win.cpp
@@ -449,7 +449,7 @@ void QThreadPrivate::finish(void *arg, bool lockAnyway) noexcept
** QThread
*************************************************************************/
-Qt::HANDLE QThread::currentThreadId() noexcept
+Qt::HANDLE QThread::currentThreadIdImpl() noexcept
{
return reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId()));
}