From 916b4d521b439135fb43424b96978332912fc85d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 17 Apr 2023 16:14:37 -0700 Subject: [PATCH] QReadWriteLock: force the loop to exist in a separate function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows the fast, uncontended case to exist in a function that does much less work and therefore needs to save less state in its prologue. This is interesting too for LTO because the compiler can then inline the fast, uncontended path where the locks were used. Change-Id: I3d728c4197df49169066fffd1756dc04d8a5f04a Reviewed-by: MÃ¥rten Nordheim (cherry picked from commit 834c755977bbfe66e041aba6d2dfa69954eb3808) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/thread/qreadwritelock.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/corelib/thread/qreadwritelock.cpp b/src/corelib/thread/qreadwritelock.cpp index f28b3fb8a30..12a9b3735b5 100644 --- a/src/corelib/thread/qreadwritelock.cpp +++ b/src/corelib/thread/qreadwritelock.cpp @@ -39,6 +39,11 @@ inline bool isUncontendedLocked(const QReadWriteLockPrivate *d) { return quintptr(d) & StateMask; } } +static bool contendedTryLockForRead(QAtomicPointer &d_ptr, + int timeout, QReadWriteLockPrivate *d); +static bool contendedTryLockForWrite(QAtomicPointer &d_ptr, + int timeout, QReadWriteLockPrivate *d); + /*! \class QReadWriteLock \inmodule QtCore \brief The QReadWriteLock class provides read-write locking. @@ -137,8 +142,6 @@ QReadWriteLock::~QReadWriteLock() */ void QReadWriteLock::lockForRead() { - if (d_ptr.testAndSetAcquire(nullptr, dummyLockedForRead)) - return; tryLockForRead(-1); } @@ -188,7 +191,12 @@ bool QReadWriteLock::tryLockForRead(int timeout) QReadWriteLockPrivate *d; if (d_ptr.testAndSetAcquire(nullptr, dummyLockedForRead, d)) return true; + return contendedTryLockForRead(d_ptr, timeout, d); +} +Q_NEVER_INLINE static bool contendedTryLockForRead(QAtomicPointer &d_ptr, + int timeout, QReadWriteLockPrivate *d) +{ while (true) { if (d == nullptr) { if (!d_ptr.testAndSetAcquire(nullptr, dummyLockedForRead, d)) @@ -302,7 +310,12 @@ bool QReadWriteLock::tryLockForWrite(int timeout) QReadWriteLockPrivate *d; if (d_ptr.testAndSetAcquire(nullptr, dummyLockedForWrite, d)) return true; + return contendedTryLockForWrite(d_ptr, timeout, d); +} +Q_NEVER_INLINE static bool contendedTryLockForWrite(QAtomicPointer &d_ptr, + int timeout, QReadWriteLockPrivate *d) +{ while (true) { if (d == nullptr) { if (!d_ptr.testAndSetAcquire(d, dummyLockedForWrite, d))