summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2023-07-07 11:16:00 -0700
committerThiago Macieira <thiago.macieira@intel.com>2023-07-24 20:24:36 +0000
commit4a43149d7b1ba10a96826a2bb38f1d5d608b6cb0 (patch)
tree1061ae9b9085e241a925c2ac9df12052548ebbdb
parent41f41393067080223422122b8ae1a0dcfe9e5f8f (diff)
QThreadPipe & QEvent: use a simpler atomic operation
This causes modern compilers (i.e., not MSVC) to emit a single bit-test-and-set instruction instead of a cmpxchg. It's still an atomic operation, so it's not that much faster (if at all), but it has simpler encoding. Previous: 000000000026bca0 <QEventDispatcherUNIX::wakeUp()>: 26bca0: mov 0x8(%rdi),%rdx 26bca4: xor %eax,%eax 26bca6: mov $0x1,%ecx 26bcab: lock cmpxchg %ecx,0x98(%rdx) 26bcb3: jne 26bcc5 <QEventDispatcherUNIX::wakeUp()+0x25> 26bcb5: mov 0x90(%rdx),%edi 26bcbb: mov $0x1,%esi 26bcc0: jmp c01d0 <eventfd_write@plt> 26bcc5: ret Now: 26b3a0: mov 0x8(%rdi),%rax 26b3a4: lock btsl $0x0,0x98(%rax) 26b3ad: jae 26b3b0 <QEventDispatcherUNIX::wakeUp()+0x10> 26b3af: ret 26b3b0: mov 0x90(%rax),%edi 26b3b6: mov $0x1,%esi 26b3bb: jmp c11d0 <eventfd_write@plt> Change-Id: I53335f845a1345299031fffd176fa8ac1de3ad13 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
-rw-r--r--src/corelib/kernel/qcoreevent.cpp5
-rw-r--r--src/corelib/kernel/qeventdispatcher_unix.cpp2
2 files changed, 4 insertions, 3 deletions
diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp
index 46398872f7..838c90fce7 100644
--- a/src/corelib/kernel/qcoreevent.cpp
+++ b/src/corelib/kernel/qcoreevent.cpp
@@ -433,8 +433,9 @@ struct QBasicAtomicBitField {
QBasicAtomicInteger<uint> &entry = data[which / BitsPerInt];
const uint old = entry.loadRelaxed();
const uint bit = 1U << (which % BitsPerInt);
- return !(old & bit) // wasn't taken
- && entry.testAndSetRelaxed(old, old | bit); // still wasn't taken
+ if (old & bit)
+ return false; // already taken
+ return (entry.fetchAndOrRelaxed(bit) & bit) == 0;
// don't update 'next' here - it's unlikely that it will need
// to be updated, in the general case, and having 'next'
diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp
index dc87a9cd63..12603d77f0 100644
--- a/src/corelib/kernel/qeventdispatcher_unix.cpp
+++ b/src/corelib/kernel/qeventdispatcher_unix.cpp
@@ -123,7 +123,7 @@ pollfd QThreadPipe::prepare() const
void QThreadPipe::wakeUp()
{
- if (wakeUps.testAndSetAcquire(0, 1)) {
+ if ((wakeUps.fetchAndOrAcquire(1) & 1) == 0) {
#if QT_CONFIG(eventfd)
eventfd_write(fds[0], 1);
return;