Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  ipci.c

  Sprache: C
 

/*-------------------------------------------------------------------------
 *
 * ipci.c
 *   POSTGRES inter-process communication initialization code.
 *
 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *   src/backend/storage/ipc/ipci.c
 *
 *-------------------------------------------------------------------------
 */

#include "postgres.h"

#include "access/clog.h"
#include "access/commit_ts.h"
#include "access/multixact.h"
#include "access/nbtree.h"
#include "access/subtrans.h"
#include "access/syncscan.h"
#include "access/transam.h"
#include "access/twophase.h"
#include "access/xlogprefetcher.h"
#include "access/xlogrecovery.h"
#include "commands/async.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "postmaster/autovacuum.h"
#include "postmaster/bgworker_internals.h"
#include "postmaster/bgwriter.h"
#include "postmaster/walsummarizer.h"
#include "replication/logicallauncher.h"
#include "replication/origin.h"
#include "replication/slot.h"
#include "replication/slotsync.h"
#include "replication/walreceiver.h"
#include "replication/walsender.h"
#include "storage/aio_subsys.h"
#include "storage/bufmgr.h"
#include "storage/dsm.h"
#include "storage/dsm_registry.h"
#include "storage/ipc.h"
#include "storage/pg_shmem.h"
#include "storage/pmsignal.h"
#include "storage/predicate.h"
#include "storage/proc.h"
#include "storage/procarray.h"
#include "storage/procsignal.h"
#include "storage/sinvaladt.h"
#include "utils/guc.h"
#include "utils/injection_point.h"

/* GUCs */
int   shared_memory_type = DEFAULT_SHARED_MEMORY_TYPE;

shmem_startup_hook_type shmem_startup_hook = NULL;

static Size total_addin_request = 0;

static void CreateOrAttachShmemStructs(void);

/*
 * RequestAddinShmemSpace
 *  Request that extra shmem space be allocated for use by
 *  a loadable module.
 *
 * This may only be called via the shmem_request_hook of a library that is
 * loaded into the postmaster via shared_preload_libraries.  Calls from
 * elsewhere will fail.
 */

void
RequestAddinShmemSpace(Size size)
{
 if (!process_shmem_requests_in_progress)
  elog(FATAL, "cannot request additional shared memory outside shmem_request_hook");
 total_addin_request = add_size(total_addin_request, size);
}

/*
 * CalculateShmemSize
 *  Calculates the amount of shared memory and number of semaphores needed.
 *
 * If num_semaphores is not NULL, it will be set to the number of semaphores
 * required.
 */

