LCOV - code coverage report
Current view: top level - src/backend/storage/buffer - buf_init.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 100.0 % 33 33
Test Date: 2026-03-16 01:14:54 Functions: 100.0 % 2 2
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*-------------------------------------------------------------------------
       2              :  *
       3              :  * buf_init.c
       4              :  *    buffer manager initialization routines
       5              :  *
       6              :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
       7              :  * Portions Copyright (c) 1994, Regents of the University of California
       8              :  *
       9              :  *
      10              :  * IDENTIFICATION
      11              :  *    src/backend/storage/buffer/buf_init.c
      12              :  *
      13              :  *-------------------------------------------------------------------------
      14              :  */
      15              : #include "postgres.h"
      16              : 
      17              : #include "storage/aio.h"
      18              : #include "storage/buf_internals.h"
      19              : #include "storage/bufmgr.h"
      20              : #include "storage/proclist.h"
      21              : 
      22              : BufferDescPadded *BufferDescriptors;
      23              : char       *BufferBlocks;
      24              : ConditionVariableMinimallyPadded *BufferIOCVArray;
      25              : WritebackContext BackendWritebackContext;
      26              : CkptSortItem *CkptBufferIds;
      27              : 
      28              : 
      29              : /*
      30              :  * Data Structures:
      31              :  *      buffers live in a freelist and a lookup data structure.
      32              :  *
      33              :  *
      34              :  * Buffer Lookup:
      35              :  *      Two important notes.  First, the buffer has to be
      36              :  *      available for lookup BEFORE an IO begins.  Otherwise
      37              :  *      a second process trying to read the buffer will
      38              :  *      allocate its own copy and the buffer pool will
      39              :  *      become inconsistent.
      40              :  *
      41              :  * Buffer Replacement:
      42              :  *      see freelist.c.  A buffer cannot be replaced while in
      43              :  *      use either by data manager or during IO.
      44              :  *
      45              :  *
      46              :  * Synchronization/Locking:
      47              :  *
      48              :  * IO_IN_PROGRESS -- this is a flag in the buffer descriptor.
      49              :  *      It must be set when an IO is initiated and cleared at
      50              :  *      the end of the IO.  It is there to make sure that one
      51              :  *      process doesn't start to use a buffer while another is
      52              :  *      faulting it in.  see WaitIO and related routines.
      53              :  *
      54              :  * refcount --  Counts the number of processes holding pins on a buffer.
      55              :  *      A buffer is pinned during IO and immediately after a BufferAlloc().
      56              :  *      Pins must be released before end of transaction.  For efficiency the
      57              :  *      shared refcount isn't increased if an individual backend pins a buffer
      58              :  *      multiple times. Check the PrivateRefCount infrastructure in bufmgr.c.
      59              :  */
      60              : 
      61              : 
      62              : /*
      63              :  * Initialize shared buffer pool
      64              :  *
      65              :  * This is called once during shared-memory initialization (either in the
      66              :  * postmaster, or in a standalone backend).
      67              :  */
      68              : void
      69         1159 : BufferManagerShmemInit(void)
      70              : {
      71              :     bool        foundBufs,
      72              :                 foundDescs,
      73              :                 foundIOCV,
      74              :                 foundBufCkpt;
      75              : 
      76              :     /* Align descriptors to a cacheline boundary. */
      77         1159 :     BufferDescriptors = (BufferDescPadded *)
      78         1159 :         ShmemInitStruct("Buffer Descriptors",
      79              :                         NBuffers * sizeof(BufferDescPadded),
      80              :                         &foundDescs);
      81              : 
      82              :     /* Align buffer pool on IO page size boundary. */
      83         1159 :     BufferBlocks = (char *)
      84         1159 :         TYPEALIGN(PG_IO_ALIGN_SIZE,
      85              :                   ShmemInitStruct("Buffer Blocks",
      86              :                                   NBuffers * (Size) BLCKSZ + PG_IO_ALIGN_SIZE,
      87              :                                   &foundBufs));
      88              : 
      89              :     /* Align condition variables to cacheline boundary. */
      90         1159 :     BufferIOCVArray = (ConditionVariableMinimallyPadded *)
      91         1159 :         ShmemInitStruct("Buffer IO Condition Variables",
      92              :                         NBuffers * sizeof(ConditionVariableMinimallyPadded),
      93              :                         &foundIOCV);
      94              : 
      95              :     /*
      96              :      * The array used to sort to-be-checkpointed buffer ids is located in
      97              :      * shared memory, to avoid having to allocate significant amounts of
      98              :      * memory at runtime. As that'd be in the middle of a checkpoint, or when
      99              :      * the checkpointer is restarted, memory allocation failures would be
     100              :      * painful.
     101              :      */
     102         1159 :     CkptBufferIds = (CkptSortItem *)
     103         1159 :         ShmemInitStruct("Checkpoint BufferIds",
     104              :                         NBuffers * sizeof(CkptSortItem), &foundBufCkpt);
     105              : 
     106         1159 :     if (foundDescs || foundBufs || foundIOCV || foundBufCkpt)
     107              :     {
     108              :         /* should find all of these, or none of them */
     109              :         Assert(foundDescs && foundBufs && foundIOCV && foundBufCkpt);
     110              :         /* note: this path is only taken in EXEC_BACKEND case */
     111              :     }
     112              :     else
     113              :     {
     114              :         int         i;
     115              : 
     116              :         /*
     117              :          * Initialize all the buffer headers.
     118              :          */
     119     10873759 :         for (i = 0; i < NBuffers; i++)
     120              :         {
     121     10872600 :             BufferDesc *buf = GetBufferDescriptor(i);
     122              : 
     123     10872600 :             ClearBufferTag(&buf->tag);
     124              : 
     125     10872600 :             pg_atomic_init_u64(&buf->state, 0);
     126     10872600 :             buf->wait_backend_pgprocno = INVALID_PROC_NUMBER;
     127              : 
     128     10872600 :             buf->buf_id = i;
     129              : 
     130     10872600 :             pgaio_wref_clear(&buf->io_wref);
     131              : 
     132     10872600 :             proclist_init(&buf->lock_waiters);
     133     10872600 :             ConditionVariableInit(BufferDescriptorGetIOCV(buf));
     134              :         }
     135              :     }
     136              : 
     137              :     /* Init other shared buffer-management stuff */
     138         1159 :     StrategyInitialize(!foundDescs);
     139              : 
     140              :     /* Initialize per-backend file flush context */
     141         1159 :     WritebackContextInit(&BackendWritebackContext,
     142              :                          &backend_flush_after);
     143         1159 : }
     144              : 
     145              : /*
     146              :  * BufferManagerShmemSize
     147              :  *
     148              :  * compute the size of shared memory for the buffer pool including
     149              :  * data pages, buffer descriptors, hash tables, etc.
     150              :  */
     151              : Size
     152         2165 : BufferManagerShmemSize(void)
     153              : {
     154         2165 :     Size        size = 0;
     155              : 
     156              :     /* size of buffer descriptors */
     157         2165 :     size = add_size(size, mul_size(NBuffers, sizeof(BufferDescPadded)));
     158              :     /* to allow aligning buffer descriptors */
     159         2165 :     size = add_size(size, PG_CACHE_LINE_SIZE);
     160              : 
     161              :     /* size of data pages, plus alignment padding */
     162         2165 :     size = add_size(size, PG_IO_ALIGN_SIZE);
     163         2165 :     size = add_size(size, mul_size(NBuffers, BLCKSZ));
     164              : 
     165              :     /* size of stuff controlled by freelist.c */
     166         2165 :     size = add_size(size, StrategyShmemSize());
     167              : 
     168              :     /* size of I/O condition variables */
     169         2165 :     size = add_size(size, mul_size(NBuffers,
     170              :                                    sizeof(ConditionVariableMinimallyPadded)));
     171              :     /* to allow aligning the above */
     172         2165 :     size = add_size(size, PG_CACHE_LINE_SIZE);
     173              : 
     174              :     /* size of checkpoint sort array in bufmgr.c */
     175         2165 :     size = add_size(size, mul_size(NBuffers, sizeof(CkptSortItem)));
     176              : 
     177         2165 :     return size;
     178              : }
        

Generated by: LCOV version 2.0-1