diff options
author | Andres Freund <andres@anarazel.de> | 2015-07-31 20:50:35 +0200 |
---|---|---|
committer | Andres Freund <andres@anarazel.de> | 2015-08-02 18:41:23 +0200 |
commit | a4b09af3e93707351f1d4b8efafabfa135c0f70b (patch) | |
tree | 0ea29a8ec25a8d036f4a376932d5c9ed004dcfa7 /src | |
parent | 7039760114da45552043f8fa229928e071650173 (diff) | |
download | postgresql-a4b09af3e93707351f1d4b8efafabfa135c0f70b.tar.gz postgresql-a4b09af3e93707351f1d4b8efafabfa135c0f70b.zip |
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
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/storage/lmgr/lwlock.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c index ae03eb14196..687ed6399cb 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) { |