commit 975d33e1ed4d529b9f20a6b1f631cabd836d61bc Author: Alexander Korotkov Date: Sat Nov 28 12:29:57 2020 +0300 ARM lwlock implementation v2 diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c index 108e6521796..0a1ade6d94d 100644 --- a/src/backend/storage/lmgr/lwlock.c +++ b/src/backend/storage/lmgr/lwlock.c @@ -812,6 +812,64 @@ GetLWLockIdentifier(uint32 classId, uint16 eventId) return GetLWTrancheName(eventId); } +#if defined(__arm__) || defined(__arm) || defined(__aarch64__) || defined(__aarch64) + +static bool +LWLockAttemptExclusiveLock(LWLock *lock) +{ + uint32 state, old_state; + + do + { + old_state = state = (uint32) __builtin_arm_ldrex((volatile uint32 *) &lock->state.value); + if ((state & LW_LOCK_MASK) == 0) + state += LW_VAL_EXCLUSIVE; + } while (__builtin_arm_strex(state, (volatile uint32 *) &lock->state.value)); + + return ((old_state & LW_LOCK_MASK) != 0); +} + +static bool +LWLockAttemptSharedLock(LWLock *lock) +{ + uint32 old_state, state; + + do + { + old_state = state = (uint32) __builtin_arm_ldrex((volatile uint32 *) &lock->state.value); + if ((state & LW_VAL_EXCLUSIVE) == 0) + state += LW_VAL_SHARED; + } while (__builtin_arm_strex(state, (volatile uint32 *) &lock->state.value)); + + return ((old_state & LW_VAL_EXCLUSIVE) != 0); +} + +static bool +LWLockAttemptLock(LWLock *lock, LWLockMode mode) +{ + bool result; + + AssertArg(mode == LW_EXCLUSIVE || mode == LW_SHARED); + + if (mode == LW_EXCLUSIVE) + result = LWLockAttemptExclusiveLock(lock); + else + result = LWLockAttemptSharedLock(lock); + +#ifdef LOCK_DEBUG + if (!result) + { + /* Great! Got the lock. */ + if (mode == LW_EXCLUSIVE) + lock->owner = MyProc; + } +#endif + + return result; +} + +#else + /* * Internal function that tries to atomically acquire the lwlock in the passed * in mode. @@ -884,6 +942,8 @@ LWLockAttemptLock(LWLock *lock, LWLockMode mode) pg_unreachable(); } +#endif + /* * Lock the LWLock's wait list against concurrent activity. *