LCOV - code coverage report
Current view: top level - src/include/access - slru.h (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 100.0 % 3 3
Test Date: 2026-04-07 14:16:30 Functions: 100.0 % 1 1
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*-------------------------------------------------------------------------
       2              :  *
       3              :  * slru.h
       4              :  *      Simple LRU buffering for transaction status logfiles
       5              :  *
       6              :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
       7              :  * Portions Copyright (c) 1994, Regents of the University of California
       8              :  *
       9              :  * src/include/access/slru.h
      10              :  *
      11              :  *-------------------------------------------------------------------------
      12              :  */
      13              : #ifndef SLRU_H
      14              : #define SLRU_H
      15              : 
      16              : #include "access/transam.h"
      17              : #include "access/xlogdefs.h"
      18              : #include "storage/lwlock.h"
      19              : #include "storage/shmem.h"
      20              : #include "storage/sync.h"
      21              : 
      22              : /*
      23              :  * To avoid overflowing internal arithmetic and the size_t data type, the
      24              :  * number of buffers must not exceed this number.
      25              :  */
      26              : #define SLRU_MAX_ALLOWED_BUFFERS ((1024 * 1024 * 1024) / BLCKSZ)
      27              : 
      28              : /*
      29              :  * Page status codes.  Note that these do not include the "dirty" bit.
      30              :  * page_dirty can be true only in the VALID or WRITE_IN_PROGRESS states;
      31              :  * in the latter case it implies that the page has been re-dirtied since
      32              :  * the write started.
      33              :  */
      34              : typedef enum
      35              : {
      36              :     SLRU_PAGE_EMPTY,            /* buffer is not in use */
      37              :     SLRU_PAGE_READ_IN_PROGRESS, /* page is being read in */
      38              :     SLRU_PAGE_VALID,            /* page is valid and not being written */
      39              :     SLRU_PAGE_WRITE_IN_PROGRESS,    /* page is being written out */
      40              : } SlruPageStatus;
      41              : 
      42              : /*
      43              :  * Shared-memory state
      44              :  *
      45              :  * SLRU bank locks are used to protect access to the other fields, except
      46              :  * latest_page_number, which uses atomics; see comment in slru.c.
      47              :  */
      48              : typedef struct SlruSharedData
      49              : {
      50              :     /* Number of buffers managed by this SLRU structure */
      51              :     int         num_slots;
      52              : 
      53              :     /*
      54              :      * Arrays holding info for each buffer slot.  Page number is undefined
      55              :      * when status is EMPTY, as is page_lru_count.
      56              :      */
      57              :     char      **page_buffer;
      58              :     SlruPageStatus *page_status;
      59              :     bool       *page_dirty;
      60              :     int64      *page_number;
      61              :     int        *page_lru_count;
      62              : 
      63              :     /* The buffer_locks protects the I/O on each buffer slots */
      64              :     LWLockPadded *buffer_locks;
      65              : 
      66              :     /* Locks to protect the in memory buffer slot access in SLRU bank. */
      67              :     LWLockPadded *bank_locks;
      68              : 
      69              :     /*----------
      70              :      * A bank-wise LRU counter is maintained because we do a victim buffer
      71              :      * search within a bank. Furthermore, manipulating an individual bank
      72              :      * counter avoids frequent cache invalidation since we update it every time
      73              :      * we access the page.
      74              :      *
      75              :      * We mark a page "most recently used" by setting
      76              :      *      page_lru_count[slotno] = ++bank_cur_lru_count[bankno];
      77              :      * The oldest page in the bank is therefore the one with the highest value
      78              :      * of
      79              :      *      bank_cur_lru_count[bankno] - page_lru_count[slotno]
      80              :      * The counts will eventually wrap around, but this calculation still
      81              :      * works as long as no page's age exceeds INT_MAX counts.
      82              :      *----------
      83              :      */
      84              :     int        *bank_cur_lru_count;
      85              : 
      86              :     /*
      87              :      * Optional array of WAL flush LSNs associated with entries in the SLRU
      88              :      * pages.  If not zero/NULL, we must flush WAL before writing pages (true
      89              :      * for pg_xact, false for everything else).  group_lsn[] has
      90              :      * lsn_groups_per_page entries per buffer slot, each containing the
      91              :      * highest LSN known for a contiguous group of SLRU entries on that slot's
      92              :      * page.
      93              :      */
      94              :     XLogRecPtr *group_lsn;
      95              :     int         lsn_groups_per_page;
      96              : 
      97              :     /*
      98              :      * latest_page_number is the page number of the current end of the log;
      99              :      * this is not critical data, since we use it only to avoid swapping out
     100              :      * the latest page.
     101              :      */
     102              :     pg_atomic_uint64 latest_page_number;
     103              : 
     104              :     /* SLRU's index for statistics purposes (might not be unique) */
     105              :     int         slru_stats_idx;
     106              : } SlruSharedData;
     107              : 
     108              : typedef SlruSharedData *SlruShared;
     109              : 
     110              : typedef struct SlruDesc SlruDesc;
     111              : 
     112              : /*
     113              :  * Options for SimpleLruRequest()
     114              :  */
     115              : typedef struct SlruOpts
     116              : {
     117              :     /* Options for allocating the underlying shmem area; do not touch directly */
     118              :     ShmemStructOpts base;
     119              : 
     120              :     /*
     121              :      * name of SLRU.  (This is user-visible, pick with care!)
     122              :      */
     123              :     const char *name;
     124              : 
     125              :     /*
     126              :      * Pointer to a backend-private handle for the SLRU.  It is initialized
     127              :      * when the SLRU is initialized or attached to.
     128              :      */
     129              :     SlruDesc   *desc;
     130              : 
     131              :     /* number of page slots to use. */
     132              :     int         nslots;
     133              : 
     134              :     /* number of LSN groups per page (set to zero if not relevant). */
     135              :     int         nlsns;
     136              : 
     137              :     /*
     138              :      * Which sync handler function to use when handing sync requests over to
     139              :      * the checkpointer.  SYNC_HANDLER_NONE to disable fsync (eg pg_notify).
     140              :      */
     141              :     SyncRequestHandler sync_handler;
     142              : 
     143              :     /*
     144              :      * PGDATA-relative subdirectory that will contain the files.
     145              :      */
     146              :     const char *Dir;
     147              : 
     148              :     /*
     149              :      * If true, use long segment file names.  Otherwise, use short file names.
     150              :      *
     151              :      * For details about the file name format, see SlruFileName().
     152              :      */
     153              :     bool        long_segment_names;
     154              : 
     155              : 
     156              :     /*
     157              :      * Decide whether a page is "older" for truncation and as a hint for
     158              :      * evicting pages in LRU order.  Return true if every entry of the first
     159              :      * argument is older than every entry of the second argument.  Note that
     160              :      * !PagePrecedes(a,b) && !PagePrecedes(b,a) need not imply a==b; it also
     161              :      * arises when some entries are older and some are not.  For SLRUs using
     162              :      * SimpleLruTruncate(), this must use modular arithmetic.  (For others,
     163              :      * the behavior of this callback has no functional implications.)  Use
     164              :      * SlruPagePrecedesUnitTests() in SLRUs meeting its criteria.
     165              :      */
     166              :     bool        (*PagePrecedes) (int64, int64);
     167              : 
     168              :     /*
     169              :      * Callback to provide more details on an I/O error.  This is called as
     170              :      * part of ereport(), and the callback function is expected to call
     171              :      * errdetail() to provide more context on the SLRU access.
     172              :      *
     173              :      * The opaque_data argument here is the argument that was passed to the
     174              :      * SimpleLruReadPage() function.
     175              :      */
     176              :     int         (*errdetail_for_io_error) (const void *opaque_data);
     177              : 
     178              :     /*
     179              :      * Tranche IDs to use for the SLRU's per-buffer and per-bank LWLocks.  If
     180              :      * these are left as zeros, new tranches will be assigned dynamically.
     181              :      */
     182              :     int         buffer_tranche_id;
     183              :     int         bank_tranche_id;
     184              : } SlruOpts;
     185              : 
     186              : /*
     187              :  * SlruDesc is an unshared structure that points to the active information
     188              :  * in shared memory.
     189              :  */
     190              : typedef struct SlruDesc
     191              : {
     192              :     SlruOpts    options;
     193              : 
     194              :     SlruShared  shared;
     195              : 
     196              :     /* Number of banks in this SLRU. */
     197              :     uint16      nbanks;
     198              : } SlruDesc;
     199              : 
     200              : /*
     201              :  * Get the SLRU bank lock for the given pageno.
     202              :  *
     203              :  * This lock needs to be acquired to access the slru buffer slots in the
     204              :  * respective bank.
     205              :  */
     206              : static inline LWLock *
     207      9929358 : SimpleLruGetBankLock(SlruDesc *ctl, int64 pageno)
     208              : {
     209              :     int         bankno;
     210              : 
     211              :     Assert(ctl->nbanks != 0);
     212      9929358 :     bankno = pageno % ctl->nbanks;
     213      9929358 :     return &(ctl->shared->bank_locks[bankno].lock);
     214              : }
     215              : 
     216              : extern void SimpleLruRequestWithOpts(const SlruOpts *options);
     217              : 
     218              : #define SimpleLruRequest(...)  \
     219              :     SimpleLruRequestWithOpts(&(SlruOpts){__VA_ARGS__})
     220              : 
     221              : extern int  SimpleLruAutotuneBuffers(int divisor, int max);
     222              : extern int  SimpleLruZeroPage(SlruDesc *ctl, int64 pageno);
     223              : extern void SimpleLruZeroAndWritePage(SlruDesc *ctl, int64 pageno);
     224              : extern int  SimpleLruReadPage(SlruDesc *ctl, int64 pageno, bool write_ok,
     225              :                               const void *opaque_data);
     226              : extern int  SimpleLruReadPage_ReadOnly(SlruDesc *ctl, int64 pageno,
     227              :                                        const void *opaque_data);
     228              : extern void SimpleLruWritePage(SlruDesc *ctl, int slotno);
     229              : extern void SimpleLruWriteAll(SlruDesc *ctl, bool allow_redirtied);
     230              : #ifdef USE_ASSERT_CHECKING
     231              : extern void SlruPagePrecedesUnitTests(SlruDesc *ctl, int per_page);
     232              : #else
     233              : #define SlruPagePrecedesUnitTests(ctl, per_page) do {} while (0)
     234              : #endif
     235              : extern void SimpleLruTruncate(SlruDesc *ctl, int64 cutoffPage);
     236              : extern bool SimpleLruDoesPhysicalPageExist(SlruDesc *ctl, int64 pageno);
     237              : 
     238              : typedef bool (*SlruScanCallback) (SlruDesc *ctl, char *filename, int64 segpage,
     239              :                                   void *data);
     240              : extern bool SlruScanDirectory(SlruDesc *ctl, SlruScanCallback callback, void *data);
     241              : extern void SlruDeleteSegment(SlruDesc *ctl, int64 segno);
     242              : 
     243              : extern int  SlruSyncFileTag(SlruDesc *ctl, const FileTag *ftag, char *path);
     244              : 
     245              : /* SlruScanDirectory public callbacks */
     246              : extern bool SlruScanDirCbReportPresence(SlruDesc *ctl, char *filename,
     247              :                                         int64 segpage, void *data);
     248              : extern bool SlruScanDirCbDeleteAll(SlruDesc *ctl, char *filename, int64 segpage,
     249              :                                    void *data);
     250              : extern bool check_slru_buffers(const char *name, int *newval);
     251              : 
     252              : extern void shmem_slru_init(void *location, ShmemStructOpts *base_options);
     253              : extern void shmem_slru_attach(void *location, ShmemStructOpts *base_options);
     254              : 
     255              : #endif                          /* SLRU_H */
        

Generated by: LCOV version 2.0-1