From 25f42429e2ff2acca35c9154fc2e36b75c79227a Mon Sep 17 00:00:00 2001 From: Alexander Korotkov Date: Sun, 7 Apr 2024 00:31:43 +0300 Subject: Use an LWLock instead of a spinlock in waitlsn.c This should prevent busy-waiting when number of waiting processes is high. Discussion: https://postgr.es/m/202404030658.hhj3vfxeyhft%40alvherre.pgsql Author: Alvaro Herrera --- src/backend/commands/waitlsn.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'src/backend/commands/waitlsn.c') diff --git a/src/backend/commands/waitlsn.c b/src/backend/commands/waitlsn.c index 51a34d422e2..a57b818a2d4 100644 --- a/src/backend/commands/waitlsn.c +++ b/src/backend/commands/waitlsn.c @@ -58,7 +58,6 @@ WaitLSNShmemInit(void) &found); if (!found) { - SpinLockInit(&waitLSN->waitersHeapMutex); pg_atomic_init_u64(&waitLSN->minWaitedLSN, PG_UINT64_MAX); pairingheap_initialize(&waitLSN->waitersHeap, lsn_cmp, NULL); memset(&waitLSN->procInfos, 0, MaxBackends * sizeof(WaitLSNProcInfo)); @@ -115,13 +114,13 @@ addLSNWaiter(XLogRecPtr lsn) procInfo->procnum = MyProcNumber; procInfo->waitLSN = lsn; - SpinLockAcquire(&waitLSN->waitersHeapMutex); + LWLockAcquire(WaitLSNLock, LW_EXCLUSIVE); pairingheap_add(&waitLSN->waitersHeap, &procInfo->phNode); procInfo->inHeap = true; updateMinWaitedLSN(); - SpinLockRelease(&waitLSN->waitersHeapMutex); + LWLockRelease(WaitLSNLock); } /* @@ -132,11 +131,11 @@ deleteLSNWaiter(void) { WaitLSNProcInfo *procInfo = &waitLSN->procInfos[MyProcNumber]; - SpinLockAcquire(&waitLSN->waitersHeapMutex); + LWLockAcquire(WaitLSNLock, LW_EXCLUSIVE); if (!procInfo->inHeap) { - SpinLockRelease(&waitLSN->waitersHeapMutex); + LWLockRelease(WaitLSNLock); return; } @@ -144,7 +143,7 @@ deleteLSNWaiter(void) procInfo->inHeap = false; updateMinWaitedLSN(); - SpinLockRelease(&waitLSN->waitersHeapMutex); + LWLockRelease(WaitLSNLock); } /* @@ -160,7 +159,7 @@ WaitLSNSetLatches(XLogRecPtr currentLSN) wakeUpProcNums = palloc(sizeof(int) * MaxBackends); - SpinLockAcquire(&waitLSN->waitersHeapMutex); + LWLockAcquire(WaitLSNLock, LW_EXCLUSIVE); /* * Iterate the pairing heap of waiting processes till we find LSN not yet @@ -182,7 +181,7 @@ WaitLSNSetLatches(XLogRecPtr currentLSN) updateMinWaitedLSN(); - SpinLockRelease(&waitLSN->waitersHeapMutex); + LWLockRelease(WaitLSNLock); /* * Set latches for processes, whose waited LSNs are already replayed. This -- cgit v1.2.3