From 9074e41dbd41bc45ef79aeac1b6496bf087509a7 Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Fri, 31 Jul 2015 20:50:35 +0200 Subject: [PATCH] Micro optimize LWLockAttemptLock() a bit. LWLockAttemptLock pointlessly read the lock's state in every loop iteration, even though pg_atomic_compare_exchange_u32() returns the old value. Instead do that only once before the loop iteration. Additionally there's no need to have the expected_state variable, old_state mostly had the same value anyway. Noticed-By: Heikki Linnakangas Backpatch: 9.5, no reason to let the branches diverge at this point --- src/backend/storage/lmgr/lwlock.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c index ae03eb1419..687ed6399c 100644 --- a/src/backend/storage/lmgr/lwlock.c +++ b/src/backend/storage/lmgr/lwlock.c @@ -582,29 +582,33 @@ LWLockInitialize(LWLock *lock, int tranche_id) static bool LWLockAttemptLock(LWLock *lock, LWLockMode mode) { + uint32 old_state; + AssertArg(mode == LW_EXCLUSIVE || mode == LW_SHARED); + /* + * Read once outside the loop, later iterations will get the newer value + * via compare & exchange. + */ + old_state = pg_atomic_read_u32(&lock->state); + /* loop until we've determined whether we could acquire the lock or not */ while (true) { - uint32 old_state; - uint32 expected_state; uint32 desired_state; bool lock_free; - old_state = pg_atomic_read_u32(&lock->state); - expected_state = old_state; - desired_state = expected_state; + desired_state = old_state; if (mode == LW_EXCLUSIVE) { - lock_free = (expected_state & LW_LOCK_MASK) == 0; + lock_free = (old_state & LW_LOCK_MASK) == 0; if (lock_free) desired_state += LW_VAL_EXCLUSIVE; } else { - lock_free = (expected_state & LW_VAL_EXCLUSIVE) == 0; + lock_free = (old_state & LW_VAL_EXCLUSIVE) == 0; if (lock_free) desired_state += LW_VAL_SHARED; } @@ -620,7 +624,7 @@ LWLockAttemptLock(LWLock *lock, LWLockMode mode) * Retry if the value changed since we last looked at it. */ if (pg_atomic_compare_exchange_u32(&lock->state, - &expected_state, desired_state)) + &old_state, desired_state)) { if (lock_free) {