Micro optimize LWLockAttemptLock() a bit.
authorAndres Freund
Fri, 31 Jul 2015 18:50:35 +0000 (20:50 +0200)
committerAndres Freund
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)
            {