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
This commit is contained in:
Andres Freund 2015-07-31 20:50:35 +02:00
parent 27b7191735
commit 9074e41dbd

View File

@ -582,29 +582,33 @@ LWLockInitialize(LWLock *lock, int tranche_id)
static bool static bool
LWLockAttemptLock(LWLock *lock, LWLockMode mode) LWLockAttemptLock(LWLock *lock, LWLockMode mode)
{ {
uint32 old_state;
AssertArg(mode == LW_EXCLUSIVE || mode == LW_SHARED); 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 */ /* loop until we've determined whether we could acquire the lock or not */
while (true) while (true)
{ {
uint32 old_state;
uint32 expected_state;
uint32 desired_state; uint32 desired_state;
bool lock_free; bool lock_free;
old_state = pg_atomic_read_u32(&lock->state); desired_state = old_state;
expected_state = old_state;
desired_state = expected_state;
if (mode == LW_EXCLUSIVE) if (mode == LW_EXCLUSIVE)
{ {
lock_free = (expected_state & LW_LOCK_MASK) == 0; lock_free = (old_state & LW_LOCK_MASK) == 0;
if (lock_free) if (lock_free)
desired_state += LW_VAL_EXCLUSIVE; desired_state += LW_VAL_EXCLUSIVE;
} }
else else
{ {
lock_free = (expected_state & LW_VAL_EXCLUSIVE) == 0; lock_free = (old_state & LW_VAL_EXCLUSIVE) == 0;
if (lock_free) if (lock_free)
desired_state += LW_VAL_SHARED; 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. * Retry if the value changed since we last looked at it.
*/ */
if (pg_atomic_compare_exchange_u32(&lock->state, if (pg_atomic_compare_exchange_u32(&lock->state,
&expected_state, desired_state)) &old_state, desired_state))
{ {
if (lock_free) if (lock_free)
{ {