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>
This commit is contained in:
parent
41f4139306
commit
4a43149d7b
@ -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'
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user