LCOV - code coverage report
Current view: top level - src/backend/storage/buffer - buf_init.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 95.3 % 43 41
Test Date: 2026-01-26 10:56:24 Functions: 100.0 % 2 2
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 50.0 % 12 6

             Branch data     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                 :           6 : BufferManagerShmemInit(void)
      70                 :             : {
      71                 :           6 :         bool            foundBufs,
      72                 :             :                                 foundDescs,
      73                 :             :                                 foundIOCV,
      74                 :             :                                 foundBufCkpt;
      75                 :             : 
      76                 :             :         /* Align descriptors to a cacheline boundary. */
      77                 :           6 :         BufferDescriptors = (BufferDescPadded *)
      78                 :           6 :                 ShmemInitStruct("Buffer Descriptors",
      79                 :           6 :                                                 NBuffers * sizeof(BufferDescPadded),
      80                 :             :                                                 &foundDescs);
      81                 :             : 
      82                 :             :         /* Align buffer pool on IO page size boundary. */
      83                 :           6 :         BufferBlocks = (char *)
      84                 :           6 :                 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                 :           6 :         BufferIOCVArray = (ConditionVariableMinimallyPadded *)
      91                 :           6 :                 ShmemInitStruct("Buffer IO Condition Variables",
      92                 :           6 :                                                 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                 :           6 :         CkptBufferIds = (CkptSortItem *)
     103                 :           6 :                 ShmemInitStruct("Checkpoint BufferIds",
     104                 :           6 :                                                 NBuffers * sizeof(CkptSortItem), &foundBufCkpt);
     105                 :             : 
     106   [ +  -  +  -  :           6 :         if (foundDescs || foundBufs || foundIOCV || foundBufCkpt)
             +  -  -  + ]
     107                 :             :         {
     108                 :             :                 /* should find all of these, or none of them */
     109         [ #  # ]:           0 :                 Assert(foundDescs && foundBufs && foundIOCV && foundBufCkpt);
     110                 :             :                 /* note: this path is only taken in EXEC_BACKEND case */
     111                 :           0 :         }
     112                 :             :         else
     113                 :             :         {
     114                 :           6 :                 int                     i;
     115                 :             : 
     116                 :             :                 /*
     117                 :             :                  * Initialize all the buffer headers.
     118                 :             :                  */
     119         [ +  + ]:       82926 :                 for (i = 0; i < NBuffers; i++)
     120                 :             :                 {
     121                 :       82920 :                         BufferDesc *buf = GetBufferDescriptor(i);
     122                 :             : 
     123                 :       82920 :                         ClearBufferTag(&buf->tag);
     124                 :             : 
     125                 :       82920 :                         pg_atomic_init_u64(&buf->state, 0);
     126                 :       82920 :                         buf->wait_backend_pgprocno = INVALID_PROC_NUMBER;
     127                 :             : 
     128                 :       82920 :                         buf->buf_id = i;
     129                 :             : 
     130                 :       82920 :                         pgaio_wref_clear(&buf->io_wref);
     131                 :             : 
     132                 :       82920 :                         proclist_init(&buf->lock_waiters);
     133                 :       82920 :                         ConditionVariableInit(BufferDescriptorGetIOCV(buf));
     134                 :       82920 :                 }
     135                 :           6 :         }
     136                 :             : 
     137                 :             :         /* Init other shared buffer-management stuff */
     138                 :           6 :         StrategyInitialize(!foundDescs);
     139                 :             : 
     140                 :             :         /* Initialize per-backend file flush context */
     141                 :           6 :         WritebackContextInit(&BackendWritebackContext,
     142                 :             :                                                  &backend_flush_after);
     143                 :           6 : }
     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                 :           9 : BufferManagerShmemSize(void)
     153                 :             : {
     154                 :           9 :         Size            size = 0;
     155                 :             : 
     156                 :             :         /* size of buffer descriptors */
     157                 :           9 :         size = add_size(size, mul_size(NBuffers, sizeof(BufferDescPadded)));
     158                 :             :         /* to allow aligning buffer descriptors */
     159                 :           9 :         size = add_size(size, PG_CACHE_LINE_SIZE);
     160                 :             : 
     161                 :             :         /* size of data pages, plus alignment padding */
     162                 :           9 :         size = add_size(size, PG_IO_ALIGN_SIZE);
     163                 :           9 :         size = add_size(size, mul_size(NBuffers, BLCKSZ));
     164                 :             : 
     165                 :             :         /* size of stuff controlled by freelist.c */
     166                 :           9 :         size = add_size(size, StrategyShmemSize());
     167                 :             : 
     168                 :             :         /* size of I/O condition variables */
     169                 :           9 :         size = add_size(size, mul_size(NBuffers,
     170                 :             :                                                                    sizeof(ConditionVariableMinimallyPadded)));
     171                 :             :         /* to allow aligning the above */
     172                 :           9 :         size = add_size(size, PG_CACHE_LINE_SIZE);
     173                 :             : 
     174                 :             :         /* size of checkpoint sort array in bufmgr.c */
     175                 :           9 :         size = add_size(size, mul_size(NBuffers, sizeof(CkptSortItem)));
     176                 :             : 
     177                 :          18 :         return size;
     178                 :           9 : }
        

Generated by: LCOV version 2.3.2-1