LCOV - code coverage report
Current view: top level - src/backend/storage/ipc - ipci.c (source / functions) Hit Total Coverage
Test: PostgreSQL 14devel Lines: 86 88 97.7 %
Date: 2020-11-27 11:06:40 Functions: 2 2 100.0 %
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-2020, 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 "access/clog.h"
      18             : #include "access/commit_ts.h"
      19             : #include "access/heapam.h"
      20             : #include "access/multixact.h"
      21             : #include "access/nbtree.h"
      22             : #include "access/subtrans.h"
      23             : #include "access/syncscan.h"
      24             : #include "access/twophase.h"
      25             : #include "commands/async.h"
      26             : #include "miscadmin.h"
      27             : #include "pgstat.h"
      28             : #include "postmaster/autovacuum.h"
      29             : #include "postmaster/bgworker_internals.h"
      30             : #include "postmaster/bgwriter.h"
      31             : #include "postmaster/postmaster.h"
      32             : #include "replication/logicallauncher.h"
      33             : #include "replication/origin.h"
      34             : #include "replication/slot.h"
      35             : #include "replication/walreceiver.h"
      36             : #include "replication/walsender.h"
      37             : #include "storage/bufmgr.h"
      38             : #include "storage/dsm.h"
      39             : #include "storage/ipc.h"
      40             : #include "storage/pg_shmem.h"
      41             : #include "storage/pmsignal.h"
      42             : #include "storage/predicate.h"
      43             : #include "storage/proc.h"
      44             : #include "storage/procarray.h"
      45             : #include "storage/procsignal.h"
      46             : #include "storage/sinvaladt.h"
      47             : #include "storage/spin.h"
      48             : #include "utils/snapmgr.h"
      49             : 
      50             : /* GUCs */
      51             : int         shared_memory_type = DEFAULT_SHARED_MEMORY_TYPE;
      52             : 
      53             : shmem_startup_hook_type shmem_startup_hook = NULL;
      54             : 
      55             : static Size total_addin_request = 0;
      56             : static bool addin_request_allowed = true;
      57             : 
      58             : 
      59             : /*
      60             :  * RequestAddinShmemSpace
      61             :  *      Request that extra shmem space be allocated for use by
      62             :  *      a loadable module.
      63             :  *
      64             :  * This is only useful if called from the _PG_init hook of a library that
      65             :  * is loaded into the postmaster via shared_preload_libraries.  Once
      66             :  * shared memory has been allocated, calls will be ignored.  (We could
      67             :  * raise an error, but it seems better to make it a no-op, so that
      68             :  * libraries containing such calls can be reloaded if needed.)
      69             :  */
      70             : void
      71           2 : RequestAddinShmemSpace(Size size)
      72             : {
      73           2 :     if (IsUnderPostmaster || !addin_request_allowed)
      74           0 :         return;                 /* too late */
      75           2 :     total_addin_request = add_size(total_addin_request, size);
      76             : }
      77             : 
      78             : 
      79             : /*
      80             :  * CreateSharedMemoryAndSemaphores
      81             :  *      Creates and initializes shared memory and semaphores.
      82             :  *
      83             :  * This is called by the postmaster or by a standalone backend.
      84             :  * It is also called by a backend forked from the postmaster in the
      85             :  * EXEC_BACKEND case.  In the latter case, the shared memory segment
      86             :  * already exists and has been physically attached to, but we have to
      87             :  * initialize pointers in local memory that reference the shared structures,
      88             :  * because we didn't inherit the correct pointer values from the postmaster
      89             :  * as we do in the fork() scenario.  The easiest way to do that is to run
      90             :  * through the same code as before.  (Note that the called routines mostly
      91             :  * check IsUnderPostmaster, rather than EXEC_BACKEND, to detect this case.
      92             :  * This is a bit code-wasteful and could be cleaned up.)
      93             :  */
      94             : void
      95        2376 : CreateSharedMemoryAndSemaphores(void)
      96             : {
      97        2376 :     PGShmemHeader *shim = NULL;
      98             : 
      99        2376 :     if (!IsUnderPostmaster)
     100             :     {
     101             :         PGShmemHeader *seghdr;
     102             :         Size        size;
     103             :         int         numSemas;
     104             : 
     105             :         /* Compute number of semaphores we'll need */
     106        2376 :         numSemas = ProcGlobalSemas();
     107        2376 :         numSemas += SpinlockSemas();
     108             : 
     109             :         /*
     110             :          * Size of the Postgres shared-memory block is estimated via
     111             :          * moderately-accurate estimates for the big hogs, plus 100K for the
     112             :          * stuff that's too small to bother with estimating.
     113             :          *
     114             :          * We take some care during this phase to ensure that the total size
     115             :          * request doesn't overflow size_t.  If this gets through, we don't
     116             :          * need to be so careful during the actual allocation phase.
     117             :          */
     118        2376 :         size = 100000;
     119        2376 :         size = add_size(size, PGSemaphoreShmemSize(numSemas));
     120        2376 :         size = add_size(size, SpinlockSemaSize());
     121        2376 :         size = add_size(size, hash_estimate_size(SHMEM_INDEX_SIZE,
     122             :                                                  sizeof(ShmemIndexEnt)));
     123        2376 :         size = add_size(size, dsm_estimate_size());
     124        2376 :         size = add_size(size, BufferShmemSize());
     125        2376 :         size = add_size(size, LockShmemSize());
     126        2376 :         size = add_size(size, PredicateLockShmemSize());
     127        2376 :         size = add_size(size, ProcGlobalShmemSize());
     128        2376 :         size = add_size(size, XLOGShmemSize());
     129        2376 :         size = add_size(size, CLOGShmemSize());
     130        2376 :         size = add_size(size, CommitTsShmemSize());
     131        2376 :         size = add_size(size, SUBTRANSShmemSize());
     132        2376 :         size = add_size(size, TwoPhaseShmemSize());
     133        2376 :         size = add_size(size, BackgroundWorkerShmemSize());
     134        2376 :         size = add_size(size, MultiXactShmemSize());
     135        2376 :         size = add_size(size, LWLockShmemSize());
     136        2376 :         size = add_size(size, ProcArrayShmemSize());
     137        2376 :         size = add_size(size, BackendStatusShmemSize());
     138        2376 :         size = add_size(size, SInvalShmemSize());
     139        2376 :         size = add_size(size, PMSignalShmemSize());
     140        2376 :         size = add_size(size, ProcSignalShmemSize());
     141        2376 :         size = add_size(size, CheckpointerShmemSize());
     142        2376 :         size = add_size(size, AutoVacuumShmemSize());
     143        2376 :         size = add_size(size, ReplicationSlotsShmemSize());
     144        2376 :         size = add_size(size, ReplicationOriginShmemSize());
     145        2376 :         size = add_size(size, WalSndShmemSize());
     146        2376 :         size = add_size(size, WalRcvShmemSize());
     147        2376 :         size = add_size(size, ApplyLauncherShmemSize());
     148        2376 :         size = add_size(size, SnapMgrShmemSize());
     149        2376 :         size = add_size(size, BTreeShmemSize());
     150        2376 :         size = add_size(size, SyncScanShmemSize());
     151        2376 :         size = add_size(size, AsyncShmemSize());
     152             : #ifdef EXEC_BACKEND
     153             :         size = add_size(size, ShmemBackendArraySize());
     154             : #endif
     155             : 
     156             :         /* freeze the addin request size and include it */
     157        2376 :         addin_request_allowed = false;
     158        2376 :         size = add_size(size, total_addin_request);
     159             : 
     160             :         /* might as well round it off to a multiple of a typical page size */
     161        2376 :         size = add_size(size, 8192 - (size % 8192));
     162             : 
     163        2376 :         elog(DEBUG3, "invoking IpcMemoryCreate(size=%zu)", size);
     164             : 
     165             :         /*
     166             :          * Create the shmem segment
     167             :          */
     168        2376 :         seghdr = PGSharedMemoryCreate(size, &shim);
     169             : 
     170        2372 :         InitShmemAccess(seghdr);
     171             : 
     172             :         /*
     173             :          * Create semaphores
     174             :          */
     175        2372 :         PGReserveSemaphores(numSemas);
     176             : 
     177             :         /*
     178             :          * If spinlocks are disabled, initialize emulation layer (which
     179             :          * depends on semaphores, so the order is important here).
     180             :          */
     181             : #ifndef HAVE_SPINLOCKS
     182             :         SpinlockSemaInit();
     183             : #endif
     184             :     }
     185             :     else
     186             :     {
     187             :         /*
     188             :          * We are reattaching to an existing shared memory segment. This
     189             :          * should only be reached in the EXEC_BACKEND case.
     190             :          */
     191             : #ifndef EXEC_BACKEND
     192           0 :         elog(PANIC, "should be attached to shared memory already");
     193             : #endif
     194             :     }
     195             : 
     196             :     /*
     197             :      * Set up shared memory allocation mechanism
     198             :      */
     199        2372 :     if (!IsUnderPostmaster)
     200        2372 :         InitShmemAllocation();
     201             : 
     202             :     /*
     203             :      * Now initialize LWLocks, which do shared memory allocation and are
     204             :      * needed for InitShmemIndex.
     205             :      */
     206        2372 :     CreateLWLocks();
     207             : 
     208             :     /*
     209             :      * Set up shmem.c index hashtable
     210             :      */
     211        2372 :     InitShmemIndex();
     212             : 
     213        2372 :     dsm_shmem_init();
     214             : 
     215             :     /*
     216             :      * Set up xlog, clog, and buffers
     217             :      */
     218        2372 :     XLOGShmemInit();
     219        2372 :     CLOGShmemInit();
     220        2372 :     CommitTsShmemInit();
     221        2372 :     SUBTRANSShmemInit();
     222        2372 :     MultiXactShmemInit();
     223        2372 :     InitBufferPool();
     224             : 
     225             :     /*
     226             :      * Set up lock manager
     227             :      */
     228        2372 :     InitLocks();
     229             : 
     230             :     /*
     231             :      * Set up predicate lock manager
     232             :      */
     233        2372 :     InitPredicateLocks();
     234             : 
     235             :     /*
     236             :      * Set up process table
     237             :      */
     238        2372 :     if (!IsUnderPostmaster)
     239        2372 :         InitProcGlobal();
     240        2372 :     CreateSharedProcArray();
     241        2372 :     CreateSharedBackendStatus();
     242        2372 :     TwoPhaseShmemInit();
     243        2372 :     BackgroundWorkerShmemInit();
     244             : 
     245             :     /*
     246             :      * Set up shared-inval messaging
     247             :      */
     248        2372 :     CreateSharedInvalidationState();
     249             : 
     250             :     /*
     251             :      * Set up interprocess signaling mechanisms
     252             :      */
     253        2372 :     PMSignalShmemInit();
     254        2372 :     ProcSignalShmemInit();
     255        2372 :     CheckpointerShmemInit();
     256        2372 :     AutoVacuumShmemInit();
     257        2372 :     ReplicationSlotsShmemInit();
     258        2372 :     ReplicationOriginShmemInit();
     259        2372 :     WalSndShmemInit();
     260        2372 :     WalRcvShmemInit();
     261        2372 :     ApplyLauncherShmemInit();
     262             : 
     263             :     /*
     264             :      * Set up other modules that need some shared memory space
     265             :      */
     266        2372 :     SnapMgrInit();
     267        2372 :     BTreeShmemInit();
     268        2372 :     SyncScanShmemInit();
     269        2372 :     AsyncShmemInit();
     270             : 
     271             : #ifdef EXEC_BACKEND
     272             : 
     273             :     /*
     274             :      * Alloc the win32 shared backend array
     275             :      */
     276             :     if (!IsUnderPostmaster)
     277             :         ShmemBackendArrayAllocation();
     278             : #endif
     279             : 
     280             :     /* Initialize dynamic shared memory facilities. */
     281        2372 :     if (!IsUnderPostmaster)
     282        2372 :         dsm_postmaster_startup(shim);
     283             : 
     284             :     /*
     285             :      * Now give loadable modules a chance to set up their shmem allocations
     286             :      */
     287        2372 :     if (shmem_startup_hook)
     288           2 :         shmem_startup_hook();
     289        2372 : }

Generated by: LCOV version 1.13