From 8dc7d0df8589b39d791e6ec2418b0dbafcb490b6 Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Sat, 21 Mar 2026 19:06:04 +0200 Subject: [PATCH v7 14/18] Use the new mechanism in a few core subsystems I chose these subsystems specifically because they have some complicating properties, making them slightly harder to convert than most: - The initialization callbacks of some of these subsystems have dependencies, i.e. they need to be initialized in the right order. - The ProgGlobal pointer still needs to be inherited by the BackendParameters mechanism on EXEC_BACKEND builds, because ProcGlobal is required by InitProcess() to get a PGPROC entry, and the PGPROC entry is required to use LWLocks, and usually attaching to shared memory areas requires the use of LWLocks. - Similarly, ProcSignal pointer still needs to be handled by BackendParameters, because query cancellation connections access it without calling InitProcess I'm believe converting all the rest of the subsystems after this will be pretty mechanic. Reviewed-by: Ashutosh Bapat Reviewed-by: Zsolt Parragi Discussion: https://www.postgresql.org/message-id/CAExHW5vM1bneLYfg0wGeAa=52UiJ3z4vKd3AJ72X8Fw6k3KKrg@mail.gmail.com --- src/backend/access/transam/varsup.c | 36 ++--- src/backend/access/transam/xlog.c | 1 + src/backend/postmaster/launch_backend.c | 2 + src/backend/storage/ipc/dsm.c | 66 +++++---- src/backend/storage/ipc/dsm_registry.c | 39 +++--- src/backend/storage/ipc/ipci.c | 33 +---- src/backend/storage/ipc/pmsignal.c | 52 +++---- src/backend/storage/ipc/procarray.c | 126 +++++++++-------- src/backend/storage/ipc/procsignal.c | 67 ++++----- src/backend/storage/ipc/shmem.c | 32 +++-- src/backend/storage/ipc/sinvaladt.c | 41 +++--- src/backend/storage/lmgr/proc.c | 179 ++++++++++++------------ src/backend/utils/activity/wait_event.c | 97 +++++++------ src/include/access/transam.h | 2 - src/include/storage/dsm.h | 3 - src/include/storage/dsm_registry.h | 2 - src/include/storage/pmsignal.h | 2 - src/include/storage/proc.h | 1 - src/include/storage/procarray.h | 2 - src/include/storage/procsignal.h | 3 - src/include/storage/sinvaladt.h | 2 - src/include/storage/subsystemlist.h | 19 +++ src/include/utils/wait_event.h | 4 +- 23 files changed, 410 insertions(+), 401 deletions(-) diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 1441a051773..91f95816bb8 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -23,6 +23,7 @@ #include "postmaster/autovacuum.h" #include "storage/pmsignal.h" #include "storage/proc.h" +#include "storage/subsystems.h" #include "utils/lsyscache.h" #include "utils/syscache.h" @@ -30,35 +31,28 @@ /* Number of OIDs to prefetch (preallocate) per XLOG write */ #define VAR_OID_PREFETCH 8192 +static void VarsupShmemRequest(void *arg); + /* pointer to variables struct in shared memory */ TransamVariablesData *TransamVariables = NULL; +const ShmemCallbacks VarsupShmemCallbacks = { + .request_fn = VarsupShmemRequest, +}; /* - * Initialization of shared memory for TransamVariables. + * Request shared memory for TransamVariables. */ -Size -VarsupShmemSize(void) -{ - return sizeof(TransamVariablesData); -} - -void -VarsupShmemInit(void) +static void +VarsupShmemRequest(void *arg) { - bool found; + static ShmemStructDesc TransamVariablesShmemDesc = { + .name = "TransamVariables", + .size = sizeof(TransamVariablesData), + .ptr = (void **) &TransamVariables, + }; - /* Initialize our shared state struct */ - TransamVariables = ShmemInitStruct("TransamVariables", - sizeof(TransamVariablesData), - &found); - if (!IsUnderPostmaster) - { - Assert(!found); - memset(TransamVariables, 0, sizeof(TransamVariablesData)); - } - else - Assert(found); + ShmemRequestStruct(&TransamVariablesShmemDesc); } /* diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index f5c9a34374d..35d9a09f5da 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -5648,6 +5648,7 @@ StartupXLOG(void) checkPoint = ControlFile->checkPointCopy; /* initialize shared memory variables from the checkpoint record */ + Assert(TransamVariables); TransamVariables->nextXid = checkPoint.nextXid; TransamVariables->nextOid = checkPoint.nextOid; TransamVariables->oidCount = 0; diff --git a/src/backend/postmaster/launch_backend.c b/src/backend/postmaster/launch_backend.c index 0e4c00cfb39..b9d670d84b4 100644 --- a/src/backend/postmaster/launch_backend.c +++ b/src/backend/postmaster/launch_backend.c @@ -668,6 +668,8 @@ SubPostmasterMain(int argc, char *argv[]) */ LocalProcessControlFile(false); + RegisterBuiltinShmemCallbacks(); + /* * Reload any libraries that were preloaded by the postmaster. Since we * exec'd this process, those libraries didn't come along with us; but we diff --git a/src/backend/storage/ipc/dsm.c b/src/backend/storage/ipc/dsm.c index 6a5b16392f7..048bfbc4a1d 100644 --- a/src/backend/storage/ipc/dsm.c +++ b/src/backend/storage/ipc/dsm.c @@ -43,6 +43,7 @@ #include "storage/lwlock.h" #include "storage/pg_shmem.h" #include "storage/shmem.h" +#include "storage/subsystems.h" #include "utils/freepage.h" #include "utils/memutils.h" #include "utils/resowner.h" @@ -110,6 +111,14 @@ static bool dsm_init_done = false; /* Preallocated DSM space in the main shared memory region. */ static void *dsm_main_space_begin = NULL; +static void dsm_main_space_request(void *arg); +static void dsm_main_space_init(void *arg); + +const ShmemCallbacks dsm_shmem_callbacks = { + .request_fn = dsm_main_space_request, + .init_fn = dsm_main_space_init, +}; + /* * List of dynamic shared memory segments used by this backend. * @@ -463,43 +472,46 @@ dsm_set_control_handle(dsm_handle h) } #endif +static ShmemStructDesc dsm_main_space_shmem_desc = { + .name = "Preallocated DSM", + .size = 0, /* calculated later */ + .ptr = &dsm_main_space_begin, +}; + /* - * Reserve some space in the main shared memory segment for DSM segments. + * Reserve space in the main shared memory segment for DSM segments. */ -size_t -dsm_estimate_size(void) +static void +dsm_main_space_request(void *arg) { - return 1024 * 1024 * (size_t) min_dynamic_shared_memory; + size_t size = 1024 * 1024 * (size_t) min_dynamic_shared_memory; + + if (size == 0) + return; + + dsm_main_space_shmem_desc.size = size; + ShmemRequestStruct(&dsm_main_space_shmem_desc); } -/* - * Initialize space in the main shared memory segment for DSM segments. - */ -void -dsm_shmem_init(void) +static void +dsm_main_space_init(void *arg) { - size_t size = dsm_estimate_size(); - bool found; + size_t size = dsm_main_space_shmem_desc.size; + FreePageManager *fpm = (FreePageManager *) dsm_main_space_begin; + size_t first_page = 0; + size_t pages; if (size == 0) return; - dsm_main_space_begin = ShmemInitStruct("Preallocated DSM", size, &found); - if (!found) - { - FreePageManager *fpm = (FreePageManager *) dsm_main_space_begin; - size_t first_page = 0; - size_t pages; - - /* Reserve space for the FreePageManager. */ - while (first_page * FPM_PAGE_SIZE < sizeof(FreePageManager)) - ++first_page; - - /* Initialize it and give it all the rest of the space. */ - FreePageManagerInitialize(fpm, dsm_main_space_begin); - pages = (size / FPM_PAGE_SIZE) - first_page; - FreePageManagerPut(fpm, first_page, pages); - } + /* Reserve space for the FreePageManager. */ + while (first_page * FPM_PAGE_SIZE < sizeof(FreePageManager)) + ++first_page; + + /* Initialize it and give it all the rest of the space. */ + FreePageManagerInitialize(fpm, dsm_main_space_begin); + pages = (size / FPM_PAGE_SIZE) - first_page; + FreePageManagerPut(fpm, first_page, pages); } /* diff --git a/src/backend/storage/ipc/dsm_registry.c b/src/backend/storage/ipc/dsm_registry.c index 9bfcd616827..6f7f1f79e52 100644 --- a/src/backend/storage/ipc/dsm_registry.c +++ b/src/backend/storage/ipc/dsm_registry.c @@ -45,6 +45,7 @@ #include "storage/dsm_registry.h" #include "storage/lwlock.h" #include "storage/shmem.h" +#include "storage/subsystems.h" #include "utils/builtins.h" #include "utils/memutils.h" #include "utils/tuplestore.h" @@ -57,6 +58,14 @@ typedef struct DSMRegistryCtxStruct static DSMRegistryCtxStruct *DSMRegistryCtx; +static void DSMRegistryShmemRequest(void *arg); +static void DSMRegistryShmemInit(void *arg); + +const ShmemCallbacks DSMRegistryShmemCallbacks = { + .request_fn = DSMRegistryShmemRequest, + .init_fn = DSMRegistryShmemInit, +}; + typedef struct NamedDSMState { dsm_handle handle; @@ -114,27 +123,23 @@ static const dshash_parameters dsh_params = { static dsa_area *dsm_registry_dsa; static dshash_table *dsm_registry_table; -Size -DSMRegistryShmemSize(void) +static void +DSMRegistryShmemRequest(void *arg) { - return MAXALIGN(sizeof(DSMRegistryCtxStruct)); + static ShmemStructDesc DSMRegistryCtxShmemDesc = { + .name = "DSM Registry Data", + .size = sizeof(DSMRegistryCtxStruct), + .ptr = (void **) &DSMRegistryCtx, + }; + + ShmemRequestStruct(&DSMRegistryCtxShmemDesc); } -void -DSMRegistryShmemInit(void) +static void +DSMRegistryShmemInit(void *arg) { - bool found; - - DSMRegistryCtx = (DSMRegistryCtxStruct *) - ShmemInitStruct("DSM Registry Data", - DSMRegistryShmemSize(), - &found); - - if (!found) - { - DSMRegistryCtx->dsah = DSA_HANDLE_INVALID; - DSMRegistryCtx->dshh = DSHASH_HANDLE_INVALID; - } + DSMRegistryCtx->dsah = DSA_HANDLE_INVALID; + DSMRegistryCtx->dshh = DSHASH_HANDLE_INVALID; } /* diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c index afa7762e7dc..4295e8f16ac 100644 --- a/src/backend/storage/ipc/ipci.c +++ b/src/backend/storage/ipc/ipci.c @@ -20,7 +20,6 @@ #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" @@ -41,18 +40,13 @@ #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 "storage/subsystems.h" #include "utils/guc.h" -#include "utils/wait_event.h" /* GUCs */ int shared_memory_type = DEFAULT_SHARED_MEMORY_TYPE; @@ -102,15 +96,10 @@ CalculateShmemSize(void) size = add_size(size, ShmemGetRequestedSize()); /* legacy subsystems */ - 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()); @@ -120,11 +109,7 @@ CalculateShmemSize(void) 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()); @@ -138,7 +123,6 @@ CalculateShmemSize(void) size = add_size(size, SyncScanShmemSize()); size = add_size(size, AsyncShmemSize()); size = add_size(size, StatsShmemSize()); - size = add_size(size, WaitEventCustomShmemSize()); size = add_size(size, SlotSyncShmemSize()); size = add_size(size, AioShmemSize()); size = add_size(size, WaitLSNShmemSize()); @@ -176,7 +160,7 @@ AttachSharedMemoryStructs(void) InitializeFastPathLocks(); /* Establish pointers to all shared memory areas in this backend */ - ShmemAttachRegistered(); + ShmemAttachRequested(); CreateOrAttachShmemStructs(); /* @@ -284,13 +268,9 @@ RegisterBuiltinShmemCallbacks(void) static void CreateOrAttachShmemStructs(void) { - dsm_shmem_init(); - DSMRegistryShmemInit(); - /* * Set up xlog, clog, and buffers */ - VarsupShmemInit(); XLOGShmemInit(); XLogPrefetchShmemInit(); XLogRecoveryShmemInit(); @@ -313,23 +293,13 @@ CreateOrAttachShmemStructs(void) /* * 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(); @@ -348,7 +318,6 @@ CreateOrAttachShmemStructs(void) SyncScanShmemInit(); AsyncShmemInit(); StatsShmemInit(); - WaitEventCustomShmemInit(); AioShmemInit(); WaitLSNShmemInit(); LogicalDecodingCtlShmemInit(); diff --git a/src/backend/storage/ipc/pmsignal.c b/src/backend/storage/ipc/pmsignal.c index 4618820b337..3d21d991885 100644 --- a/src/backend/storage/ipc/pmsignal.c +++ b/src/backend/storage/ipc/pmsignal.c @@ -27,6 +27,7 @@ #include "storage/ipc.h" #include "storage/pmsignal.h" #include "storage/shmem.h" +#include "storage/subsystems.h" #include "utils/memutils.h" @@ -83,6 +84,14 @@ struct PMSignalData /* PMSignalState pointer is valid in both postmaster and child processes */ NON_EXEC_STATIC volatile PMSignalData *PMSignalState = NULL; +static void PMSignalShmemRequest(void *); +static void PMSignalShmemInit(void *); + +const ShmemCallbacks PMSignalShmemCallbacks = { + .request_fn = PMSignalShmemRequest, + .init_fn = PMSignalShmemInit, +}; + /* * Local copy of PMSignalState->num_child_flags, only valid in the * postmaster. Postmaster keeps a local copy so that it doesn't need to @@ -123,39 +132,30 @@ postmaster_death_handler(SIGNAL_ARGS) static void MarkPostmasterChildInactive(int code, Datum arg); /* - * PMSignalShmemSize - * Compute space needed for pmsignal.c's shared memory + * PMSignalShmemRequest - Register pmsignal.c's shared memory needs */ -Size -PMSignalShmemSize(void) +static void +PMSignalShmemRequest(void *arg) { - Size size; + static ShmemStructDesc PMSignalShmemDesc = { + .name = "PMSignalState", + .ptr = (void **) &PMSignalState, + }; - size = offsetof(PMSignalData, PMChildFlags); - size = add_size(size, mul_size(MaxLivePostmasterChildren(), - sizeof(sig_atomic_t))); + num_child_flags = MaxLivePostmasterChildren(); - return size; + PMSignalShmemDesc.size = + add_size(offsetof(PMSignalData, PMChildFlags), + mul_size(num_child_flags, sizeof(sig_atomic_t))); + ShmemRequestStruct(&PMSignalShmemDesc); } -/* - * PMSignalShmemInit - initialize during shared-memory creation - */ -void -PMSignalShmemInit(void) +static void +PMSignalShmemInit(void *arg) { - bool found; - - PMSignalState = (PMSignalData *) - ShmemInitStruct("PMSignalState", PMSignalShmemSize(), &found); - - if (!found) - { - /* initialize all flags to zeroes */ - MemSet(unvolatize(PMSignalData *, PMSignalState), 0, PMSignalShmemSize()); - num_child_flags = MaxLivePostmasterChildren(); - PMSignalState->num_child_flags = num_child_flags; - } + Assert(PMSignalState); + Assert(num_child_flags > 0); + PMSignalState->num_child_flags = num_child_flags; } /* diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index 0f913897acc..2e9529485f5 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -61,6 +61,7 @@ #include "storage/proc.h" #include "storage/procarray.h" #include "storage/procsignal.h" +#include "storage/subsystems.h" #include "utils/acl.h" #include "utils/builtins.h" #include "utils/injection_point.h" @@ -103,6 +104,24 @@ typedef struct ProcArrayStruct int pgprocnos[FLEXIBLE_ARRAY_MEMBER]; } ProcArrayStruct; +static void ProcArrayShmemRequest(void *arg); +static void ProcArrayShmemInit(void *arg); +static void ProcArrayShmemAttach(void *arg); + +static ProcArrayStruct *procArray; + +const struct ShmemCallbacks ProcArrayShmemCallbacks = { + .request_fn = ProcArrayShmemRequest, + .init_fn = ProcArrayShmemInit, + .attach_fn = ProcArrayShmemAttach, +}; + +static ShmemStructDesc ProcArrayShmemDesc = { + .name = "Proc Array", + .size = 0, /* calculated later */ + .ptr = (void **) &procArray, +}; + /* * State for the GlobalVisTest* family of functions. Those functions can * e.g. be used to decide if a deleted row can be removed without violating @@ -269,9 +288,6 @@ typedef enum KAXCompressReason KAX_STARTUP_PROCESS_IDLE, /* startup process is about to sleep */ } KAXCompressReason; - -static ProcArrayStruct *procArray; - static PGPROC *allProcs; /* @@ -282,8 +298,23 @@ static TransactionId cachedXidIsNotInProgress = InvalidTransactionId; /* * Bookkeeping for tracking emulated transactions in recovery */ + static TransactionId *KnownAssignedXids; + +static ShmemStructDesc KnownAssignedXidsShmemDesc = { + .name = "KnownAssignedXids", + .size = 0, /* calculated later */ + .ptr = (void **) &KnownAssignedXids, +}; + static bool *KnownAssignedXidsValid; + +static ShmemStructDesc KnownAssignedXidsValidShmemDesc = { + .name = "KnownAssignedXidsValid", + .size = 0, /* calculated later */ + .ptr = (void **) &KnownAssignedXidsValid, +}; + static TransactionId latestObservedXid = InvalidTransactionId; /* @@ -374,18 +405,17 @@ static inline FullTransactionId FullXidRelativeTo(FullTransactionId rel, static void GlobalVisUpdateApply(ComputeXidHorizonsResult *horizons); /* - * Report shared-memory space needed by ProcArrayShmemInit + * Register the shared PGPROC array during postmaster startup. */ -Size -ProcArrayShmemSize(void) +static void +ProcArrayShmemRequest(void *arg) { - Size size; - - /* Size of the ProcArray structure itself */ #define PROCARRAY_MAXPROCS (MaxBackends + max_prepared_xacts) - size = offsetof(ProcArrayStruct, pgprocnos); - size = add_size(size, mul_size(sizeof(int), PROCARRAY_MAXPROCS)); + /* Register the ProcArray shared structure */ + ProcArrayShmemDesc.size = + add_size(offsetof(ProcArrayStruct, pgprocnos), + mul_size(sizeof(int), PROCARRAY_MAXPROCS)); /* * During Hot Standby processing we have a data structure called @@ -405,64 +435,42 @@ ProcArrayShmemSize(void) if (EnableHotStandby) { - size = add_size(size, - mul_size(sizeof(TransactionId), - TOTAL_MAX_CACHED_SUBXIDS)); - size = add_size(size, - mul_size(sizeof(bool), TOTAL_MAX_CACHED_SUBXIDS)); + KnownAssignedXidsShmemDesc.size = + mul_size(sizeof(TransactionId), + TOTAL_MAX_CACHED_SUBXIDS); + + KnownAssignedXidsValidShmemDesc.size = + mul_size(sizeof(bool), TOTAL_MAX_CACHED_SUBXIDS); + ShmemRequestStruct(&KnownAssignedXidsShmemDesc); + ShmemRequestStruct(&KnownAssignedXidsValidShmemDesc); } - - return size; + ShmemRequestStruct(&ProcArrayShmemDesc); } /* * Initialize the shared PGPROC array during postmaster startup. */ -void -ProcArrayShmemInit(void) +static void +ProcArrayShmemInit(void *arg) { - bool found; - - /* Create or attach to the ProcArray shared structure */ - procArray = (ProcArrayStruct *) - ShmemInitStruct("Proc Array", - add_size(offsetof(ProcArrayStruct, pgprocnos), - mul_size(sizeof(int), - PROCARRAY_MAXPROCS)), - &found); - - if (!found) - { - /* - * We're the first - initialize. - */ - procArray->numProcs = 0; - procArray->maxProcs = PROCARRAY_MAXPROCS; - procArray->maxKnownAssignedXids = TOTAL_MAX_CACHED_SUBXIDS; - procArray->numKnownAssignedXids = 0; - procArray->tailKnownAssignedXids = 0; - procArray->headKnownAssignedXids = 0; - procArray->lastOverflowedXid = InvalidTransactionId; - procArray->replication_slot_xmin = InvalidTransactionId; - procArray->replication_slot_catalog_xmin = InvalidTransactionId; - TransamVariables->xactCompletionCount = 1; - } + procArray->numProcs = 0; + procArray->maxProcs = PROCARRAY_MAXPROCS; + procArray->maxKnownAssignedXids = TOTAL_MAX_CACHED_SUBXIDS; + procArray->numKnownAssignedXids = 0; + procArray->tailKnownAssignedXids = 0; + procArray->headKnownAssignedXids = 0; + procArray->lastOverflowedXid = InvalidTransactionId; + procArray->replication_slot_xmin = InvalidTransactionId; + procArray->replication_slot_catalog_xmin = InvalidTransactionId; + TransamVariables->xactCompletionCount = 1; allProcs = ProcGlobal->allProcs; +} - /* Create or attach to the KnownAssignedXids arrays too, if needed */ - if (EnableHotStandby) - { - KnownAssignedXids = (TransactionId *) - ShmemInitStruct("KnownAssignedXids", - mul_size(sizeof(TransactionId), - TOTAL_MAX_CACHED_SUBXIDS), - &found); - KnownAssignedXidsValid = (bool *) - ShmemInitStruct("KnownAssignedXidsValid", - mul_size(sizeof(bool), TOTAL_MAX_CACHED_SUBXIDS), - &found); - } +static void +ProcArrayShmemAttach(void *arg) +{ + allProcs = ProcGlobal->allProcs; } /* diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 7e017c8d53b..6a53b4044ad 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -32,6 +32,7 @@ #include "storage/shmem.h" #include "storage/sinval.h" #include "storage/smgr.h" +#include "storage/subsystems.h" #include "tcop/tcopprot.h" #include "utils/memutils.h" #include "utils/wait_event.h" @@ -105,7 +106,17 @@ struct ProcSignalHeader #define BARRIER_CLEAR_BIT(flags, type) \ ((flags) &= ~(((uint32) 1) << (uint32) (type))) +static void ProcSignalShmemRequest(void *arg); +static void ProcSignalShmemInit(void *arg); + NON_EXEC_STATIC ProcSignalHeader *ProcSignal = NULL; + +const ShmemCallbacks ProcSignalShmemCallbacks = { + .request_fn = ProcSignalShmemRequest, + .init_fn = ProcSignalShmemInit, +}; + + static ProcSignalSlot *MyProcSignalSlot = NULL; static bool CheckProcSignal(ProcSignalReason reason); @@ -113,51 +124,41 @@ static void CleanupProcSignalState(int status, Datum arg); static void ResetProcSignalBarrierBits(uint32 flags); /* - * ProcSignalShmemSize - * Compute space needed for ProcSignal's shared memory + * ProcSignalShmemRequest + * Register ProcSignal's shared memory needs at postmaster startup */ -Size -ProcSignalShmemSize(void) +static void +ProcSignalShmemRequest(void *arg) { + static ShmemStructDesc ProcSignalShmemDesc = { + .name = "ProcSignal", + .ptr = (void **) &ProcSignal, + }; Size size; size = mul_size(NumProcSignalSlots, sizeof(ProcSignalSlot)); size = add_size(size, offsetof(ProcSignalHeader, psh_slot)); - return size; + + ProcSignalShmemDesc.size = size; + ShmemRequestStruct(&ProcSignalShmemDesc); } -/* - * ProcSignalShmemInit - * Allocate and initialize ProcSignal's shared memory - */ -void -ProcSignalShmemInit(void) +static void +ProcSignalShmemInit(void *arg) { - Size size = ProcSignalShmemSize(); - bool found; + pg_atomic_init_u64(&ProcSignal->psh_barrierGeneration, 0); - ProcSignal = (ProcSignalHeader *) - ShmemInitStruct("ProcSignal", size, &found); - - /* If we're first, initialize. */ - if (!found) + for (int i = 0; i < NumProcSignalSlots; ++i) { - int i; - - pg_atomic_init_u64(&ProcSignal->psh_barrierGeneration, 0); + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; - for (i = 0; i < NumProcSignalSlots; ++i) - { - ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; - - SpinLockInit(&slot->pss_mutex); - pg_atomic_init_u32(&slot->pss_pid, 0); - slot->pss_cancel_key_len = 0; - MemSet(slot->pss_signalFlags, 0, sizeof(slot->pss_signalFlags)); - pg_atomic_init_u64(&slot->pss_barrierGeneration, PG_UINT64_MAX); - pg_atomic_init_u32(&slot->pss_barrierCheckMask, 0); - ConditionVariableInit(&slot->pss_barrierCV); - } + SpinLockInit(&slot->pss_mutex); + pg_atomic_init_u32(&slot->pss_pid, 0); + slot->pss_cancel_key_len = 0; + MemSet(slot->pss_signalFlags, 0, sizeof(slot->pss_signalFlags)); + pg_atomic_init_u64(&slot->pss_barrierGeneration, PG_UINT64_MAX); + pg_atomic_init_u32(&slot->pss_barrierCheckMask, 0); + ConditionVariableInit(&slot->pss_barrierCV); } } diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c index de843d03c50..e4dc66122ab 100644 --- a/src/backend/storage/ipc/shmem.c +++ b/src/backend/storage/ipc/shmem.c @@ -388,21 +388,22 @@ ShmemInitRequested(void) void ShmemAttachRequested(void) { + ListCell *lc; + /* Must be initializing a (non-standalone) backend */ Assert(IsUnderPostmaster); Assert(ShmemAllocator->index != NULL); Assert(shmem_startup_state == SB_REQUESTING); shmem_startup_state = SB_ATTACHING; + LWLockAcquire(ShmemIndexLock, LW_SHARED); + /* * Attach to all the requested memory areas. */ - LWLockAcquire(ShmemIndexLock, LW_SHARED); - while (!dclist_is_empty(&requested_shmem_areas)) + foreach(lc, requested_shmem_areas) { - requested_shmem_area *area = dlist_container(requested_shmem_area, node, - dclist_pop_head_node(&requested_shmem_areas)); - ShmemStructDesc *desc = area->desc; + ShmemStructDesc *desc = (ShmemStructDesc *) lfirst(lc); AttachOrInit(desc, false, true); } @@ -410,12 +411,12 @@ ShmemAttachRequested(void) requested_shmem_areas = NIL; /* Call attach callbacks */ - dlist_foreach(iter, ®istered_shmem_init_callbacks) + foreach(lc, registered_shmem_callbacks) { - registered_shmem_init_callback *callback = - dlist_container(registered_shmem_init_callback, node, iter.cur); + const ShmemCallbacks *callbacks = (const ShmemCallbacks *) lfirst(lc); - callback->attach_fn(callback->attach_fn_arg); + if (callbacks->attach_fn) + callbacks->attach_fn(callbacks->attach_fn_arg); } LWLockRelease(ShmemIndexLock); @@ -452,8 +453,12 @@ AttachOrInit(ShmemStructDesc *desc, bool init_allowed, bool attach_allowed) elog(ERROR, "shared memory struct \"%s\" is already initialized", desc->name); if (index_entry->size != desc->size) - elog(ERROR, "shared memory struct \"%s\" is already registered with different size", - desc->name); + { + if (desc->size != 0) + elog(ERROR, "shared memory struct \"%s\" is already registered with different size (%zd vs %zd)", + desc->name, index_entry->size, desc->size); + desc->size = index_entry->size; + } switch (desc->kind) { case SHMEM_KIND_STRUCT: @@ -738,7 +743,7 @@ ShmemAddrIsValid(const void *addr) void RegisterShmemCallbacks(const ShmemCallbacks *callbacks) { - if (IsUnderPostmaster && !process_shared_preload_libraries_in_progress) + if (shmem_startup_state == SB_DONE && IsUnderPostmaster) { /* After-startup initialization */ ListCell *lc; @@ -765,7 +770,8 @@ RegisterShmemCallbacks(const ShmemCallbacks *callbacks) /* * FIXME: What to do if multiple shmem areas were requested, and some - * of them are already initialized but not all? + * of them are already initialized but not all? We expect all shmem + * areas requested by a single callback to form a coherent unit. */ if (found) { diff --git a/src/backend/storage/ipc/sinvaladt.c b/src/backend/storage/ipc/sinvaladt.c index a7a7cc4f0a9..127584df022 100644 --- a/src/backend/storage/ipc/sinvaladt.c +++ b/src/backend/storage/ipc/sinvaladt.c @@ -25,6 +25,7 @@ #include "storage/shmem.h" #include "storage/sinvaladt.h" #include "storage/spin.h" +#include "storage/subsystems.h" /* * Conceptually, the shared cache invalidation messages are stored in an @@ -203,8 +204,16 @@ typedef struct SISeg */ #define NumProcStateSlots (MaxBackends + NUM_AUXILIARY_PROCS) +static void SharedInvalShmemRequest(void *arg); +static void SharedInvalShmemInit(void *arg); + static SISeg *shmInvalBuffer; /* pointer to the shared inval buffer */ +const ShmemCallbacks SharedInvalShmemCallbacks = { + .request_fn = SharedInvalShmemRequest, + .init_fn = SharedInvalShmemInit, +}; + static LocalTransactionId nextLocalTransactionId; @@ -212,37 +221,33 @@ static void CleanupInvalidationState(int status, Datum arg); /* - * SharedInvalShmemSize --- return shared-memory space needed + * SharedInvalShmemRequest + * Register shared memory needs for the SI message buffer */ -Size -SharedInvalShmemSize(void) +static void +SharedInvalShmemRequest(void *arg) { + static ShmemStructDesc SharedInvalShmemDesc = { + .name = "shmInvalBuffer", + .size = 0, /* calculated later */ + .ptr = (void **) &shmInvalBuffer, + }; Size size; size = offsetof(SISeg, procState); size = add_size(size, mul_size(sizeof(ProcState), NumProcStateSlots)); /* procState */ size = add_size(size, mul_size(sizeof(int), NumProcStateSlots)); /* pgprocnos */ - return size; + SharedInvalShmemDesc.size = size; + ShmemRequestStruct(&SharedInvalShmemDesc); } -/* - * SharedInvalShmemInit - * Create and initialize the SI message buffer - */ -void -SharedInvalShmemInit(void) +static void +SharedInvalShmemInit(void *arg) { int i; - bool found; - - /* Allocate space in shared memory */ - shmInvalBuffer = (SISeg *) - ShmemInitStruct("shmInvalBuffer", SharedInvalShmemSize(), &found); - if (found) - return; - /* Clear message counters, save size of procState array, init spinlock */ + /* Clear message counters, init spinlock */ shmInvalBuffer->minMsgNum = 0; shmInvalBuffer->maxMsgNum = 0; shmInvalBuffer->nextThreshold = CLEANUP_MIN; diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 8f5ce0e2a8a..03f02d332bd 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -51,6 +51,7 @@ #include "storage/procsignal.h" #include "storage/spin.h" #include "storage/standby.h" +#include "storage/subsystems.h" #include "utils/timeout.h" #include "utils/timestamp.h" #include "utils/wait_event.h" @@ -69,9 +70,44 @@ PGPROC *MyProc = NULL; /* Pointers to shared-memory structures */ PROC_HDR *ProcGlobal = NULL; +static void *tmpAllProcs; +static void *tmpFastPathLockArray; NON_EXEC_STATIC PGPROC *AuxiliaryProcs = NULL; PGPROC *PreparedXactProcs = NULL; +static void ProcGlobalShmemRequest(void *arg); +static void ProcGlobalShmemInit(void *arg); + +const ShmemCallbacks ProcGlobalShmemCallbacks = { + .request_fn = ProcGlobalShmemRequest, + .init_fn = ProcGlobalShmemInit, +}; + +static ShmemStructDesc ProcGlobalShmemDesc = { + .name = "Proc Header", + .size = sizeof(PROC_HDR), + + /* + * ProcGlobal is registered here in .ptr as usual, but it needs to be + * propagated specially in EXEC_BACKEND mode, because ProcGlobal needs to + * be accessed early at backend startup, before ShmemAttachRequested() + * has been called. + */ + .ptr = (void **) &ProcGlobal, +}; +static ShmemStructDesc ProcGlobalAllProcsShmemDesc = { + .name = "PGPROC structures", + .size = 0, /* calculated later */ + .ptr = (void **) &tmpAllProcs, +}; +static ShmemStructDesc FastPathLockArrayShmemDesc = { + .name = "Fast-Path Lock Array", + .size = 0, /* calculated later */ + .ptr = (void **) &tmpFastPathLockArray, +}; + +static uint32 TotalProcs; + /* Is a deadlock check pending? */ static volatile sig_atomic_t got_deadlock_timeout; @@ -81,24 +117,6 @@ static void AuxiliaryProcKill(int code, Datum arg); static DeadLockState CheckDeadLock(void); -/* - * Report shared-memory space needed by PGPROC. - */ -static Size -PGProcShmemSize(void) -{ - Size size = 0; - Size TotalProcs = - add_size(MaxBackends, add_size(NUM_AUXILIARY_PROCS, max_prepared_xacts)); - - size = add_size(size, mul_size(TotalProcs, sizeof(PGPROC))); - size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->xids))); - size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->subxidStates))); - size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->statusFlags))); - - return size; -} - /* * Report shared-memory space needed by Fast-Path locks. */ @@ -106,8 +124,6 @@ static Size FastPathLockShmemSize(void) { Size size = 0; - Size TotalProcs = - add_size(MaxBackends, add_size(NUM_AUXILIARY_PROCS, max_prepared_xacts)); Size fpLockBitsSize, fpRelIdSize; @@ -123,25 +139,6 @@ FastPathLockShmemSize(void) return size; } -/* - * Report shared-memory space needed by InitProcGlobal. - */ -Size -ProcGlobalShmemSize(void) -{ - Size size = 0; - - /* ProcGlobal */ - size = add_size(size, sizeof(PROC_HDR)); - size = add_size(size, sizeof(slock_t)); - - size = add_size(size, PGSemaphoreShmemSize(ProcGlobalSemas())); - size = add_size(size, PGProcShmemSize()); - size = add_size(size, FastPathLockShmemSize()); - - return size; -} - /* * Report number of semaphores needed by InitProcGlobal. */ @@ -156,7 +153,47 @@ ProcGlobalSemas(void) } /* - * InitProcGlobal - + * ProcGlobalShmemRequest + * Register shared memory needs. + * + * This is called during postmaster or standalone backend startup, and also + * during backend startup in EXEC_BACKEND mode. + */ +static void +ProcGlobalShmemRequest(void *arg) +{ + Size size; + + /* + * Reserve all the PGPROC structures we'll need. There are six separate + * consumers: (1) normal backends, (2) autovacuum workers and special + * workers, (3) background workers, (4) walsenders, (5) auxiliary + * processes, and (6) prepared transactions. (For largely-historical + * reasons, we combine autovacuum and special workers into one category + * with a single freelist.) Each PGPROC structure is dedicated to exactly + * one of these purposes, and they do not move between groups. + */ + TotalProcs = + add_size(MaxBackends, add_size(NUM_AUXILIARY_PROCS, max_prepared_xacts)); + + size = 0; + size = add_size(size, mul_size(TotalProcs, sizeof(PGPROC))); + size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->xids))); + size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->subxidStates))); + size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->statusFlags))); + ProcGlobalAllProcsShmemDesc.size = size; + ShmemRequestStruct(&ProcGlobalAllProcsShmemDesc); + + FastPathLockArrayShmemDesc.size = FastPathLockShmemSize(); + ShmemRequestStruct(&FastPathLockArrayShmemDesc); + + ShmemRequestStruct(&ProcGlobalShmemDesc); + +} + + +/* + * ProcGlobalShmemInit - * Initialize the global process table during postmaster or standalone * backend startup. * @@ -175,36 +212,23 @@ ProcGlobalSemas(void) * Another reason for creating semaphores here is that the semaphore * implementation typically requires us to create semaphores in the * postmaster, not in backends. - * - * Note: this is NOT called by individual backends under a postmaster, - * not even in the EXEC_BACKEND case. The ProcGlobal and AuxiliaryProcs - * pointers must be propagated specially for EXEC_BACKEND operation. */ -void -InitProcGlobal(void) +static void +ProcGlobalShmemInit(void *arg) { + char *ptr; + size_t requestSize; PGPROC *procs; int i, j; - bool found; - uint32 TotalProcs = MaxBackends + NUM_AUXILIARY_PROCS + max_prepared_xacts; /* Used for setup of per-backend fast-path slots. */ char *fpPtr, *fpEndPtr PG_USED_FOR_ASSERTS_ONLY; Size fpLockBitsSize, fpRelIdSize; - Size requestSize; - char *ptr; - - /* Create the ProcGlobal shared structure */ - ProcGlobal = (PROC_HDR *) - ShmemInitStruct("Proc Header", sizeof(PROC_HDR), &found); - Assert(!found); - /* - * Initialize the data structures. - */ + Assert(ProcGlobal); ProcGlobal->spins_per_delay = DEFAULT_SPINS_PER_DELAY; SpinLockInit(&ProcGlobal->freeProcsLock); dlist_init(&ProcGlobal->freeProcs); @@ -217,23 +241,12 @@ InitProcGlobal(void) pg_atomic_init_u32(&ProcGlobal->procArrayGroupFirst, INVALID_PROC_NUMBER); pg_atomic_init_u32(&ProcGlobal->clogGroupFirst, INVALID_PROC_NUMBER); - /* - * Create and initialize all the PGPROC structures we'll need. There are - * six separate consumers: (1) normal backends, (2) autovacuum workers and - * special workers, (3) background workers, (4) walsenders, (5) auxiliary - * processes, and (6) prepared transactions. (For largely-historical - * reasons, we combine autovacuum and special workers into one category - * with a single freelist.) Each PGPROC structure is dedicated to exactly - * one of these purposes, and they do not move between groups. - */ - requestSize = PGProcShmemSize(); - - ptr = ShmemInitStruct("PGPROC structures", - requestSize, - &found); - + Assert(tmpAllProcs); + ptr = tmpAllProcs; + requestSize = ProcGlobalAllProcsShmemDesc.size; MemSet(ptr, 0, requestSize); + /* Carve out the allProcs array from the shared memory area */ procs = (PGPROC *) ptr; ptr = ptr + TotalProcs * sizeof(PGPROC); @@ -242,7 +255,7 @@ InitProcGlobal(void) ProcGlobal->allProcCount = MaxBackends + NUM_AUXILIARY_PROCS; /* - * Allocate arrays mirroring PGPROC fields in a dense manner. See + * Carve out arrays mirroring PGPROC fields in a dense manner. See * PROC_HDR. * * XXX: It might make sense to increase padding for these arrays, given @@ -257,31 +270,25 @@ InitProcGlobal(void) ProcGlobal->statusFlags = (uint8 *) ptr; ptr = ptr + (TotalProcs * sizeof(*ProcGlobal->statusFlags)); - /* make sure wer didn't overflow */ + /* make sure we didn't overflow */ Assert((ptr > (char *) procs) && (ptr <= (char *) procs + requestSize)); /* - * Allocate arrays for fast-path locks. Those are variable-length, so + * Initialize arrays for fast-path locks. Those are variable-length, so * can't be included in PGPROC directly. We allocate a separate piece of * shared memory and then divide that between backends. */ fpLockBitsSize = MAXALIGN(FastPathLockGroupsPerBackend * sizeof(uint64)); fpRelIdSize = MAXALIGN(FastPathLockSlotsPerBackend() * sizeof(Oid)); - requestSize = FastPathLockShmemSize(); - - fpPtr = ShmemInitStruct("Fast-Path Lock Array", - requestSize, - &found); - - MemSet(fpPtr, 0, requestSize); + Assert(tmpFastPathLockArray); + fpPtr = tmpFastPathLockArray; + requestSize = FastPathLockArrayShmemDesc.size; + memset(fpPtr, 0, requestSize); /* For asserts checking we did not overflow. */ fpEndPtr = fpPtr + requestSize; - /* Reserve space for semaphores. */ - PGReserveSemaphores(ProcGlobalSemas()); - for (i = 0; i < TotalProcs; i++) { PGPROC *proc = &procs[i]; diff --git a/src/backend/utils/activity/wait_event.c b/src/backend/utils/activity/wait_event.c index aca2c8fc742..2869c452ed0 100644 --- a/src/backend/utils/activity/wait_event.c +++ b/src/backend/utils/activity/wait_event.c @@ -24,6 +24,7 @@ #include "storage/lmgr.h" /* for GetLockNameFromTagType */ #include "storage/lwlock.h" /* for GetLWLockIdentifier */ +#include "storage/subsystems.h" #include "storage/spin.h" #include "utils/wait_event.h" @@ -79,7 +80,6 @@ typedef struct WaitEventCustomEntryByName uint32 wait_event_info; } WaitEventCustomEntryByName; - /* dynamic allocation counter for custom wait events */ typedef struct WaitEventCustomCounterData { @@ -96,61 +96,58 @@ static WaitEventCustomCounterData *WaitEventCustomCounter; static uint32 WaitEventCustomNew(uint32 classId, const char *wait_event_name); static const char *GetWaitEventCustomIdentifier(uint32 wait_event_info); +static void WaitEventCustomShmemRequest(void *arg); +static void WaitEventCustomShmemInit(void *arg); + +const ShmemCallbacks WaitEventCustomShmemCallbacks = { + .request_fn = WaitEventCustomShmemRequest, + .init_fn = WaitEventCustomShmemInit, +}; + /* - * Return the space for dynamic shared hash tables and dynamic allocation counter. + * Register shmem space for dynamic shared hash and dynamic allocation counter. */ -Size -WaitEventCustomShmemSize(void) +static void +WaitEventCustomShmemRequest(void *arg) { - Size sz; - - sz = MAXALIGN(sizeof(WaitEventCustomCounterData)); - sz = add_size(sz, hash_estimate_size(WAIT_EVENT_CUSTOM_HASH_MAX_SIZE, - sizeof(WaitEventCustomEntryByInfo))); - sz = add_size(sz, hash_estimate_size(WAIT_EVENT_CUSTOM_HASH_MAX_SIZE, - sizeof(WaitEventCustomEntryByName))); - return sz; + static ShmemStructDesc WaitEventCustomCounterShmemDesc = { + .name = "WaitEventCustomCounterData", + .size = sizeof(WaitEventCustomCounterData), + .ptr = (void **) &WaitEventCustomCounter, + }; + static ShmemHashDesc WaitEventCustomHashByInfoDesc = { + .name = "WaitEventCustom hash by wait event information", + .ptr = &WaitEventCustomHashByInfo, + + .init_size = WAIT_EVENT_CUSTOM_HASH_INIT_SIZE, + .max_size = WAIT_EVENT_CUSTOM_HASH_MAX_SIZE, + .hash_info.keysize = sizeof(uint32), + .hash_info.entrysize = sizeof(WaitEventCustomEntryByInfo), + .hash_flags = HASH_ELEM | HASH_BLOBS, + }; + static ShmemHashDesc WaitEventCustomHashByNameDesc = { + .name = "WaitEventCustom hash by name", + .ptr = &WaitEventCustomHashByName, + + .init_size = WAIT_EVENT_CUSTOM_HASH_INIT_SIZE, + .max_size = WAIT_EVENT_CUSTOM_HASH_MAX_SIZE, + /* key is a NULL-terminated string */ + .hash_info.keysize = sizeof(char[NAMEDATALEN]), + .hash_info.entrysize = sizeof(WaitEventCustomEntryByName), + .hash_flags = HASH_ELEM | HASH_STRINGS, + }; + + ShmemRequestStruct(&WaitEventCustomCounterShmemDesc); + ShmemRequestHash(&WaitEventCustomHashByInfoDesc); + ShmemRequestHash(&WaitEventCustomHashByNameDesc); } -/* - * Allocate shmem space for dynamic shared hash and dynamic allocation counter. - */ -void -WaitEventCustomShmemInit(void) +static void +WaitEventCustomShmemInit(void *arg) { - bool found; - HASHCTL info; - - WaitEventCustomCounter = (WaitEventCustomCounterData *) - ShmemInitStruct("WaitEventCustomCounterData", - sizeof(WaitEventCustomCounterData), &found); - - if (!found) - { - /* initialize the allocation counter and its spinlock. */ - WaitEventCustomCounter->nextId = WAIT_EVENT_CUSTOM_INITIAL_ID; - SpinLockInit(&WaitEventCustomCounter->mutex); - } - - /* initialize or attach the hash tables to store custom wait events */ - info.keysize = sizeof(uint32); - info.entrysize = sizeof(WaitEventCustomEntryByInfo); - WaitEventCustomHashByInfo = - ShmemInitHash("WaitEventCustom hash by wait event information", - WAIT_EVENT_CUSTOM_HASH_INIT_SIZE, - WAIT_EVENT_CUSTOM_HASH_MAX_SIZE, - &info, - HASH_ELEM | HASH_BLOBS); - - /* key is a NULL-terminated string */ - info.keysize = sizeof(char[NAMEDATALEN]); - info.entrysize = sizeof(WaitEventCustomEntryByName); - WaitEventCustomHashByName = - ShmemInitHash("WaitEventCustom hash by name", - WAIT_EVENT_CUSTOM_HASH_INIT_SIZE, - WAIT_EVENT_CUSTOM_HASH_MAX_SIZE, - &info, - HASH_ELEM | HASH_STRINGS); + /* initialize the allocation counter and its spinlock. */ + WaitEventCustomCounter->nextId = WAIT_EVENT_CUSTOM_INITIAL_ID; + SpinLockInit(&WaitEventCustomCounter->mutex); } /* diff --git a/src/include/access/transam.h b/src/include/access/transam.h index 6fa91bfcdc0..55a4ab26b34 100644 --- a/src/include/access/transam.h +++ b/src/include/access/transam.h @@ -345,8 +345,6 @@ extern TransactionId TransactionIdLatest(TransactionId mainxid, extern XLogRecPtr TransactionIdGetCommitLSN(TransactionId xid); /* in transam/varsup.c */ -extern Size VarsupShmemSize(void); -extern void VarsupShmemInit(void); extern FullTransactionId GetNewTransactionId(bool isSubXact); extern void AdvanceNextFullTransactionIdPastXid(TransactionId xid); extern FullTransactionId ReadNextFullTransactionId(void); diff --git a/src/include/storage/dsm.h b/src/include/storage/dsm.h index 407657df3ff..1bde71b4406 100644 --- a/src/include/storage/dsm.h +++ b/src/include/storage/dsm.h @@ -26,9 +26,6 @@ extern void dsm_postmaster_startup(PGShmemHeader *); extern void dsm_backend_shutdown(void); extern void dsm_detach_all(void); -extern size_t dsm_estimate_size(void); -extern void dsm_shmem_init(void); - #ifdef EXEC_BACKEND extern void dsm_set_control_handle(dsm_handle h); #endif diff --git a/src/include/storage/dsm_registry.h b/src/include/storage/dsm_registry.h index 506fae2c9ca..a2269c89f01 100644 --- a/src/include/storage/dsm_registry.h +++ b/src/include/storage/dsm_registry.h @@ -22,7 +22,5 @@ extern dsa_area *GetNamedDSA(const char *name, bool *found); extern dshash_table *GetNamedDSHash(const char *name, const dshash_parameters *params, bool *found); -extern Size DSMRegistryShmemSize(void); -extern void DSMRegistryShmemInit(void); #endif /* DSM_REGISTRY_H */ diff --git a/src/include/storage/pmsignal.h b/src/include/storage/pmsignal.h index 206fb78f8a5..001e6eea61c 100644 --- a/src/include/storage/pmsignal.h +++ b/src/include/storage/pmsignal.h @@ -66,8 +66,6 @@ extern PGDLLIMPORT volatile PMSignalData *PMSignalState; /* * prototypes for functions in pmsignal.c */ -extern Size PMSignalShmemSize(void); -extern void PMSignalShmemInit(void); extern void SendPostmasterSignal(PMSignalReason reason); extern bool CheckPostmasterSignal(PMSignalReason reason); extern void SetQuitSignalReason(QuitSignalReason reason); diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h index bf3094f0f7d..7f94653c25f 100644 --- a/src/include/storage/proc.h +++ b/src/include/storage/proc.h @@ -549,7 +549,6 @@ extern PGDLLIMPORT PGPROC *AuxiliaryProcs; * Function Prototypes */ extern int ProcGlobalSemas(void); -extern Size ProcGlobalShmemSize(void); extern void InitProcGlobal(void); extern void InitProcess(void); extern void InitProcessPhase2(void); diff --git a/src/include/storage/procarray.h b/src/include/storage/procarray.h index c5ab1574fe3..58226d3869d 100644 --- a/src/include/storage/procarray.h +++ b/src/include/storage/procarray.h @@ -20,8 +20,6 @@ #include "utils/snapshot.h" -extern Size ProcArrayShmemSize(void); -extern void ProcArrayShmemInit(void); extern void ProcArrayAdd(PGPROC *proc); extern void ProcArrayRemove(PGPROC *proc, TransactionId latestXid); diff --git a/src/include/storage/procsignal.h b/src/include/storage/procsignal.h index 348fba53a93..031897015f4 100644 --- a/src/include/storage/procsignal.h +++ b/src/include/storage/procsignal.h @@ -63,9 +63,6 @@ typedef enum /* * prototypes for functions in procsignal.c */ -extern Size ProcSignalShmemSize(void); -extern void ProcSignalShmemInit(void); - extern void ProcSignalInit(const uint8 *cancel_key, int cancel_key_len); extern int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber); diff --git a/src/include/storage/sinvaladt.h b/src/include/storage/sinvaladt.h index a1694500a85..e2627b589c1 100644 --- a/src/include/storage/sinvaladt.h +++ b/src/include/storage/sinvaladt.h @@ -28,8 +28,6 @@ /* * prototypes for functions in sinvaladt.c */ -extern Size SharedInvalShmemSize(void); -extern void SharedInvalShmemInit(void); extern void SharedInvalBackendInit(bool sendOnly); extern void SIInsertDataEntries(const SharedInvalidationMessage *data, int n); diff --git a/src/include/storage/subsystemlist.h b/src/include/storage/subsystemlist.h index 65da6f17c5d..5c11b2b3499 100644 --- a/src/include/storage/subsystemlist.h +++ b/src/include/storage/subsystemlist.h @@ -20,4 +20,23 @@ * of these matter. */ +PG_SHMEM_SUBSYSTEM(dsm_shmem_callbacks) +PG_SHMEM_SUBSYSTEM(DSMRegistryShmemCallbacks) + +/* xlog, clog, and buffers */ +PG_SHMEM_SUBSYSTEM(VarsupShmemCallbacks) + +/* process table */ +PG_SHMEM_SUBSYSTEM(ProcGlobalShmemCallbacks) +PG_SHMEM_SUBSYSTEM(ProcArrayShmemCallbacks) + +/* shared-inval messaging */ +PG_SHMEM_SUBSYSTEM(SharedInvalShmemCallbacks) + +/* interprocess signaling mechanisms */ +PG_SHMEM_SUBSYSTEM(PMSignalShmemCallbacks) +PG_SHMEM_SUBSYSTEM(ProcSignalShmemCallbacks) + +/* other modules that need some shared memory space */ +PG_SHMEM_SUBSYSTEM(WaitEventCustomShmemCallbacks) PG_SHMEM_SUBSYSTEM(InjectionPointShmemCallbacks) diff --git a/src/include/utils/wait_event.h b/src/include/utils/wait_event.h index 34c27cc3dc3..4d5e54bbbe5 100644 --- a/src/include/utils/wait_event.h +++ b/src/include/utils/wait_event.h @@ -10,6 +10,8 @@ #ifndef WAIT_EVENT_H #define WAIT_EVENT_H +#include "storage/shmem.h" + /* enums for wait events */ #include "utils/wait_event_types.h" @@ -42,8 +44,6 @@ extern PGDLLIMPORT uint32 *my_wait_event_info; extern uint32 WaitEventExtensionNew(const char *wait_event_name); extern uint32 WaitEventInjectionPointNew(const char *wait_event_name); -extern void WaitEventCustomShmemInit(void); -extern Size WaitEventCustomShmemSize(void); extern char **GetWaitEventCustomNames(uint32 classId, int *nwaitevents); /* ---------- -- 2.47.3