v16-0007-Add-UnlockBufferGetLSN-utility-function.patch
application/octet-stream
Filename: v16-0007-Add-UnlockBufferGetLSN-utility-function.patch
Type: application/octet-stream
Part: 14
Message:
Re: index prefetching
Patch
Format: format-patch
Series: patch v16-0007
Subject: Add UnlockBufferGetLSN utility function.
| File | + | − |
|---|---|---|
| src/backend/access/index/indexbatch.c | 1 | 11 |
| src/backend/storage/buffer/bufmgr.c | 47 | 0 |
| src/include/storage/bufmgr.h | 1 | 0 |
From 7e78a9867214dd2a6134972476de265688355659 Mon Sep 17 00:00:00 2001
From: Peter Geoghegan <pg@bowt.ie>
Date: Tue, 17 Mar 2026 13:25:12 -0400
Subject: [PATCH v16 07/17] Add UnlockBufferGetLSN utility function.
This combines the functionality of BufferGetLSNAtomic() with
UnlockReleaseBuffer, with the option of not releasing buffer pin.
---
src/include/storage/bufmgr.h | 1 +
src/backend/access/index/indexbatch.c | 12 +------
src/backend/storage/buffer/bufmgr.c | 47 +++++++++++++++++++++++++++
3 files changed, 49 insertions(+), 11 deletions(-)
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index 4017896f9..408d76c56 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -253,6 +253,7 @@ extern void WaitReadBuffers(ReadBuffersOperation *operation);
extern void ReleaseBuffer(Buffer buffer);
extern void UnlockReleaseBuffer(Buffer buffer);
+extern XLogRecPtr UnlockBufferGetLSN(Buffer buffer, bool release);
extern bool BufferIsLockedByMe(Buffer buffer);
extern bool BufferIsLockedByMeInMode(Buffer buffer, BufferLockMode mode);
extern bool BufferIsDirty(Buffer buffer);
diff --git a/src/backend/access/index/indexbatch.c b/src/backend/access/index/indexbatch.c
index 007fd03dd..40c89a40c 100644
--- a/src/backend/access/index/indexbatch.c
+++ b/src/backend/access/index/indexbatch.c
@@ -562,17 +562,7 @@ indexam_util_batch_unlock(IndexScanDesc scan, IndexScanBatch batch, Buffer buf)
* Non-immediate-unguard scans retain the pin; the table AM will call
* amunguardbatch to drop the interlock when ready.
*/
- batch->lsn = BufferGetLSNAtomic(buf);
- if (scan->batchImmediateUnguard)
- {
- /* drop both the lock and the pin */
- UnlockReleaseBuffer(buf);
- }
- else
- {
- /* just drop the lock (hold on to interlock pin) */
- UnlockBuffer(buf);
- }
+ batch->lsn = UnlockBufferGetLSN(buf, scan->batchImmediateUnguard);
}
else
{
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index 00bc60952..2a95517a3 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -5525,6 +5525,53 @@ UnlockReleaseBuffer(Buffer buffer)
ReleaseBuffer(buffer);
}
+/*
+ * UnlockBufferGetLSN
+ * Read a buffer's LSN, then unlock the buffer. Optionally release the
+ * pin too.
+ *
+ * This combines the functionality of BufferGetLSNAtomic() with
+ * UnlockReleaseBuffer, with the option of not releasing buffer pin.
+ *
+ * Used to unlock a buffer lock (and possibly to release its pin) when held on
+ * an index page. This is needed frequently enough to justify specialization.
+ */
+XLogRecPtr
+UnlockBufferGetLSN(Buffer buffer, bool release)
+{
+ BufferDesc *buf_hdr;
+ Page page;
+ XLogRecPtr lsn;
+
+ Assert(BufferIsValid(buffer));
+ Assert(BufferIsPinned(buffer));
+
+ if (BufferIsLocal(buffer))
+ {
+ buf_hdr = GetLocalBufferDescriptor(-buffer - 1);
+ page = (Page) LocalBufHdrGetBlock(buf_hdr);
+ lsn = PageGetLSN(page);
+ if (release)
+ UnpinLocalBuffer(buffer);
+ return lsn;
+ }
+
+ buf_hdr = GetBufferDescriptor(buffer - 1);
+ page = (Page) BufHdrGetBlock(buf_hdr);
+
+#ifdef PG_HAVE_8BYTE_SINGLE_COPY_ATOMICITY
+ lsn = PageGetLSN(page);
+#else
+ lsn = BufferGetLSNAtomic(buffer);
+#endif
+
+ BufferLockUnlock(buffer, buf_hdr);
+ if (release)
+ UnpinBuffer(buf_hdr);
+
+ return lsn;
+}
+
/*
* IncrBufferRefCount
* Increment the pin count on a buffer that we have *already* pinned
--
2.53.0