Size
CalculateShmemSize(int *num_semaphores)
{
 Size  size;
 int   numSemas;

 /* Compute number of semaphores we'll need */
 numSemas = ProcGlobalSemas();

 /* Return the number of semaphores if requested by the caller */
 if (num_semaphores)
  *num_semaphores = numSemas;

 /*
  * Size of the Postgres shared-memory block is estimated via moderately-
  * accurate estimates for the big hogs, plus 100K for the stuff that's too
  * small to bother with estimating.
  *
  * We take some care to ensure that the total size request doesn't
  * overflow size_t.  If this gets through, we don't need to be so careful
  * during the actual allocation phase.
 */

 size = 100000;
 size = add_size(size, PGSemaphoreShmemSize(numSemas));
 size = add_size(size, hash_estimate_size(SHMEM_INDEX_SIZE,
            sizeof(ShmemIndexEnt)));
 size = add_size(size, dsm_estimate_size());
 size = add_size(size, DSMRegistryShmemSize());
 size = add_size(size, BufferManagerShmemSize());
 size = add_size(size, LockManagerShmemSize());
 size = add_size(size, PredicateLockShmemSize());
 size = add_size(size, ProcGlobalShmemSize());
 size = add_size(size, XLogPrefetchShmemSize());
 size = add_size(size, VarsupShmemSize());
 size = add_size(size, XLOGShmemSize());
 size = add_size(size, XLogRecoveryShmemSize());
 size = add_size(size, CLOGShmemSize());
 size = add_size(size, CommitTsShmemSize());
 size = add_size(size, SUBTRANSShmemSize());
 size = add_size(size, TwoPhaseShmemSize());
 size = add_size(size, BackgroundWorkerShmemSize());
 size = add_size(size, MultiXactShmemSize());
 size = add_size(size, LWLockShmemSize());
 size = add_size(size, ProcArrayShmemSize());
 size = add_size(size, BackendStatusShmemSize());
 size = add_size(size, SharedInvalShmemSize());
 size = add_size(size, PMSignalShmemSize());
 size = add_size(size, ProcSignalShmemSize());
 size = add_size(size, CheckpointerShmemSize());
 size = add_size(size, AutoVacuumShmemSize());
 size = add_size(size, ReplicationSlotsShmemSize());
 size = add_size(size, ReplicationOriginShmemSize());
 size = add_size(size, WalSndShmemSize());
 size = add_size(size, WalRcvShmemSize());
 size = add_size(size, WalSummarizerShmemSize());
 size = add_size(size, PgArchShmemSize());
 size = add_size(size, ApplyLauncherShmemSize());
 size = add_size(size, BTreeShmemSize());
 size = add_size(size, SyncScanShmemSize());
 size = add_size(size, AsyncShmemSize());
 size = add_size(size, StatsShmemSize());
 size = add_size(size, WaitEventCustomShmemSize());
 size = add_size(size, InjectionPointShmemSize());
 size = add_size(size, SlotSyncShmemSize());
 size = add_size(size, AioShmemSize());

 /* include additional requested shmem from preload libraries */
 size = add_size(size, total_addin_request);

 /* might as well round it off to a multiple of a typical page size */
 size = add_size(size, 8192 - (size % 8192));

 return size;
}

#ifdef EXEC_BACKEND
/*
 * AttachSharedMemoryStructs
 *  Initialize a postmaster child process's access to shared memory
 *      structures.
 *
 * In !EXEC_BACKEND mode, we inherit everything through the fork, and this
 * isn't needed.
 */

void
AttachSharedMemoryStructs(void)
{
 /* InitProcess must've been called already */
 Assert(MyProc != NULL);
 Assert(IsUnderPostmaster);

 /*
  * In EXEC_BACKEND mode, backends don't inherit the number of fast-path
  * groups we calculated before setting the shmem up, so recalculate it.
 */

 InitializeFastPathLocks();

 CreateOrAttachShmemStructs();

 /*
  * Now give loadable modules a chance to set up their shmem allocations
 */

 if (shmem_startup_hook)
  shmem_startup_hook();
}
#endif

/*
 * CreateSharedMemoryAndSemaphores
 *  Creates and initializes shared memory and semaphores.
 */

void
CreateSharedMemoryAndSemaphores(void)
{
 PGShmemHeader *shim;
 PGShmemHeader *seghdr;
 Size  size;
 int   numSemas;

 Assert(!IsUnderPostmaster);

 /* Compute the size of the shared-memory block */
 size = CalculateShmemSize(&numSemas);
 elog(DEBUG3, "invoking IpcMemoryCreate(size=%zu)", size);

 /*
  * Create the shmem segment
 */

 seghdr = PGSharedMemoryCreate(size, &shim);

 /*
  * Make sure that huge pages are never reported as "unknown" while the
  * server is running.
 */

 Assert(strcmp("unknown",
      GetConfigOption("huge_pages_status"falsefalse)) != 0);

 InitShmemAccess(seghdr);

 /*
  * Create semaphores.  (This is done here for historical reasons.  We used
  * to support emulating spinlocks with semaphores, which required
  * initializing semaphores early.)
 */

 PGReserveSemaphores(numSemas);

 /*
  * Set up shared memory allocation mechanism
 */

 InitShmemAllocation();

 /* Initialize subsystems */
 CreateOrAttachShmemStructs();

 /* Initialize dynamic shared memory facilities. */
 dsm_postmaster_startup(shim);

 /*
  * Now give loadable modules a chance to set up their shmem allocations
 */

 if (shmem_startup_hook)
  shmem_startup_hook();
}

