]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Micro optimize LWLockAttemptLock() a bit.
authorAndres Freund <andres@anarazel.de>
Fri, 31 Jul 2015 18:50:35 +0000 (20:50 +0200)
committerAndres Freund <andres@anarazel.de>
Sun, 2 Aug 2015 16:41:23 +0000 (18:41 +0200)
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

index ae03eb14196c80fec7a0d042da94726a4a2e2b65..687ed6399cb19ed3183bb75a0214b57229e05675 100644 (file)
@@ -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)
                        {