LCOV - code coverage report
Current view: top level - src/backend/storage/buffer - buf_init.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 85.7 % 21 18
Test Date: 2026-04-07 14:16:30 Functions: 66.7 % 3 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              : #include "storage/shmem.h"
      22              : #include "storage/subsystems.h"
      23              : 
      24              : BufferDescPadded *BufferDescriptors;
      25              : char       *BufferBlocks;
      26              : ConditionVariableMinimallyPadded *BufferIOCVArray;
      27              : WritebackContext BackendWritebackContext;
      28              : CkptSortItem *CkptBufferIds;
      29              : 
      30              : static void BufferManagerShmemRequest(void *arg);
      31              : static void BufferManagerShmemInit(void *arg);
      32              : static void BufferManagerShmemAttach(void *arg);
      33              : 
      34              : const ShmemCallbacks BufferManagerShmemCallbacks = {
      35              :     .request_fn = BufferManagerShmemRequest,
      36              :     .init_fn = BufferManagerShmemInit,
      37              :     .attach_fn = BufferManagerShmemAttach,
      38              : };
      39              : 
      40              : /*
      41              :  * Data Structures:
      42              :  *      buffers live in a freelist and a lookup data structure.
      43              :  *
      44              :  *
      45              :  * Buffer Lookup:
      46              :  *      Two important notes.  First, the buffer has to be
      47              :  *      available for lookup BEFORE an IO begins.  Otherwise
      48              :  *      a second process trying to read the buffer will
      49              :  *      allocate its own copy and the buffer pool will
      50              :  *      become inconsistent.
      51              :  *
      52              :  * Buffer Replacement:
      53              :  *      see freelist.c.  A buffer cannot be replaced while in
      54              :  *      use either by data manager or during IO.
      55              :  *
      56              :  *
      57              :  * Synchronization/Locking:
      58              :  *
      59              :  * IO_IN_PROGRESS -- this is a flag in the buffer descriptor.
      60              :  *      It must be set when an IO is initiated and cleared at
      61              :  *      the end of the IO.  It is there to make sure that one
      62              :  *      process doesn't start to use a buffer while another is
      63              :  *      faulting it in.  see WaitIO and related routines.
      64              :  *
      65              :  * refcount --  Counts the number of processes holding pins on a buffer.
      66              :  *      A buffer is pinned during IO and immediately after a BufferAlloc().
      67              :  *      Pins must be released before end of transaction.  For efficiency the
      68              :  *      shared refcount isn't increased if an individual backend pins a buffer
      69              :  *      multiple times. Check the PrivateRefCount infrastructure in bufmgr.c.
      70              :  */
      71              : 
      72              : 
      73              : /*
      74              :  * Register shared memory area for the buffer pool.
      75              :  */
      76              : static void
      77         1234 : BufferManagerShmemRequest(void *arg)
      78              : {
      79         1234 :     ShmemRequestStruct(.name = "Buffer Descriptors",
      80              :                        .size = NBuffers * sizeof(BufferDescPadded),
      81              :     /* Align descriptors to a cacheline boundary. */
      82              :                        .alignment = PG_CACHE_LINE_SIZE,
      83              :                        .ptr = (void **) &BufferDescriptors,
      84              :         );
      85              : 
      86         1234 :     ShmemRequestStruct(.name = "Buffer Blocks",
      87              :                        .size = NBuffers * (Size) BLCKSZ,
      88              :     /* Align buffer pool on IO page size boundary. */
      89              :                        .alignment = PG_IO_ALIGN_SIZE,
      90              :                        .ptr = (void **) &BufferBlocks,
      91              :         );
      92              : 
      93         1234 :     ShmemRequestStruct(.name = "Buffer IO Condition Variables",
      94              :                        .size = NBuffers * sizeof(ConditionVariableMinimallyPadded),
      95              :     /* Align descriptors to a cacheline boundary. */
      96              :                        .alignment = PG_CACHE_LINE_SIZE,
      97              :                        .ptr = (void **) &BufferIOCVArray,
      98              :         );
      99              : 
     100              :     /*
     101              :      * The array used to sort to-be-checkpointed buffer ids is located in
     102              :      * shared memory, to avoid having to allocate significant amounts of
     103              :      * memory at runtime. As that'd be in the middle of a checkpoint, or when
     104              :      * the checkpointer is restarted, memory allocation failures would be
     105              :      * painful.
     106              :      */
     107         1234 :     ShmemRequestStruct(.name = "Checkpoint BufferIds",
     108              :                        .size = NBuffers * sizeof(CkptSortItem),
     109              :                        .ptr = (void **) &CkptBufferIds,
     110              :         );
     111         1234 : }
     112              : 
     113              : /*
     114              :  * Initialize shared buffer pool
     115              :  *
     116              :  * This is called once during shared-memory initialization (either in the
     117              :  * postmaster, or in a standalone backend).
     118              :  */
     119              : static void
     120         1231 : BufferManagerShmemInit(void *arg)
     121              : {
     122              :     /*
     123              :      * Initialize all the buffer headers.
     124              :      */
     125     11814871 :     for (int i = 0; i < NBuffers; i++)
     126              :     {
     127     11813640 :         BufferDesc *buf = GetBufferDescriptor(i);
     128              : 
     129     11813640 :         ClearBufferTag(&buf->tag);
     130              : 
     131     11813640 :         pg_atomic_init_u64(&buf->state, 0);
     132     11813640 :         buf->wait_backend_pgprocno = INVALID_PROC_NUMBER;
     133              : 
     134     11813640 :         buf->buf_id = i;
     135              : 
     136     11813640 :         pgaio_wref_clear(&buf->io_wref);
     137              : 
     138     11813640 :         proclist_init(&buf->lock_waiters);
     139     11813640 :         ConditionVariableInit(BufferDescriptorGetIOCV(buf));
     140              :     }
     141              : 
     142              :     /* Initialize per-backend file flush context */
     143         1231 :     WritebackContextInit(&BackendWritebackContext,
     144              :                          &backend_flush_after);
     145         1231 : }
     146              : 
     147              : static void
     148            0 : BufferManagerShmemAttach(void *arg)
     149              : {
     150              :     /* Initialize per-backend file flush context */
     151            0 :     WritebackContextInit(&BackendWritebackContext,
     152              :                          &backend_flush_after);
     153            0 : }
        

Generated by: LCOV version 2.0-1