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 100 K 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" , false , false )) != 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
2026-08-25
Neuigkeiten
Aktuelles
Motto des Tages
Open Source Software
Jenseits des Üblichen ....
Besucherstatistik
Statistik
#Sources=141584
#Domains=752002