v-18-0003-Pack-SLRU-page_number-page_status-and-page_dirt.patch
text/x-diff
Filename: v-18-0003-Pack-SLRU-page_number-page_status-and-page_dirt.patch
Type: text/x-diff
Part: 1
Patch
Format: format-patch
Series: patch 0003
Subject: Pack SLRU page_number, page_status and page_dirty toogether
| File | + | − |
|---|---|---|
| src/backend/access/transam/clog.c | 6 | 6 |
| src/backend/access/transam/commit_ts.c | 3 | 3 |
| src/backend/access/transam/multixact.c | 8 | 8 |
| src/backend/access/transam/slru.c | 69 | 74 |
| src/backend/access/transam/subtrans.c | 2 | 2 |
| src/backend/commands/async.c | 1 | 1 |
| src/backend/storage/lmgr/predicate.c | 1 | 1 |
| src/include/access/slru.h | 9 | 4 |
From 5c1aace8b1f5a2b852bf1476dffbd4a43f196ef3 Mon Sep 17 00:00:00 2001
From: Andrey Borodin <x4m@flight.local>
Date: Sun, 26 Dec 2021 15:03:30 +0500
Subject: [PATCH v=18 3/3] Pack SLRU page_number, page_status and page_dirty
toogether
This allows to test only one cacheline during successfull
SlruSelectLRUPage().
---
src/backend/access/transam/clog.c | 12 +--
src/backend/access/transam/commit_ts.c | 6 +-
src/backend/access/transam/multixact.c | 16 +--
src/backend/access/transam/slru.c | 143 ++++++++++++-------------
src/backend/access/transam/subtrans.c | 4 +-
src/backend/commands/async.c | 2 +-
src/backend/storage/lmgr/predicate.c | 2 +-
src/include/access/slru.h | 13 ++-
8 files changed, 99 insertions(+), 99 deletions(-)
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index ca28ada75fa..7d3a0286a5f 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -375,7 +375,7 @@ TransactionIdSetPageStatusInternal(TransactionId xid, int nsubxids,
{
for (i = 0; i < nsubxids; i++)
{
- Assert(XactCtl->shared->page_number[slotno] == TransactionIdToPage(subxids[i]));
+ Assert(XactCtl->shared->page_entries[slotno].page_number == TransactionIdToPage(subxids[i]));
TransactionIdSetStatusBit(subxids[i],
TRANSACTION_STATUS_SUB_COMMITTED,
lsn, slotno);
@@ -389,11 +389,11 @@ TransactionIdSetPageStatusInternal(TransactionId xid, int nsubxids,
/* Set the subtransactions */
for (i = 0; i < nsubxids; i++)
{
- Assert(XactCtl->shared->page_number[slotno] == TransactionIdToPage(subxids[i]));
+ Assert(XactCtl->shared->page_entries[slotno].page_number == TransactionIdToPage(subxids[i]));
TransactionIdSetStatusBit(subxids[i], status, lsn, slotno);
}
- XactCtl->shared->page_dirty[slotno] = true;
+ XactCtl->shared->page_entries[slotno].page_dirty = true;
}
/*
@@ -713,7 +713,7 @@ BootStrapCLOG(void)
/* Make sure it's written out */
SimpleLruWritePage(XactCtl, slotno);
- Assert(!XactCtl->shared->page_dirty[slotno]);
+ Assert(!XactCtl->shared->page_entries[slotno].page_dirty);
LWLockRelease(XactSLRULock);
}
@@ -798,7 +798,7 @@ TrimCLOG(void)
/* Zero the rest of the page */
MemSet(byteptr + 1, 0, BLCKSZ - byteno - 1);
- XactCtl->shared->page_dirty[slotno] = true;
+ XactCtl->shared->page_entries[slotno].page_dirty = true;
}
LWLockRelease(XactSLRULock);
@@ -994,7 +994,7 @@ clog_redo(XLogReaderState *record)
slotno = ZeroCLOGPage(pageno, false);
SimpleLruWritePage(XactCtl, slotno);
- Assert(!XactCtl->shared->page_dirty[slotno]);
+ Assert(!XactCtl->shared->page_entries[slotno].page_dirty);
LWLockRelease(XactSLRULock);
}
diff --git a/src/backend/access/transam/commit_ts.c b/src/backend/access/transam/commit_ts.c
index cb2e0ceb1c3..6879ef3ec71 100644
--- a/src/backend/access/transam/commit_ts.c
+++ b/src/backend/access/transam/commit_ts.c
@@ -227,7 +227,7 @@ SetXidCommitTsInPage(TransactionId xid, int nsubxids,
for (i = 0; i < nsubxids; i++)
TransactionIdSetCommitTs(subxids[i], ts, nodeid, slotno);
- CommitTsCtl->shared->page_dirty[slotno] = true;
+ CommitTsCtl->shared->page_entries[slotno].page_dirty = true;
LWLockRelease(CommitTsSLRULock);
}
@@ -735,7 +735,7 @@ ActivateCommitTs(void)
LWLockAcquire(CommitTsSLRULock, LW_EXCLUSIVE);
slotno = ZeroCommitTsPage(pageno, false);
SimpleLruWritePage(CommitTsCtl, slotno);
- Assert(!CommitTsCtl->shared->page_dirty[slotno]);
+ Assert(!CommitTsCtl->shared->page_entries[slotno].page_dirty);
LWLockRelease(CommitTsSLRULock);
}
@@ -1005,7 +1005,7 @@ commit_ts_redo(XLogReaderState *record)
slotno = ZeroCommitTsPage(pageno, false);
SimpleLruWritePage(CommitTsCtl, slotno);
- Assert(!CommitTsCtl->shared->page_dirty[slotno]);
+ Assert(!CommitTsCtl->shared->page_entries[slotno].page_dirty);
LWLockRelease(CommitTsSLRULock);
}
diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c
index a29ab4769dc..eb32821b717 100644
--- a/src/backend/access/transam/multixact.c
+++ b/src/backend/access/transam/multixact.c
@@ -887,7 +887,7 @@ RecordNewMultiXact(MultiXactId multi, MultiXactOffset offset,
*offptr = offset;
- MultiXactOffsetCtl->shared->page_dirty[slotno] = true;
+ MultiXactOffsetCtl->shared->page_entries[slotno].page_dirty = true;
/* Exchange our lock */
LWLockRelease(MultiXactOffsetSLRULock);
@@ -931,7 +931,7 @@ RecordNewMultiXact(MultiXactId multi, MultiXactOffset offset,
flagsval |= (members[i].status << bshift);
*flagsptr = flagsval;
- MultiXactMemberCtl->shared->page_dirty[slotno] = true;
+ MultiXactMemberCtl->shared->page_entries[slotno].page_dirty = true;
}
LWLockRelease(MultiXactMemberSLRULock);
@@ -1902,7 +1902,7 @@ BootStrapMultiXact(void)
/* Make sure it's written out */
SimpleLruWritePage(MultiXactOffsetCtl, slotno);
- Assert(!MultiXactOffsetCtl->shared->page_dirty[slotno]);
+ Assert(!MultiXactOffsetCtl->shared->page_entries[slotno].page_dirty);
LWLockRelease(MultiXactOffsetSLRULock);
@@ -1913,7 +1913,7 @@ BootStrapMultiXact(void)
/* Make sure it's written out */
SimpleLruWritePage(MultiXactMemberCtl, slotno);
- Assert(!MultiXactMemberCtl->shared->page_dirty[slotno]);
+ Assert(!MultiXactMemberCtl->shared->page_entries[slotno].page_dirty);
LWLockRelease(MultiXactMemberSLRULock);
}
@@ -2074,7 +2074,7 @@ TrimMultiXact(void)
MemSet(offptr, 0, BLCKSZ - (entryno * sizeof(MultiXactOffset)));
- MultiXactOffsetCtl->shared->page_dirty[slotno] = true;
+ MultiXactOffsetCtl->shared->page_entries[slotno].page_dirty = true;
}
LWLockRelease(MultiXactOffsetSLRULock);
@@ -2112,7 +2112,7 @@ TrimMultiXact(void)
* writing.
*/
- MultiXactMemberCtl->shared->page_dirty[slotno] = true;
+ MultiXactMemberCtl->shared->page_entries[slotno].page_dirty = true;
}
LWLockRelease(MultiXactMemberSLRULock);
@@ -3251,7 +3251,7 @@ multixact_redo(XLogReaderState *record)
slotno = ZeroMultiXactOffsetPage(pageno, false);
SimpleLruWritePage(MultiXactOffsetCtl, slotno);
- Assert(!MultiXactOffsetCtl->shared->page_dirty[slotno]);
+ Assert(!MultiXactOffsetCtl->shared->page_entries[slotno].page_dirty);
LWLockRelease(MultiXactOffsetSLRULock);
}
@@ -3266,7 +3266,7 @@ multixact_redo(XLogReaderState *record)
slotno = ZeroMultiXactMemberPage(pageno, false);
SimpleLruWritePage(MultiXactMemberCtl, slotno);
- Assert(!MultiXactMemberCtl->shared->page_dirty[slotno]);
+ Assert(!MultiXactMemberCtl->shared->page_entries[slotno].page_dirty);
LWLockRelease(MultiXactMemberSLRULock);
}
diff --git a/src/backend/access/transam/slru.c b/src/backend/access/transam/slru.c
index 33857bffb79..1f87e50f05c 100644
--- a/src/backend/access/transam/slru.c
+++ b/src/backend/access/transam/slru.c
@@ -186,9 +186,7 @@ SimpleLruShmemSize(int nslots, int nlsns)
/* we assume nslots isn't so large as to risk overflow */
sz = MAXALIGN(sizeof(SlruSharedData));
sz += MAXALIGN(nslots * sizeof(char *)); /* page_buffer[] */
- sz += MAXALIGN(nslots * sizeof(SlruPageStatus)); /* page_status[] */
- sz += MAXALIGN(nslots * sizeof(bool)); /* page_dirty[] */
- sz += MAXALIGN(nslots * sizeof(int)); /* page_number[] */
+ sz += MAXALIGN(nslots * sizeof(SlruPageEntry)); /* page_entries[] */
sz += MAXALIGN(nslots * sizeof(int)); /* page_lru_count[] */
sz += MAXALIGN(nslots * sizeof(LWLockPadded)); /* buffer_locks[] */
@@ -248,16 +246,13 @@ SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns,
shared->slru_stats_idx = pgstat_slru_index(name);
+ Assert(sizeof(SlruPageEntry) == 8);
ptr = (char *) shared;
offset = MAXALIGN(sizeof(SlruSharedData));
shared->page_buffer = (char **) (ptr + offset);
offset += MAXALIGN(nslots * sizeof(char *));
- shared->page_status = (SlruPageStatus *) (ptr + offset);
- offset += MAXALIGN(nslots * sizeof(SlruPageStatus));
- shared->page_dirty = (bool *) (ptr + offset);
- offset += MAXALIGN(nslots * sizeof(bool));
- shared->page_number = (int *) (ptr + offset);
- offset += MAXALIGN(nslots * sizeof(int));
+ shared->page_entries = (SlruPageEntry *) (ptr + offset);
+ offset += MAXALIGN(nslots * sizeof(SlruPageEntry));
shared->page_lru_count = (int *) (ptr + offset);
offset += MAXALIGN(nslots * sizeof(int));
@@ -278,8 +273,8 @@ SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns,
tranche_id);
shared->page_buffer[slotno] = ptr;
- shared->page_status[slotno] = SLRU_PAGE_EMPTY;
- shared->page_dirty[slotno] = false;
+ shared->page_entries[slotno].page_status = SLRU_PAGE_EMPTY;
+ shared->page_entries[slotno].page_dirty = false;
shared->page_lru_count[slotno] = 0;
ptr += BLCKSZ;
}
@@ -315,15 +310,15 @@ SimpleLruZeroPage(SlruCtl ctl, int pageno)
/* Find a suitable buffer slot for the page */
slotno = SlruSelectLRUPage(ctl, pageno);
- Assert(shared->page_status[slotno] == SLRU_PAGE_EMPTY ||
- (shared->page_status[slotno] == SLRU_PAGE_VALID &&
- !shared->page_dirty[slotno]) ||
- shared->page_number[slotno] == pageno);
+ Assert(shared->page_entries[slotno].page_status == SLRU_PAGE_EMPTY ||
+ (shared->page_entries[slotno].page_status == SLRU_PAGE_VALID &&
+ !shared->page_entries[slotno].page_dirty) ||
+ shared->page_entries[slotno].page_number == pageno);
/* Mark the slot as containing this page */
- shared->page_number[slotno] = pageno;
- shared->page_status[slotno] = SLRU_PAGE_VALID;
- shared->page_dirty[slotno] = true;
+ shared->page_entries[slotno].page_number = pageno;
+ shared->page_entries[slotno].page_status = SLRU_PAGE_VALID;
+ shared->page_entries[slotno].page_dirty = true;
SlruRecentlyUsed(shared, slotno);
/* Set the buffer to zeroes */
@@ -387,18 +382,18 @@ SimpleLruWaitIO(SlruCtl ctl, int slotno)
* cheaply test for failure by seeing if the buffer lock is still held (we
* assume that transaction abort would release the lock).
*/
- if (shared->page_status[slotno] == SLRU_PAGE_READ_IN_PROGRESS ||
- shared->page_status[slotno] == SLRU_PAGE_WRITE_IN_PROGRESS)
+ if (shared->page_entries[slotno].page_status == SLRU_PAGE_READ_IN_PROGRESS ||
+ shared->page_entries[slotno].page_status == SLRU_PAGE_WRITE_IN_PROGRESS)
{
if (LWLockConditionalAcquire(&shared->buffer_locks[slotno].lock, LW_SHARED))
{
/* indeed, the I/O must have failed */
- if (shared->page_status[slotno] == SLRU_PAGE_READ_IN_PROGRESS)
- shared->page_status[slotno] = SLRU_PAGE_EMPTY;
+ if (shared->page_entries[slotno].page_status == SLRU_PAGE_READ_IN_PROGRESS)
+ shared->page_entries[slotno].page_status = SLRU_PAGE_EMPTY;
else /* write_in_progress */
{
- shared->page_status[slotno] = SLRU_PAGE_VALID;
- shared->page_dirty[slotno] = true;
+ shared->page_entries[slotno].page_status = SLRU_PAGE_VALID;
+ shared->page_entries[slotno].page_dirty = true;
}
LWLockRelease(&shared->buffer_locks[slotno].lock);
}
@@ -438,15 +433,15 @@ SimpleLruReadPage(SlruCtl ctl, int pageno, bool write_ok,
slotno = SlruSelectLRUPage(ctl, pageno);
/* Did we find the page in memory? */
- if (shared->page_number[slotno] == pageno &&
- shared->page_status[slotno] != SLRU_PAGE_EMPTY)
+ if (shared->page_entries[slotno].page_number == pageno &&
+ shared->page_entries[slotno].page_status != SLRU_PAGE_EMPTY)
{
/*
* If page is still being read in, we must wait for I/O. Likewise
* if the page is being written and the caller said that's not OK.
*/
- if (shared->page_status[slotno] == SLRU_PAGE_READ_IN_PROGRESS ||
- (shared->page_status[slotno] == SLRU_PAGE_WRITE_IN_PROGRESS &&
+ if (shared->page_entries[slotno].page_status == SLRU_PAGE_READ_IN_PROGRESS ||
+ (shared->page_entries[slotno].page_status == SLRU_PAGE_WRITE_IN_PROGRESS &&
!write_ok))
{
SimpleLruWaitIO(ctl, slotno);
@@ -463,14 +458,14 @@ SimpleLruReadPage(SlruCtl ctl, int pageno, bool write_ok,
}
/* We found no match; assert we selected a freeable slot */
- Assert(shared->page_status[slotno] == SLRU_PAGE_EMPTY ||
- (shared->page_status[slotno] == SLRU_PAGE_VALID &&
- !shared->page_dirty[slotno]));
+ Assert(shared->page_entries[slotno].page_status == SLRU_PAGE_EMPTY ||
+ (shared->page_entries[slotno].page_status == SLRU_PAGE_VALID &&
+ !shared->page_entries[slotno].page_dirty));
/* Mark the slot read-busy */
- shared->page_number[slotno] = pageno;
- shared->page_status[slotno] = SLRU_PAGE_READ_IN_PROGRESS;
- shared->page_dirty[slotno] = false;
+ shared->page_entries[slotno].page_number = pageno;
+ shared->page_entries[slotno].page_status = SLRU_PAGE_READ_IN_PROGRESS;
+ shared->page_entries[slotno].page_dirty = false;
/* Acquire per-buffer lock (cannot deadlock, see notes at top) */
LWLockAcquire(&shared->buffer_locks[slotno].lock, LW_EXCLUSIVE);
@@ -487,11 +482,11 @@ SimpleLruReadPage(SlruCtl ctl, int pageno, bool write_ok,
/* Re-acquire control lock and update page state */
LWLockAcquire(shared->ControlLock, LW_EXCLUSIVE);
- Assert(shared->page_number[slotno] == pageno &&
- shared->page_status[slotno] == SLRU_PAGE_READ_IN_PROGRESS &&
- !shared->page_dirty[slotno]);
+ Assert(shared->page_entries[slotno].page_number == pageno &&
+ shared->page_entries[slotno].page_status == SLRU_PAGE_READ_IN_PROGRESS &&
+ !shared->page_entries[slotno].page_dirty);
- shared->page_status[slotno] = ok ? SLRU_PAGE_VALID : SLRU_PAGE_EMPTY;
+ shared->page_entries[slotno].page_status = ok ? SLRU_PAGE_VALID : SLRU_PAGE_EMPTY;
LWLockRelease(&shared->buffer_locks[slotno].lock);
@@ -536,9 +531,9 @@ SimpleLruReadPage_ReadOnly(SlruCtl ctl, int pageno, TransactionId xid)
int bankend = bankstart + shared->bank_size;
for (slotno = bankstart; slotno < bankend; slotno++)
{
- if (shared->page_number[slotno] == pageno &&
- shared->page_status[slotno] != SLRU_PAGE_EMPTY &&
- shared->page_status[slotno] != SLRU_PAGE_READ_IN_PROGRESS)
+ if (shared->page_entries[slotno].page_number == pageno &&
+ shared->page_entries[slotno].page_status != SLRU_PAGE_EMPTY &&
+ shared->page_entries[slotno].page_status != SLRU_PAGE_READ_IN_PROGRESS)
{
/* See comments for SlruRecentlyUsed macro */
SlruRecentlyUsed(shared, slotno);
@@ -572,12 +567,12 @@ static void
SlruInternalWritePage(SlruCtl ctl, int slotno, SlruWriteAll fdata)
{
SlruShared shared = ctl->shared;
- int pageno = shared->page_number[slotno];
+ int pageno = shared->page_entries[slotno].page_number;
bool ok;
/* If a write is in progress, wait for it to finish */
- while (shared->page_status[slotno] == SLRU_PAGE_WRITE_IN_PROGRESS &&
- shared->page_number[slotno] == pageno)
+ while (shared->page_entries[slotno].page_status == SLRU_PAGE_WRITE_IN_PROGRESS &&
+ shared->page_entries[slotno].page_number == pageno)
{
SimpleLruWaitIO(ctl, slotno);
}
@@ -586,17 +581,17 @@ SlruInternalWritePage(SlruCtl ctl, int slotno, SlruWriteAll fdata)
* Do nothing if page is not dirty, or if buffer no longer contains the
* same page we were called for.
*/
- if (!shared->page_dirty[slotno] ||
- shared->page_status[slotno] != SLRU_PAGE_VALID ||
- shared->page_number[slotno] != pageno)
+ if (!shared->page_entries[slotno].page_dirty ||
+ shared->page_entries[slotno].page_status != SLRU_PAGE_VALID ||
+ shared->page_entries[slotno].page_number != pageno)
return;
/*
* Mark the slot write-busy, and clear the dirtybit. After this point, a
* transaction status update on this page will mark it dirty again.
*/
- shared->page_status[slotno] = SLRU_PAGE_WRITE_IN_PROGRESS;
- shared->page_dirty[slotno] = false;
+ shared->page_entries[slotno].page_status = SLRU_PAGE_WRITE_IN_PROGRESS;
+ shared->page_entries[slotno].page_dirty = false;
/* Acquire per-buffer lock (cannot deadlock, see notes at top) */
LWLockAcquire(&shared->buffer_locks[slotno].lock, LW_EXCLUSIVE);
@@ -619,14 +614,14 @@ SlruInternalWritePage(SlruCtl ctl, int slotno, SlruWriteAll fdata)
/* Re-acquire control lock and update page state */
LWLockAcquire(shared->ControlLock, LW_EXCLUSIVE);
- Assert(shared->page_number[slotno] == pageno &&
- shared->page_status[slotno] == SLRU_PAGE_WRITE_IN_PROGRESS);
+ Assert(shared->page_entries[slotno].page_number == pageno &&
+ shared->page_entries[slotno].page_status == SLRU_PAGE_WRITE_IN_PROGRESS);
/* If we failed to write, mark the page dirty again */
if (!ok)
- shared->page_dirty[slotno] = true;
+ shared->page_entries[slotno].page_dirty = true;
- shared->page_status[slotno] = SLRU_PAGE_VALID;
+ shared->page_entries[slotno].page_status = SLRU_PAGE_VALID;
LWLockRelease(&shared->buffer_locks[slotno].lock);
@@ -1067,8 +1062,8 @@ SlruSelectLRUPage(SlruCtl ctl, int pageno)
int bankend = bankstart + shared->bank_size;
for (slotno = bankstart; slotno < bankend; slotno++)
{
- if (shared->page_number[slotno] == pageno &&
- shared->page_status[slotno] != SLRU_PAGE_EMPTY)
+ if (shared->page_entries[slotno].page_number == pageno &&
+ shared->page_entries[slotno].page_status != SLRU_PAGE_EMPTY)
return slotno;
}
@@ -1105,7 +1100,7 @@ SlruSelectLRUPage(SlruCtl ctl, int pageno)
int this_delta;
int this_page_number;
- if (shared->page_status[slotno] == SLRU_PAGE_EMPTY)
+ if (shared->page_entries[slotno].page_status == SLRU_PAGE_EMPTY)
return slotno;
this_delta = cur_count - shared->page_lru_count[slotno];
if (this_delta < 0)
@@ -1120,10 +1115,10 @@ SlruSelectLRUPage(SlruCtl ctl, int pageno)
shared->page_lru_count[slotno] = cur_count;
this_delta = 0;
}
- this_page_number = shared->page_number[slotno];
+ this_page_number = shared->page_entries[slotno].page_number;
if (this_page_number == shared->latest_page_number)
continue;
- if (shared->page_status[slotno] == SLRU_PAGE_VALID)
+ if (shared->page_entries[slotno].page_status == SLRU_PAGE_VALID)
{
if (this_delta > best_valid_delta ||
(this_delta == best_valid_delta &&
@@ -1165,7 +1160,7 @@ SlruSelectLRUPage(SlruCtl ctl, int pageno)
/*
* If the selected page is clean, we're set.
*/
- if (!shared->page_dirty[bestvalidslot])
+ if (!shared->page_entries[bestvalidslot].page_dirty)
return bestvalidslot;
/*
@@ -1217,9 +1212,9 @@ SimpleLruWriteAll(SlruCtl ctl, bool allow_redirtied)
* already. That's okay.
*/
Assert(allow_redirtied ||
- shared->page_status[slotno] == SLRU_PAGE_EMPTY ||
- (shared->page_status[slotno] == SLRU_PAGE_VALID &&
- !shared->page_dirty[slotno]));
+ shared->page_entries[slotno].page_status == SLRU_PAGE_EMPTY ||
+ (shared->page_entries[slotno].page_status == SLRU_PAGE_VALID &&
+ !shared->page_entries[slotno].page_dirty));
}
LWLockRelease(shared->ControlLock);
@@ -1291,18 +1286,18 @@ restart:;
for (slotno = 0; slotno < shared->num_slots; slotno++)
{
- if (shared->page_status[slotno] == SLRU_PAGE_EMPTY)
+ if (shared->page_entries[slotno].page_status == SLRU_PAGE_EMPTY)
continue;
- if (!ctl->PagePrecedes(shared->page_number[slotno], cutoffPage))
+ if (!ctl->PagePrecedes(shared->page_entries[slotno].page_number, cutoffPage))
continue;
/*
* If page is clean, just change state to EMPTY (expected case).
*/
- if (shared->page_status[slotno] == SLRU_PAGE_VALID &&
- !shared->page_dirty[slotno])
+ if (shared->page_entries[slotno].page_status == SLRU_PAGE_VALID &&
+ !shared->page_entries[slotno].page_dirty)
{
- shared->page_status[slotno] = SLRU_PAGE_EMPTY;
+ shared->page_entries[slotno].page_status = SLRU_PAGE_EMPTY;
continue;
}
@@ -1316,7 +1311,7 @@ restart:;
* won't have cause to read its data again. For now, keep the logic
* the same as it was.)
*/
- if (shared->page_status[slotno] == SLRU_PAGE_VALID)
+ if (shared->page_entries[slotno].page_status == SLRU_PAGE_VALID)
SlruInternalWritePage(ctl, slotno, NULL);
else
SimpleLruWaitIO(ctl, slotno);
@@ -1371,9 +1366,9 @@ restart:
did_write = false;
for (slotno = 0; slotno < shared->num_slots; slotno++)
{
- int pagesegno = shared->page_number[slotno] / SLRU_PAGES_PER_SEGMENT;
+ int pagesegno = shared->page_entries[slotno].page_number / SLRU_PAGES_PER_SEGMENT;
- if (shared->page_status[slotno] == SLRU_PAGE_EMPTY)
+ if (shared->page_entries[slotno].page_status == SLRU_PAGE_EMPTY)
continue;
/* not the segment we're looking for */
@@ -1381,15 +1376,15 @@ restart:
continue;
/* If page is clean, just change state to EMPTY (expected case). */
- if (shared->page_status[slotno] == SLRU_PAGE_VALID &&
- !shared->page_dirty[slotno])
+ if (shared->page_entries[slotno].page_status == SLRU_PAGE_VALID &&
+ !shared->page_entries[slotno].page_dirty)
{
- shared->page_status[slotno] = SLRU_PAGE_EMPTY;
+ shared->page_entries[slotno].page_status = SLRU_PAGE_EMPTY;
continue;
}
/* Same logic as SimpleLruTruncate() */
- if (shared->page_status[slotno] == SLRU_PAGE_VALID)
+ if (shared->page_entries[slotno].page_status == SLRU_PAGE_VALID)
SlruInternalWritePage(ctl, slotno, NULL);
else
SimpleLruWaitIO(ctl, slotno);
diff --git a/src/backend/access/transam/subtrans.c b/src/backend/access/transam/subtrans.c
index 785f2520fde..11754fdbac6 100644
--- a/src/backend/access/transam/subtrans.c
+++ b/src/backend/access/transam/subtrans.c
@@ -97,7 +97,7 @@ SubTransSetParent(TransactionId xid, TransactionId parent)
{
Assert(*ptr == InvalidTransactionId);
*ptr = parent;
- SubTransCtl->shared->page_dirty[slotno] = true;
+ SubTransCtl->shared->page_entries[slotno].page_dirty = true;
}
LWLockRelease(SubtransSLRULock);
@@ -220,7 +220,7 @@ BootStrapSUBTRANS(void)
/* Make sure it's written out */
SimpleLruWritePage(SubTransCtl, slotno);
- Assert(!SubTransCtl->shared->page_dirty[slotno]);
+ Assert(!SubTransCtl->shared->page_entries[slotno].page_dirty);
LWLockRelease(SubtransSLRULock);
}
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index 7f2b7598449..86a5bc2430c 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -1445,7 +1445,7 @@ asyncQueueAddEntries(ListCell *nextNotify)
InvalidTransactionId);
/* Note we mark the page dirty before writing in it */
- NotifyCtl->shared->page_dirty[slotno] = true;
+ NotifyCtl->shared->page_entries[slotno].page_dirty = true;
while (nextNotify != NULL)
{
diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c
index c5e66757643..53bd7d957ce 100644
--- a/src/backend/storage/lmgr/predicate.c
+++ b/src/backend/storage/lmgr/predicate.c
@@ -963,7 +963,7 @@ SerialAdd(TransactionId xid, SerCommitSeqNo minConflictCommitSeqNo)
slotno = SimpleLruReadPage(SerialSlruCtl, targetPage, true, xid);
SerialValue(slotno, xid) = minConflictCommitSeqNo;
- SerialSlruCtl->shared->page_dirty[slotno] = true;
+ SerialSlruCtl->shared->page_entries[slotno].page_dirty = true;
LWLockRelease(SerialSLRULock);
}
diff --git a/src/include/access/slru.h b/src/include/access/slru.h
index f4df54d3c12..0a4fae91d7f 100644
--- a/src/include/access/slru.h
+++ b/src/include/access/slru.h
@@ -44,7 +44,7 @@
* in the latter case it implies that the page has been re-dirtied since
* the write started.
*/
-typedef enum
+typedef enum SlruPageStatus:int16_t
{
SLRU_PAGE_EMPTY, /* buffer is not in use */
SLRU_PAGE_READ_IN_PROGRESS, /* page is being read in */
@@ -52,6 +52,13 @@ typedef enum
SLRU_PAGE_WRITE_IN_PROGRESS /* page is being written out */
} SlruPageStatus;
+typedef struct SlruPageEntry
+{
+ int page_number;
+ SlruPageStatus page_status;
+ bool page_dirty;
+} SlruPageEntry;
+
/*
* Shared-memory state
*/
@@ -69,9 +76,7 @@ typedef struct SlruSharedData
* when status is EMPTY, as is page_lru_count.
*/
char **page_buffer;
- SlruPageStatus *page_status;
- bool *page_dirty;
- int *page_number;
+ SlruPageEntry *page_entries;
int *page_lru_count;
LWLockPadded *buffer_locks;
--
2.33.1