LCOV - code coverage report
Current view: top level - src/backend/storage/ipc - ipci.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 84.2 % 38 32
Test Date: 2026-04-07 14:16:30 Functions: 80.0 % 5 4
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*-------------------------------------------------------------------------
       2              :  *
       3              :  * ipci.c
       4              :  *    POSTGRES inter-process communication initialization code.
       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/ipc/ipci.c
      12              :  *
      13              :  *-------------------------------------------------------------------------
      14              :  */
      15              : #include "postgres.h"
      16              : 
      17              : #include "miscadmin.h"
      18              : #include "pgstat.h"
      19              : #include "storage/dsm.h"
      20              : #include "storage/ipc.h"
      21              : #include "storage/lock.h"
      22              : #include "storage/pg_shmem.h"
      23              : #include "storage/proc.h"
      24              : #include "storage/shmem_internal.h"
      25              : #include "storage/subsystems.h"
      26              : #include "utils/guc.h"
      27              : 
      28              : /* GUCs */
      29              : int         shared_memory_type = DEFAULT_SHARED_MEMORY_TYPE;
      30              : 
      31              : shmem_startup_hook_type shmem_startup_hook = NULL;
      32              : 
      33              : static Size total_addin_request = 0;
      34              : 
      35              : /*
      36              :  * RequestAddinShmemSpace
      37              :  *      Request that extra shmem space be allocated for use by
      38              :  *      a loadable module.
      39              :  *
      40              :  * This may only be called via the shmem_request_hook of a library that is
      41              :  * loaded into the postmaster via shared_preload_libraries.  Calls from
      42              :  * elsewhere will fail.
      43              :  */
      44              : void
      45            0 : RequestAddinShmemSpace(Size size)
      46              : {
      47            0 :     if (!process_shmem_requests_in_progress)
      48            0 :         elog(FATAL, "cannot request additional shared memory outside shmem_request_hook");
      49            0 :     total_addin_request = add_size(total_addin_request, size);
      50            0 : }
      51              : 
      52              : /*
      53              :  * CalculateShmemSize
      54              :  *      Calculates the amount of shared memory needed.
      55              :  */
      56              : Size
      57         2291 : CalculateShmemSize(void)
      58              : {
      59              :     Size        size;
      60              : 
      61              :     /*
      62              :      * Size of the Postgres shared-memory block is estimated via moderately-
      63              :      * accurate estimates for the big hogs, plus 100K for the stuff that's too
      64              :      * small to bother with estimating.
      65              :      *
      66              :      * We take some care to ensure that the total size request doesn't
      67              :      * overflow size_t.  If this gets through, we don't need to be so careful
      68              :      * during the actual allocation phase.
      69              :      */
      70         2291 :     size = 100000;
      71         2291 :     size = add_size(size, ShmemGetRequestedSize());
      72              : 
      73              :     /* include additional requested shmem from preload libraries */
      74         2291 :     size = add_size(size, total_addin_request);
      75              : 
      76              :     /* might as well round it off to a multiple of a typical page size */
      77         2291 :     size = add_size(size, 8192 - (size % 8192));
      78              : 
      79         2291 :     return size;
      80              : }
      81              : 
      82              : #ifdef EXEC_BACKEND
      83              : /*
      84              :  * AttachSharedMemoryStructs
      85              :  *      Initialize a postmaster child process's access to shared memory
      86              :  *      structures.
      87              :  *
      88              :  * In !EXEC_BACKEND mode, we inherit everything through the fork, and this
      89              :  * isn't needed.
      90              :  */
      91              : void
      92              : AttachSharedMemoryStructs(void)
      93              : {
      94              :     /* InitProcess must've been called already */
      95              :     Assert(MyProc != NULL);
      96              :     Assert(IsUnderPostmaster);
      97              : 
      98              :     /*
      99              :      * In EXEC_BACKEND mode, backends don't inherit the number of fast-path
     100              :      * groups we calculated before setting the shmem up, so recalculate it.
     101              :      */
     102              :     InitializeFastPathLocks();
     103              : 
     104              :     /* Establish pointers to all shared memory areas in this backend */
     105              :     ShmemAttachRequested();
     106              : 
     107              :     /*
     108              :      * Now give loadable modules a chance to set up their shmem allocations
     109              :      */
     110              :     if (shmem_startup_hook)
     111              :         shmem_startup_hook();
     112              : }
     113              : #endif
     114              : 
     115              : /*
     116              :  * CreateSharedMemoryAndSemaphores
     117              :  *      Creates and initializes shared memory and semaphores.
     118              :  */
     119              : void
     120         1233 : CreateSharedMemoryAndSemaphores(void)
     121              : {
     122              :     PGShmemHeader *shim;
     123              :     PGShmemHeader *seghdr;
     124              :     Size        size;
     125              : 
     126              :     Assert(!IsUnderPostmaster);
     127              : 
     128              :     /* Compute the size of the shared-memory block */
     129         1233 :     size = CalculateShmemSize();
     130         1233 :     elog(DEBUG3, "invoking IpcMemoryCreate(size=%zu)", size);
     131              : 
     132              :     /*
     133              :      * Create the shmem segment
     134              :      */
     135         1233 :     seghdr = PGSharedMemoryCreate(size, &shim);
     136              : 
     137              :     /*
     138              :      * Make sure that huge pages are never reported as "unknown" while the
     139              :      * server is running.
     140              :      */
     141              :     Assert(strcmp("unknown",
     142              :                   GetConfigOption("huge_pages_status", false, false)) != 0);
     143              : 
     144              :     /*
     145              :      * Set up shared memory allocation mechanism
     146              :      */
     147         1231 :     InitShmemAllocator(seghdr);
     148              : 
     149              :     /* Initialize all shmem areas */
     150         1231 :     ShmemInitRequested();
     151              : 
     152              :     /* Initialize dynamic shared memory facilities. */
     153         1231 :     dsm_postmaster_startup(shim);
     154              : 
     155              :     /*
     156              :      * Now give loadable modules a chance to set up their shmem allocations
     157              :      */
     158         1231 :     if (shmem_startup_hook)
     159            0 :         shmem_startup_hook();
     160         1231 : }
     161              : 
     162              : /*
     163              :  * Early initialization of various subsystems, giving them a chance to
     164              :  * register their shared memory needs before the shared memory segment is
     165              :  * allocated.
     166              :  */
     167              : void
     168         1242 : RegisterBuiltinShmemCallbacks(void)
     169              : {
     170              :     /*
     171              :      * Call RegisterShmemCallbacks(...) on each subsystem listed in
     172              :      * subsystemslist.h
     173              :      */
     174              : #define PG_SHMEM_SUBSYSTEM(subsystem_callbacks) \
     175              :     RegisterShmemCallbacks(&(subsystem_callbacks));
     176              : 
     177              : #include "storage/subsystemlist.h"
     178              : 
     179              : #undef PG_SHMEM_SUBSYSTEM
     180         1242 : }
     181              : 
     182              : /*
     183              :  * InitializeShmemGUCs
     184              :  *
     185              :  * This function initializes runtime-computed GUCs related to the amount of
     186              :  * shared memory required for the current configuration.
     187              :  */
     188              : void
     189         1058 : InitializeShmemGUCs(void)
     190              : {
     191              :     char        buf[64];
     192              :     Size        size_b;
     193              :     Size        size_mb;
     194              :     Size        hp_size;
     195              : 
     196              :     /*
     197              :      * Calculate the shared memory size and round up to the nearest megabyte.
     198              :      */
     199         1058 :     size_b = CalculateShmemSize();
     200         1058 :     size_mb = add_size(size_b, (1024 * 1024) - 1) / (1024 * 1024);
     201         1058 :     sprintf(buf, "%zu", size_mb);
     202         1058 :     SetConfigOption("shared_memory_size", buf,
     203              :                     PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);
     204              : 
     205              :     /*
     206              :      * Calculate the number of huge pages required.
     207              :      */
     208         1058 :     GetHugePageSize(&hp_size, NULL);
     209         1058 :     if (hp_size != 0)
     210              :     {
     211              :         Size        hp_required;
     212              : 
     213         1058 :         hp_required = size_b / hp_size;
     214         1058 :         if (size_b % hp_size != 0)
     215         1056 :             hp_required = add_size(hp_required, 1);
     216         1058 :         sprintf(buf, "%zu", hp_required);
     217         1058 :         SetConfigOption("shared_memory_size_in_huge_pages", buf,
     218              :                         PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);
     219              :     }
     220              : 
     221         1058 :     sprintf(buf, "%d", ProcGlobalSemas());
     222         1058 :     SetConfigOption("num_os_semaphores", buf, PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);
     223         1058 : }
        

Generated by: LCOV version 2.0-1