From da12409874b985042d78d35bd9dea31a2c03ae95 Mon Sep 17 00:00:00 2001 From: alterego655 <824662526@qq.com> Date: Tue, 1 Sep 2026 20:32:32 +0800 Subject: [PATCH v9 2/2] Use RegisterPinCountWaiter() in LockBufferForCleanup() Replace the duplicated pincount-waiter registration logic in LockBufferForCleanup() with a call to RegisterPinCountWaiter(), which already encapsulates the same protocol for publishing BM_PIN_COUNT_WAITER, rechecking the refcount, and returning false when only our own pin remains. --- src/backend/storage/buffer/bufmgr.c | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index c96ceb1513a..a2c922620ae 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -6842,34 +6842,14 @@ LockBufferForCleanup(Buffer buffer) LockBuffer(buffer, BUFFER_LOCK_UNLOCK); elog(ERROR, "multiple backends attempting to wait for pincount 1"); } - bufHdr->wait_backend_pgprocno = MyProcNumber; - PinCountWaitBuf = bufHdr; - - /* - * Publish BM_PIN_COUNT_WAITER while retaining the buffer header lock. - * The shared refcount can be decremented while BM_LOCKED is set, so - * use an atomic operation that preserves concurrent refcount changes. - */ - pg_atomic_fetch_or_u64(&bufHdr->state, BM_PIN_COUNT_WAITER); - /* - * Recheck the refcount after publishing the waiter flag, while shared - * refcount increments are still prevented by BM_LOCKED. If only our - * pin remains, the cleanup-lock condition has already been satisfied, - * so remove the waiter state and return without sleeping. + * Register ourselves as the pincount waiter. If the shared refcount + * was concurrently reduced to 1 (only our own pin remains), + * RegisterPinCountWaiter() returns false and no wait is necessary. */ - buf_state = pg_atomic_read_u64(&bufHdr->state); - - if (BUF_STATE_GET_REFCOUNT(buf_state) == 1) - { - UnlockBufHdrExt(bufHdr, buf_state, - 0, BM_PIN_COUNT_WAITER, - 0); - PinCountWaitBuf = NULL; + if (!RegisterPinCountWaiter(bufHdr, buf_state)) goto cleanup_lock_acquired; - } - UnlockBufHdr(bufHdr); LockBuffer(buffer, BUFFER_LOCK_UNLOCK); /* Wait to be signaled by UnpinBuffer() */ -- 2.51.0