/*
 * Initialize various subsystems, setting up their data structures in
 * shared memory.
 *
 * This is called by the postmaster or by a standalone backend.
 * It is also called by a backend forked from the postmaster in the
 * EXEC_BACKEND case.  In the latter case, the shared memory segment
 * already exists and has been physically attached to, but we have to
 * initialize pointers in local memory that reference the shared structures,
 * because we didn't inherit the correct pointer values from the postmaster
 * as we do in the fork() scenario.  The easiest way to do that is to run
 * through the same code as before.  (Note that the called routines mostly
 * check IsUnderPostmaster, rather than EXEC_BACKEND, to detect this case.
 * This is a bit code-wasteful and could be cleaned up.)
 */

static void
CreateOrAttachShmemStructs(void)
{
 /*
  * Now initialize LWLocks, which do shared memory allocation and are
  * needed for InitShmemIndex.
 */

 CreateLWLocks();

 /*
  * Set up shmem.c index hashtable
 */

 InitShmemIndex();

 dsm_shmem_init();
 DSMRegistryShmemInit();

 /*
  * Set up xlog, clog, and buffers
 */

 VarsupShmemInit();
 XLOGShmemInit();
 XLogPrefetchShmemInit();
 XLogRecoveryShmemInit();
 CLOGShmemInit();
 CommitTsShmemInit();
 SUBTRANSShmemInit();
 MultiXactShmemInit();
 BufferManagerShmemInit();

 /*
  * Set up lock manager
 */

 LockManagerShmemInit();

 /*
  * Set up predicate lock manager
 */

 PredicateLockShmemInit();

 /*
  * Set up process table
 */

 if (!IsUnderPostmaster)
  InitProcGlobal();
 ProcArrayShmemInit();
 BackendStatusShmemInit();
 TwoPhaseShmemInit();
 BackgroundWorkerShmemInit();

 /*
  * Set up shared-inval messaging
 */

 SharedInvalShmemInit();

 /*
  * Set up interprocess signaling mechanisms
 */

 PMSignalShmemInit();
 ProcSignalShmemInit();
 CheckpointerShmemInit();
 AutoVacuumShmemInit();
 ReplicationSlotsShmemInit();
 ReplicationOriginShmemInit();
 WalSndShmemInit();
 WalRcvShmemInit();
 WalSummarizerShmemInit();
 PgArchShmemInit();
 ApplyLauncherShmemInit();
 SlotSyncShmemInit();

 /*
  * Set up other modules that need some shared memory space
 */

 BTreeShmemInit();
 SyncScanShmemInit();
 AsyncShmemInit();
 StatsShmemInit();
 WaitEventCustomShmemInit();
 InjectionPointShmemInit();
 AioShmemInit();
}

/*
 * InitializeShmemGUCs
 *
 * This function initializes runtime-computed GUCs related to the amount of
 * shared memory required for the current configuration.
 */

void
InitializeShmemGUCs(void)
{
 char  buf[64];
 Size  size_b;
 Size  size_mb;
 Size  hp_size;
 int   num_semas;

 /*
  * Calculate the shared memory size and round up to the nearest megabyte.
 */

 size_b = CalculateShmemSize(&num_semas);
 size_mb = add_size(size_b, (1024 * 1024) - 1) / (1024 * 1024);
 sprintf(buf, "%zu", size_mb);
 SetConfigOption("shared_memory_size", buf,
     PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);

 /*
  * Calculate the number of huge pages required.
 */

 GetHugePageSize(&hp_size, NULL);
 if (hp_size != 0)
 {
  Size  hp_required;

  hp_required = add_size(size_b / hp_size, 1);
  sprintf(buf, "%zu", hp_required);
  SetConfigOption("shared_memory_size_in_huge_pages", buf,
      PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);
 }

 sprintf(buf, "%d", num_semas);
 SetConfigOption("num_os_semaphores", buf, PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);
}

Messung V0.5 in Prozent
C=93 H=90 G=91

¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet am  2026-08-08) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=141584
#Domains=752002