From 46d31f3bafcadccab3dff3a2ddf5912c6b5b0884 Mon Sep 17 00:00:00 2001 From: Pavel Borisov Date: Tue, 8 Nov 2022 16:01:46 +0400 Subject: [PATCH] atomic sub instead of CAS for shared lockers without queue --- src/backend/storage/lmgr/lwlock.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c index f5a149b4f42..c04ff48cabe 100644 --- a/src/backend/storage/lmgr/lwlock.c +++ b/src/backend/storage/lmgr/lwlock.c @@ -1781,26 +1781,35 @@ LWLockRelease(LWLock *lock) PRINT_LWDEBUG("LWLockRelease", lock, mode); + Assert (mode == LW_SHARED || mode == LW_EXCLUSIVE); /* * Release my hold on lock, after that it can immediately be acquired by * others, even if we still have to wakeup other waiters. */ oldState = pg_atomic_read_u64(&lock->state); + if (mode == LW_SHARED) + oldState = pg_atomic_sub_fetch_u64(&lock->state, + ((oldState & LW_FLAG_LOCK_VAR) == LW_FLAG_LOCK_VAR) ? + (LW_FLAG_LOCK_VAR | LW_VAL_SHARED) : LW_VAL_SHARED ); + while (true) { uint64 newState = oldState; if (mode == LW_EXCLUSIVE) + { newState -= LW_VAL_EXCLUSIVE; - else - newState -= LW_VAL_SHARED; + newState &= ~LW_FLAG_LOCK_VAR; + } if (LW_HAS_WAITERS(oldState) && - (newState & LW_LOCK_MASK) == 0 && - (newState & LW_FLAG_RELEASE_OK) == LW_FLAG_RELEASE_OK) + (newState & LW_LOCK_MASK) == 0 && + (newState & LW_FLAG_RELEASE_OK) == LW_FLAG_RELEASE_OK) newState |= LW_FLAG_WAKE_UP_LOCK; - newState &= ~LW_FLAG_LOCK_VAR; + + if (newState == oldState) + break; if (pg_atomic_compare_exchange_u64(&lock->state, &oldState, newState)) { -- 2.24.3 (Apple Git-128)