From 5c1aace8b1f5a2b852bf1476dffbd4a43f196ef3 Mon Sep 17 00:00:00 2001 From: Andrey Borodin 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