summaryrefslogtreecommitdiff
path: root/src/corelib/thread/qthread_unix.cpp
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2019-08-19 13:33:31 +0200
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2019-10-20 17:08:57 +0200
commit5e9b2ade678f37e43bfc2e3484f54cbbb5844d2e (patch)
tree6415a35c0a3bb9a2ca0f3e62e126986fb30c83a6 /src/corelib/thread/qthread_unix.cpp
parentab5153aa0b09320dc5c96aa2b5a564ea1e6dbed3 (diff)
downloadqtbase-5e9b2ade678f37e43bfc2e3484f54cbbb5844d2e.tar.gz
Read a unique thread identifier from CPU registers
This is, depending on the implementation of pthread, significantly cheaper than using a pthread library call. Even if we don't know the assembler for an architecture, taking the address of the thread_local variable is still faster. As QThread::currentThreadId() is documented to be used internally and not meant for application code, we don't have to care about what exact value we return. Internally, we use it only to compare thread IDs for equality, which this implementation is sufficient for, even if a thread ID is re-used when one of the threads terminate and a new thread starts (since the other thread is still executing code). Besides, pthread_self documents [0] that a thread ID may be reused, and that the returned pthread_t cannot be portably compared using operator==(); using pthread_equal would require adding a Qt thread-ID type that implements this correctly, and would make things even slower. [0] http://man7.org/linux/man-pages/man3/pthread_self.3.html Change-Id: Id08e79b9b9c88976561f7cd36c66d43771fc4f24 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/thread/qthread_unix.cpp')
-rw-r--r--src/corelib/thread/qthread_unix.cpp28
1 files changed, 24 insertions, 4 deletions
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index cb3c0d6bb1..21abe372eb 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)