From: Heikki Linnakangas Date: Sun, 5 Apr 2026 23:13:10 +0000 (+0300) Subject: Convert all remaining subsystems to use the new shmem allocation API X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9b5acad3f40fa6015f367fbf887ae5c1a93a3698;p=thirdparty%2Fpostgresql.git Convert all remaining subsystems to use the new shmem allocation API This removes all remaining uses of ShmemInitStruct() and ShmemInitHash() from built-in code. Reviewed-by: Ashutosh Bapat Reviewed-by: Matthias van de Meent Reviewed-by: Daniel Gustafsson Discussion: https://www.postgresql.org/message-id/CAExHW5vM1bneLYfg0wGeAa=52UiJ3z4vKd3AJ72X8Fw6k3KKrg@mail.gmail.com --- diff --git a/src/backend/access/common/syncscan.c b/src/backend/access/common/syncscan.c index 6fcfcb0e560..0f9eb167bed 100644 --- a/src/backend/access/common/syncscan.c +++ b/src/backend/access/common/syncscan.c @@ -50,6 +50,7 @@ #include "miscadmin.h" #include "storage/lwlock.h" #include "storage/shmem.h" +#include "storage/subsystems.h" #include "utils/rel.h" @@ -111,6 +112,14 @@ typedef struct ss_scan_locations_t #define SizeOfScanLocations(N) \ (offsetof(ss_scan_locations_t, items) + (N) * sizeof(ss_lru_item_t)) +static void SyncScanShmemRequest(void *arg); +static void SyncScanShmemInit(void *arg); + +const ShmemCallbacks SyncScanShmemCallbacks = { + .request_fn = SyncScanShmemRequest, + .init_fn = SyncScanShmemInit, +}; + /* Pointer to struct in shared memory */ static ss_scan_locations_t *scan_locations; @@ -120,58 +129,47 @@ static BlockNumber ss_search(RelFileLocator relfilelocator, /* - * SyncScanShmemSize --- report amount of shared memory space needed + * SyncScanShmemRequest --- register this module's shared memory */ -Size -SyncScanShmemSize(void) +static void +SyncScanShmemRequest(void *arg) { - return SizeOfScanLocations(SYNC_SCAN_NELEM); + ShmemRequestStruct(.name = "Sync Scan Locations List", + .size = SizeOfScanLocations(SYNC_SCAN_NELEM), + .ptr = (void **) &scan_locations, + ); } /* * SyncScanShmemInit --- initialize this module's shared memory */ -void -SyncScanShmemInit(void) +static void +SyncScanShmemInit(void *arg) { int i; - bool found; - scan_locations = (ss_scan_locations_t *) - ShmemInitStruct("Sync Scan Locations List", - SizeOfScanLocations(SYNC_SCAN_NELEM), - &found); + scan_locations->head = &scan_locations->items[0]; + scan_locations->tail = &scan_locations->items[SYNC_SCAN_NELEM - 1]; - if (!IsUnderPostmaster) + for (i = 0; i < SYNC_SCAN_NELEM; i++) { - /* Initialize shared memory area */ - Assert(!found); - - scan_locations->head = &scan_locations->items[0]; - scan_locations->tail = &scan_locations->items[SYNC_SCAN_NELEM - 1]; - - for (i = 0; i < SYNC_SCAN_NELEM; i++) - { - ss_lru_item_t *item = &scan_locations->items[i]; - - /* - * Initialize all slots with invalid values. As scans are started, - * these invalid entries will fall off the LRU list and get - * replaced with real entries. - */ - item->location.relfilelocator.spcOid = InvalidOid; - item->location.relfilelocator.dbOid = InvalidOid; - item->location.relfilelocator.relNumber = InvalidRelFileNumber; - item->location.location = InvalidBlockNumber; - - item->prev = (i > 0) ? - (&scan_locations->items[i - 1]) : NULL; - item->next = (i < SYNC_SCAN_NELEM - 1) ? - (&scan_locations->items[i + 1]) : NULL; - } + ss_lru_item_t *item = &scan_locations->items[i]; + + /* + * Initialize all slots with invalid values. As scans are started, + * these invalid entries will fall off the LRU list and get replaced + * with real entries. + */ + item->location.relfilelocator.spcOid = InvalidOid; + item->location.relfilelocator.dbOid = InvalidOid; + item->location.relfilelocator.relNumber = InvalidRelFileNumber; + item->location.location = InvalidBlockNumber; + + item->prev = (i > 0) ? + (&scan_locations->items[i - 1]) : NULL; + item->next = (i < SYNC_SCAN_NELEM - 1) ? + (&scan_locations->items[i + 1]) : NULL; } - else - Assert(found); } /* diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c index 732bc750c9e..014faa1622f 100644 --- a/src/backend/access/nbtree/nbtutils.c +++ b/src/backend/access/nbtree/nbtutils.c @@ -25,6 +25,7 @@ #include "lib/qunique.h" #include "miscadmin.h" #include "storage/lwlock.h" +#include "storage/subsystems.h" #include "utils/datum.h" #include "utils/lsyscache.h" #include "utils/rel.h" @@ -417,6 +418,13 @@ typedef struct BTVacInfo static BTVacInfo *btvacinfo; +static void BTreeShmemRequest(void *arg); +static void BTreeShmemInit(void *arg); + +const ShmemCallbacks BTreeShmemCallbacks = { + .request_fn = BTreeShmemRequest, + .init_fn = BTreeShmemInit, +}; /* * _bt_vacuum_cycleid --- get the active vacuum cycle ID for an index, @@ -553,47 +561,37 @@ _bt_end_vacuum_callback(int code, Datum arg) } /* - * BTreeShmemSize --- report amount of shared memory space needed + * BTreeShmemRequest --- register this module's shared memory */ -Size -BTreeShmemSize(void) +static void +BTreeShmemRequest(void *arg) { Size size; size = offsetof(BTVacInfo, vacuums); size = add_size(size, mul_size(MaxBackends, sizeof(BTOneVacInfo))); - return size; + + ShmemRequestStruct(.name = "BTree Vacuum State", + .size = size, + .ptr = (void **) &btvacinfo, + ); } /* * BTreeShmemInit --- initialize this module's shared memory */ -void -BTreeShmemInit(void) +static void +BTreeShmemInit(void *arg) { - bool found; - - btvacinfo = (BTVacInfo *) ShmemInitStruct("BTree Vacuum State", - BTreeShmemSize(), - &found); - - if (!IsUnderPostmaster) - { - /* Initialize shared memory area */ - Assert(!found); - - /* - * It doesn't really matter what the cycle counter starts at, but - * having it always start the same doesn't seem good. Seed with - * low-order bits of time() instead. - */ - btvacinfo->cycle_ctr = (BTCycleId) time(NULL); + /* + * It doesn't really matter what the cycle counter starts at, but having + * it always start the same doesn't seem good. Seed with low-order bits + * of time() instead. + */ + btvacinfo->cycle_ctr = (BTCycleId) time(NULL); - btvacinfo->num_vacuums = 0; - btvacinfo->max_vacuums = MaxBackends; - } - else - Assert(found); + btvacinfo->num_vacuums = 0; + btvacinfo->max_vacuums = MaxBackends; } bytea * diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c index ab1cbd67bac..1035e8b3fc7 100644 --- a/src/backend/access/transam/twophase.c +++ b/src/backend/access/transam/twophase.c @@ -102,6 +102,7 @@ #include "storage/predicate.h" #include "storage/proc.h" #include "storage/procarray.h" +#include "storage/subsystems.h" #include "utils/builtins.h" #include "utils/injection_point.h" #include "utils/memutils.h" @@ -189,6 +190,14 @@ typedef struct TwoPhaseStateData static TwoPhaseStateData *TwoPhaseState; +static void TwoPhaseShmemRequest(void *arg); +static void TwoPhaseShmemInit(void *arg); + +const ShmemCallbacks TwoPhaseShmemCallbacks = { + .request_fn = TwoPhaseShmemRequest, + .init_fn = TwoPhaseShmemInit, +}; + /* * Global transaction entry currently locked by us, if any. Note that any * access to the entry pointed to by this variable must be protected by @@ -234,10 +243,10 @@ static void RemoveTwoPhaseFile(FullTransactionId fxid, bool giveWarning); static void RecreateTwoPhaseFile(FullTransactionId fxid, void *content, int len); /* - * Initialization of shared memory + * Register shared memory for two-phase state. */ -Size -TwoPhaseShmemSize(void) +static void +TwoPhaseShmemRequest(void *arg) { Size size; @@ -248,46 +257,40 @@ TwoPhaseShmemSize(void) size = MAXALIGN(size); size = add_size(size, mul_size(max_prepared_xacts, sizeof(GlobalTransactionData))); - - return size; + ShmemRequestStruct(.name = "Prepared Transaction Table", + .size = size, + .ptr = (void **) &TwoPhaseState, + ); } -void -TwoPhaseShmemInit(void) +/* + * Initialize shared memory for two-phase state. + */ +static void +TwoPhaseShmemInit(void *arg) { - bool found; - - TwoPhaseState = ShmemInitStruct("Prepared Transaction Table", - TwoPhaseShmemSize(), - &found); - if (!IsUnderPostmaster) - { - GlobalTransaction gxacts; - int i; + GlobalTransaction gxacts; + int i; - Assert(!found); - TwoPhaseState->freeGXacts = NULL; - TwoPhaseState->numPrepXacts = 0; + TwoPhaseState->freeGXacts = NULL; + TwoPhaseState->numPrepXacts = 0; - /* - * Initialize the linked list of free GlobalTransactionData structs - */ - gxacts = (GlobalTransaction) - ((char *) TwoPhaseState + - MAXALIGN(offsetof(TwoPhaseStateData, prepXacts) + - sizeof(GlobalTransaction) * max_prepared_xacts)); - for (i = 0; i < max_prepared_xacts; i++) - { - /* insert into linked list */ - gxacts[i].next = TwoPhaseState->freeGXacts; - TwoPhaseState->freeGXacts = &gxacts[i]; + /* + * Initialize the linked list of free GlobalTransactionData structs + */ + gxacts = (GlobalTransaction) + ((char *) TwoPhaseState + + MAXALIGN(offsetof(TwoPhaseStateData, prepXacts) + + sizeof(GlobalTransaction) * max_prepared_xacts)); + for (i = 0; i < max_prepared_xacts; i++) + { + /* insert into linked list */ + gxacts[i].next = TwoPhaseState->freeGXacts; + TwoPhaseState->freeGXacts = &gxacts[i]; - /* associate it with a PGPROC assigned by ProcGlobalShmemInit */ - gxacts[i].pgprocno = GetNumberFromPGProc(&PreparedXactProcs[i]); - } + /* associate it with a PGPROC assigned by ProcGlobalShmemInit */ + gxacts[i].pgprocno = GetNumberFromPGProc(&PreparedXactProcs[i]); } - else - Assert(found); } /* diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 9e8999bbb61..b82af9a85c0 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -96,6 +96,7 @@ #include "storage/procsignal.h" #include "storage/reinit.h" #include "storage/spin.h" +#include "storage/subsystems.h" #include "storage/sync.h" #include "utils/guc_hooks.h" #include "utils/guc_tables.h" @@ -579,8 +580,19 @@ static WALInsertLockPadded *WALInsertLocks = NULL; /* * We maintain an image of pg_control in shared memory. */ +static ControlFileData *LocalControlFile = NULL; static ControlFileData *ControlFile = NULL; +static void XLOGShmemRequest(void *arg); +static void XLOGShmemInit(void *arg); +static void XLOGShmemAttach(void *arg); + +const ShmemCallbacks XLOGShmemCallbacks = { + .request_fn = XLOGShmemRequest, + .init_fn = XLOGShmemInit, + .attach_fn = XLOGShmemAttach, +}; + /* * Calculate the amount of space left on the page after 'endptr'. Beware * multiple evaluation! @@ -5257,7 +5269,8 @@ void LocalProcessControlFile(bool reset) { Assert(reset || ControlFile == NULL); - ControlFile = palloc_object(ControlFileData); + LocalControlFile = palloc_object(ControlFileData); + ControlFile = LocalControlFile; ReadControlFile(); SetLocalDataChecksumState(ControlFile->data_checksum_version); } @@ -5274,10 +5287,10 @@ GetActiveWalLevelOnStandby(void) } /* - * Initialization of shared memory for XLOG + * Register shared memory for XLOG. */ -Size -XLOGShmemSize(void) +static void +XLOGShmemRequest(void *arg) { Size size; @@ -5317,23 +5330,24 @@ XLOGShmemSize(void) /* and the buffers themselves */ size = add_size(size, mul_size(XLOG_BLCKSZ, XLOGbuffers)); - /* - * Note: we don't count ControlFileData, it comes out of the "slop factor" - * added by CreateSharedMemoryAndSemaphores. This lets us use this - * routine again below to compute the actual allocation size. - */ - - return size; + ShmemRequestStruct(.name = "XLOG Ctl", + .size = size, + .ptr = (void **) &XLogCtl, + ); + ShmemRequestStruct(.name = "Control File", + .size = sizeof(ControlFileData), + .ptr = (void **) &ControlFile, + ); } -void -XLOGShmemInit(void) +/* + * XLOGShmemInit - initialize the XLogCtl shared memory area. + */ +static void +XLOGShmemInit(void *arg) { - bool foundCFile, - foundXLog; char *allocptr; int i; - ControlFileData *localControlFile; #ifdef WAL_DEBUG @@ -5351,36 +5365,17 @@ XLOGShmemInit(void) } #endif - - XLogCtl = (XLogCtlData *) - ShmemInitStruct("XLOG Ctl", XLOGShmemSize(), &foundXLog); - - localControlFile = ControlFile; - ControlFile = (ControlFileData *) - ShmemInitStruct("Control File", sizeof(ControlFileData), &foundCFile); - - if (foundCFile || foundXLog) - { - /* both should be present or neither */ - Assert(foundCFile && foundXLog); - - /* Initialize local copy of WALInsertLocks */ - WALInsertLocks = XLogCtl->Insert.WALInsertLocks; - - if (localControlFile) - pfree(localControlFile); - return; - } memset(XLogCtl, 0, sizeof(XLogCtlData)); /* * Already have read control file locally, unless in bootstrap mode. Move * contents into shared memory. */ - if (localControlFile) + if (LocalControlFile) { - memcpy(ControlFile, localControlFile, sizeof(ControlFileData)); - pfree(localControlFile); + memcpy(ControlFile, LocalControlFile, sizeof(ControlFileData)); + pfree(LocalControlFile); + LocalControlFile = NULL; } /* @@ -5442,6 +5437,15 @@ XLOGShmemInit(void) pg_atomic_init_u64(&XLogCtl->unloggedLSN, InvalidXLogRecPtr); } +/* + * XLOGShmemAttach - re-establish WALInsertLocks pointer after attaching. + */ +static void +XLOGShmemAttach(void *arg) +{ + WALInsertLocks = XLogCtl->Insert.WALInsertLocks; +} + /* * This func must be called ONCE on system install. It creates pg_control * and the initial XLOG segment. diff --git a/src/backend/access/transam/xlogprefetcher.c b/src/backend/access/transam/xlogprefetcher.c index c235eca7c51..83a3f97a57c 100644 --- a/src/backend/access/transam/xlogprefetcher.c +++ b/src/backend/access/transam/xlogprefetcher.c @@ -39,6 +39,7 @@ #include "storage/fd.h" #include "storage/shmem.h" #include "storage/smgr.h" +#include "storage/subsystems.h" #include "utils/fmgrprotos.h" #include "utils/guc_hooks.h" #include "utils/hsearch.h" @@ -200,6 +201,14 @@ static LsnReadQueueNextStatus XLogPrefetcherNextBlock(uintptr_t pgsr_private, static XLogPrefetchStats *SharedStats; +static void XLogPrefetchShmemRequest(void *arg); +static void XLogPrefetchShmemInit(void *arg); + +const ShmemCallbacks XLogPrefetchShmemCallbacks = { + .request_fn = XLogPrefetchShmemRequest, + .init_fn = XLogPrefetchShmemInit, +}; + static inline LsnReadQueue * lrq_alloc(uint32 max_distance, uint32 max_inflight, @@ -292,10 +301,25 @@ lrq_complete_lsn(LsnReadQueue *lrq, XLogRecPtr lsn) lrq_prefetch(lrq); } -size_t -XLogPrefetchShmemSize(void) +static void +XLogPrefetchShmemRequest(void *arg) +{ + ShmemRequestStruct(.name = "XLogPrefetchStats", + .size = sizeof(XLogPrefetchStats), + .ptr = (void **) &SharedStats, + ); +} + +static void +XLogPrefetchShmemInit(void *arg) { - return sizeof(XLogPrefetchStats); + pg_atomic_init_u64(&SharedStats->reset_time, GetCurrentTimestamp()); + pg_atomic_init_u64(&SharedStats->prefetch, 0); + pg_atomic_init_u64(&SharedStats->hit, 0); + pg_atomic_init_u64(&SharedStats->skip_init, 0); + pg_atomic_init_u64(&SharedStats->skip_new, 0); + pg_atomic_init_u64(&SharedStats->skip_fpw, 0); + pg_atomic_init_u64(&SharedStats->skip_rep, 0); } /* @@ -313,27 +337,6 @@ XLogPrefetchResetStats(void) pg_atomic_write_u64(&SharedStats->skip_rep, 0); } -void -XLogPrefetchShmemInit(void) -{ - bool found; - - SharedStats = (XLogPrefetchStats *) - ShmemInitStruct("XLogPrefetchStats", - sizeof(XLogPrefetchStats), - &found); - - if (!found) - { - pg_atomic_init_u64(&SharedStats->reset_time, GetCurrentTimestamp()); - pg_atomic_init_u64(&SharedStats->prefetch, 0); - pg_atomic_init_u64(&SharedStats->hit, 0); - pg_atomic_init_u64(&SharedStats->skip_init, 0); - pg_atomic_init_u64(&SharedStats->skip_new, 0); - pg_atomic_init_u64(&SharedStats->skip_fpw, 0); - pg_atomic_init_u64(&SharedStats->skip_rep, 0); - } -} /* * Called when any GUC is changed that affects prefetching. diff --git a/src/backend/access/transam/xlogrecovery.c b/src/backend/access/transam/xlogrecovery.c index fd1c36d061d..c236e2b7969 100644 --- a/src/backend/access/transam/xlogrecovery.c +++ b/src/backend/access/transam/xlogrecovery.c @@ -58,6 +58,7 @@ #include "storage/pmsignal.h" #include "storage/procarray.h" #include "storage/spin.h" +#include "storage/subsystems.h" #include "utils/datetime.h" #include "utils/fmgrprotos.h" #include "utils/guc_hooks.h" @@ -307,6 +308,14 @@ static char *primary_image_masked = NULL; XLogRecoveryCtlData *XLogRecoveryCtl = NULL; +static void XLogRecoveryShmemRequest(void *arg); +static void XLogRecoveryShmemInit(void *arg); + +const ShmemCallbacks XLogRecoveryShmemCallbacks = { + .request_fn = XLogRecoveryShmemRequest, + .init_fn = XLogRecoveryShmemInit, +}; + /* * abortedRecPtr is the start pointer of a broken record at end of WAL when * recovery completes; missingContrecPtr is the location of the first @@ -385,28 +394,20 @@ static void SetCurrentChunkStartTime(TimestampTz xtime); static void SetLatestXTime(TimestampTz xtime); /* - * Initialization of shared memory for WAL recovery + * Register shared memory for WAL recovery */ -Size -XLogRecoveryShmemSize(void) +static void +XLogRecoveryShmemRequest(void *arg) { - Size size; - - /* XLogRecoveryCtl */ - size = sizeof(XLogRecoveryCtlData); - - return size; + ShmemRequestStruct(.name = "XLOG Recovery Ctl", + .size = sizeof(XLogRecoveryCtlData), + .ptr = (void **) &XLogRecoveryCtl, + ); } -void -XLogRecoveryShmemInit(void) +static void +XLogRecoveryShmemInit(void *arg) { - bool found; - - XLogRecoveryCtl = (XLogRecoveryCtlData *) - ShmemInitStruct("XLOG Recovery Ctl", XLogRecoveryShmemSize(), &found); - if (found) - return; memset(XLogRecoveryCtl, 0, sizeof(XLogRecoveryCtlData)); SpinLockInit(&XLogRecoveryCtl->info_lck); diff --git a/src/backend/access/transam/xlogwait.c b/src/backend/access/transam/xlogwait.c index bf4630677b4..2e31c0d67d7 100644 --- a/src/backend/access/transam/xlogwait.c +++ b/src/backend/access/transam/xlogwait.c @@ -57,6 +57,7 @@ #include "storage/latch.h" #include "storage/proc.h" #include "storage/shmem.h" +#include "storage/subsystems.h" #include "utils/fmgrprotos.h" #include "utils/pg_lsn.h" #include "utils/snapmgr.h" @@ -68,6 +69,14 @@ static int waitlsn_cmp(const pairingheap_node *a, const pairingheap_node *b, struct WaitLSNState *waitLSNState = NULL; +static void WaitLSNShmemRequest(void *arg); +static void WaitLSNShmemInit(void *arg); + +const ShmemCallbacks WaitLSNShmemCallbacks = { + .request_fn = WaitLSNShmemRequest, + .init_fn = WaitLSNShmemInit, +}; + /* * Wait event for each WaitLSNType, used with WaitLatch() to report * the wait in pg_stat_activity. @@ -109,41 +118,34 @@ GetCurrentLSNForWaitType(WaitLSNType lsnType) pg_unreachable(); } -/* Report the amount of shared memory space needed for WaitLSNState. */ -Size -WaitLSNShmemSize(void) +/* Register the shared memory space needed for WaitLSNState. */ +static void +WaitLSNShmemRequest(void *arg) { Size size; size = offsetof(WaitLSNState, procInfos); size = add_size(size, mul_size(MaxBackends + NUM_AUXILIARY_PROCS, sizeof(WaitLSNProcInfo))); - return size; + ShmemRequestStruct(.name = "WaitLSNState", + .size = size, + .ptr = (void **) &waitLSNState, + ); } /* Initialize the WaitLSNState in the shared memory. */ -void -WaitLSNShmemInit(void) +static void +WaitLSNShmemInit(void *arg) { - bool found; - - waitLSNState = (WaitLSNState *) ShmemInitStruct("WaitLSNState", - WaitLSNShmemSize(), - &found); - if (!found) + /* Initialize heaps and tracking */ + for (int i = 0; i < WAIT_LSN_TYPE_COUNT; i++) { - int i; - - /* Initialize heaps and tracking */ - for (i = 0; i < WAIT_LSN_TYPE_COUNT; i++) - { - pg_atomic_init_u64(&waitLSNState->minWaitedLSN[i], PG_UINT64_MAX); - pairingheap_initialize(&waitLSNState->waitersHeap[i], waitlsn_cmp, NULL); - } - - /* Initialize process info array */ - memset(&waitLSNState->procInfos, 0, - (MaxBackends + NUM_AUXILIARY_PROCS) * sizeof(WaitLSNProcInfo)); + pg_atomic_init_u64(&waitLSNState->minWaitedLSN[i], PG_UINT64_MAX); + pairingheap_initialize(&waitLSNState->waitersHeap[i], waitlsn_cmp, NULL); } + + /* Initialize process info array */ + memset(&waitLSNState->procInfos, 0, + (MaxBackends + NUM_AUXILIARY_PROCS) * sizeof(WaitLSNProcInfo)); } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index 8400e6722cc..250c43b85e5 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -98,6 +98,7 @@ #include "storage/proc.h" #include "storage/procsignal.h" #include "storage/smgr.h" +#include "storage/subsystems.h" #include "tcop/tcopprot.h" #include "utils/fmgroids.h" #include "utils/fmgrprotos.h" @@ -309,6 +310,14 @@ typedef struct static AutoVacuumShmemStruct *AutoVacuumShmem; +static void AutoVacuumShmemRequest(void *arg); +static void AutoVacuumShmemInit(void *arg); + +const ShmemCallbacks AutoVacuumShmemCallbacks = { + .request_fn = AutoVacuumShmemRequest, + .init_fn = AutoVacuumShmemInit, +}; + /* * the database list (of avl_dbase elements) in the launcher, and the context * that contains it @@ -3545,11 +3554,11 @@ autovac_init(void) } /* - * AutoVacuumShmemSize - * Compute space needed for autovacuum-related shared memory + * AutoVacuumShmemRequest + * Register shared memory space needed for autovacuum */ -Size -AutoVacuumShmemSize(void) +static void +AutoVacuumShmemRequest(void *arg) { Size size; @@ -3560,53 +3569,41 @@ AutoVacuumShmemSize(void) size = MAXALIGN(size); size = add_size(size, mul_size(autovacuum_worker_slots, sizeof(WorkerInfoData))); - return size; + + ShmemRequestStruct(.name = "AutoVacuum Data", + .size = size, + .ptr = (void **) &AutoVacuumShmem, + ); } /* * AutoVacuumShmemInit - * Allocate and initialize autovacuum-related shared memory + * Initialize autovacuum-related shared memory */ -void -AutoVacuumShmemInit(void) +static void +AutoVacuumShmemInit(void *arg) { - bool found; - - AutoVacuumShmem = (AutoVacuumShmemStruct *) - ShmemInitStruct("AutoVacuum Data", - AutoVacuumShmemSize(), - &found); - - if (!IsUnderPostmaster) - { - WorkerInfo worker; - int i; + WorkerInfo worker; - Assert(!found); - - AutoVacuumShmem->av_launcherpid = 0; - dclist_init(&AutoVacuumShmem->av_freeWorkers); - dlist_init(&AutoVacuumShmem->av_runningWorkers); - AutoVacuumShmem->av_startingWorker = NULL; - memset(AutoVacuumShmem->av_workItems, 0, - sizeof(AutoVacuumWorkItem) * NUM_WORKITEMS); - - worker = (WorkerInfo) ((char *) AutoVacuumShmem + - MAXALIGN(sizeof(AutoVacuumShmemStruct))); - - /* initialize the WorkerInfo free list */ - for (i = 0; i < autovacuum_worker_slots; i++) - { - dclist_push_head(&AutoVacuumShmem->av_freeWorkers, - &worker[i].wi_links); - pg_atomic_init_flag(&worker[i].wi_dobalance); - } + AutoVacuumShmem->av_launcherpid = 0; + dclist_init(&AutoVacuumShmem->av_freeWorkers); + dlist_init(&AutoVacuumShmem->av_runningWorkers); + AutoVacuumShmem->av_startingWorker = NULL; + memset(AutoVacuumShmem->av_workItems, 0, + sizeof(AutoVacuumWorkItem) * NUM_WORKITEMS); - pg_atomic_init_u32(&AutoVacuumShmem->av_nworkersForBalance, 0); + worker = (WorkerInfo) ((char *) AutoVacuumShmem + + MAXALIGN(sizeof(AutoVacuumShmemStruct))); + /* initialize the WorkerInfo free list */ + for (int i = 0; i < autovacuum_worker_slots; i++) + { + dclist_push_head(&AutoVacuumShmem->av_freeWorkers, + &worker[i].wi_links); + pg_atomic_init_flag(&worker[i].wi_dobalance); } - else - Assert(found); + + pg_atomic_init_u32(&AutoVacuumShmem->av_nworkersForBalance, 0); } /* diff --git a/src/backend/postmaster/bgworker.c b/src/backend/postmaster/bgworker.c index 536aff7ca05..0992b9b6353 100644 --- a/src/backend/postmaster/bgworker.c +++ b/src/backend/postmaster/bgworker.c @@ -30,6 +30,7 @@ #include "storage/procarray.h" #include "storage/procsignal.h" #include "storage/shmem.h" +#include "storage/subsystems.h" #include "tcop/tcopprot.h" #include "utils/ascii.h" #include "utils/memutils.h" @@ -110,6 +111,14 @@ struct BackgroundWorkerHandle static BackgroundWorkerArray *BackgroundWorkerData; +static void BackgroundWorkerShmemRequest(void *arg); +static void BackgroundWorkerShmemInit(void *arg); + +const ShmemCallbacks BackgroundWorkerShmemCallbacks = { + .request_fn = BackgroundWorkerShmemRequest, + .init_fn = BackgroundWorkerShmemInit, +}; + /* * List of internal background worker entry points. We need this for * reasons explained in LookupBackgroundWorkerFunction(), below. @@ -160,10 +169,10 @@ static bgworker_main_type LookupBackgroundWorkerFunction(const char *libraryname /* - * Calculate shared memory needed. + * Register shared memory needed for background workers. */ -Size -BackgroundWorkerShmemSize(void) +static void +BackgroundWorkerShmemRequest(void *arg) { Size size; @@ -171,66 +180,58 @@ BackgroundWorkerShmemSize(void) size = offsetof(BackgroundWorkerArray, slot); size = add_size(size, mul_size(max_worker_processes, sizeof(BackgroundWorkerSlot))); - - return size; + ShmemRequestStruct(.name = "Background Worker Data", + .size = size, + .ptr = (void **) &BackgroundWorkerData, + ); } /* - * Initialize shared memory. + * Initialize shared memory for background workers. */ -void -BackgroundWorkerShmemInit(void) +static void +BackgroundWorkerShmemInit(void *arg) { - bool found; - - BackgroundWorkerData = ShmemInitStruct("Background Worker Data", - BackgroundWorkerShmemSize(), - &found); - if (!IsUnderPostmaster) - { - dlist_iter iter; - int slotno = 0; + dlist_iter iter; + int slotno = 0; - BackgroundWorkerData->total_slots = max_worker_processes; - BackgroundWorkerData->parallel_register_count = 0; - BackgroundWorkerData->parallel_terminate_count = 0; + BackgroundWorkerData->total_slots = max_worker_processes; + BackgroundWorkerData->parallel_register_count = 0; + BackgroundWorkerData->parallel_terminate_count = 0; - /* - * Copy contents of worker list into shared memory. Record the shared - * memory slot assigned to each worker. This ensures a 1-to-1 - * correspondence between the postmaster's private list and the array - * in shared memory. - */ - dlist_foreach(iter, &BackgroundWorkerList) - { - BackgroundWorkerSlot *slot = &BackgroundWorkerData->slot[slotno]; - RegisteredBgWorker *rw; + /* + * Copy contents of worker list into shared memory. Record the shared + * memory slot assigned to each worker. This ensures a 1-to-1 + * correspondence between the postmaster's private list and the array in + * shared memory. + */ + dlist_foreach(iter, &BackgroundWorkerList) + { + BackgroundWorkerSlot *slot = &BackgroundWorkerData->slot[slotno]; + RegisteredBgWorker *rw; - rw = dlist_container(RegisteredBgWorker, rw_lnode, iter.cur); - Assert(slotno < max_worker_processes); - slot->in_use = true; - slot->terminate = false; - slot->pid = InvalidPid; - slot->generation = 0; - rw->rw_shmem_slot = slotno; - rw->rw_worker.bgw_notify_pid = 0; /* might be reinit after crash */ - memcpy(&slot->worker, &rw->rw_worker, sizeof(BackgroundWorker)); - ++slotno; - } + rw = dlist_container(RegisteredBgWorker, rw_lnode, iter.cur); + Assert(slotno < max_worker_processes); + slot->in_use = true; + slot->terminate = false; + slot->pid = InvalidPid; + slot->generation = 0; + rw->rw_shmem_slot = slotno; + rw->rw_worker.bgw_notify_pid = 0; /* might be reinit after crash */ + memcpy(&slot->worker, &rw->rw_worker, sizeof(BackgroundWorker)); + ++slotno; + } - /* - * Mark any remaining slots as not in use. - */ - while (slotno < max_worker_processes) - { - BackgroundWorkerSlot *slot = &BackgroundWorkerData->slot[slotno]; + /* + * Mark any remaining slots as not in use. + */ + while (slotno < max_worker_processes) + { + BackgroundWorkerSlot *slot = &BackgroundWorkerData->slot[slotno]; - slot->in_use = false; - ++slotno; - } + slot->in_use = false; + ++slotno; } - else - Assert(found); } /* diff --git a/src/backend/postmaster/checkpointer.c b/src/backend/postmaster/checkpointer.c index 3c982c6ffac..6b424ee610f 100644 --- a/src/backend/postmaster/checkpointer.c +++ b/src/backend/postmaster/checkpointer.c @@ -63,6 +63,7 @@ #include "storage/shmem.h" #include "storage/smgr.h" #include "storage/spin.h" +#include "storage/subsystems.h" #include "utils/acl.h" #include "utils/guc.h" #include "utils/memutils.h" @@ -143,6 +144,14 @@ typedef struct static CheckpointerShmemStruct *CheckpointerShmem; +static void CheckpointerShmemRequest(void *arg); +static void CheckpointerShmemInit(void *arg); + +const ShmemCallbacks CheckpointerShmemCallbacks = { + .request_fn = CheckpointerShmemRequest, + .init_fn = CheckpointerShmemInit, +}; + /* interval for calling AbsorbSyncRequests in CheckpointWriteDelay */ #define WRITES_PER_ABSORB 1000 @@ -950,11 +959,11 @@ ReqShutdownXLOG(SIGNAL_ARGS) */ /* - * CheckpointerShmemSize - * Compute space needed for checkpointer-related shared memory + * CheckpointerShmemRequest + * Register shared memory space needed for checkpointer */ -Size -CheckpointerShmemSize(void) +static void +CheckpointerShmemRequest(void *arg) { Size size; @@ -967,39 +976,24 @@ CheckpointerShmemSize(void) size = add_size(size, mul_size(Min(NBuffers, MAX_CHECKPOINT_REQUESTS), sizeof(CheckpointerRequest))); - - return size; + ShmemRequestStruct(.name = "Checkpointer Data", + .size = size, + .ptr = (void **) &CheckpointerShmem, + ); } /* * CheckpointerShmemInit - * Allocate and initialize checkpointer-related shared memory + * Initialize checkpointer-related shared memory */ -void -CheckpointerShmemInit(void) +static void +CheckpointerShmemInit(void *arg) { - Size size = CheckpointerShmemSize(); - bool found; - - CheckpointerShmem = (CheckpointerShmemStruct *) - ShmemInitStruct("Checkpointer Data", - size, - &found); - - if (!found) - { - /* - * First time through, so initialize. Note that we zero the whole - * requests array; this is so that CompactCheckpointerRequestQueue can - * assume that any pad bytes in the request structs are zeroes. - */ - MemSet(CheckpointerShmem, 0, size); - SpinLockInit(&CheckpointerShmem->ckpt_lck); - CheckpointerShmem->max_requests = Min(NBuffers, MAX_CHECKPOINT_REQUESTS); - CheckpointerShmem->head = CheckpointerShmem->tail = 0; - ConditionVariableInit(&CheckpointerShmem->start_cv); - ConditionVariableInit(&CheckpointerShmem->done_cv); - } + SpinLockInit(&CheckpointerShmem->ckpt_lck); + CheckpointerShmem->max_requests = Min(NBuffers, MAX_CHECKPOINT_REQUESTS); + CheckpointerShmem->head = CheckpointerShmem->tail = 0; + ConditionVariableInit(&CheckpointerShmem->start_cv); + ConditionVariableInit(&CheckpointerShmem->done_cv); } /* diff --git a/src/backend/postmaster/datachecksum_state.c b/src/backend/postmaster/datachecksum_state.c index 76004bcedc6..eb7b01d0993 100644 --- a/src/backend/postmaster/datachecksum_state.c +++ b/src/backend/postmaster/datachecksum_state.c @@ -211,6 +211,7 @@ #include "storage/lwlock.h" #include "storage/procarray.h" #include "storage/smgr.h" +#include "storage/subsystems.h" #include "tcop/tcopprot.h" #include "utils/builtins.h" #include "utils/fmgroids.h" @@ -346,6 +347,7 @@ static volatile sig_atomic_t launcher_running = false; static DataChecksumsWorkerOperation operation; /* Prototypes */ +static void DataChecksumsShmemRequest(void *arg); static bool DatabaseExists(Oid dboid); static List *BuildDatabaseList(void); static List *BuildRelationList(bool temp_relations, bool include_shared); @@ -356,6 +358,10 @@ static bool ProcessSingleRelationFork(Relation reln, ForkNumber forkNum, BufferA static void launcher_cancel_handler(SIGNAL_ARGS); static void WaitForAllTransactionsToFinish(void); +const ShmemCallbacks DataChecksumsShmemCallbacks = { + .request_fn = DataChecksumsShmemRequest, +}; + /***************************************************************************** * Functionality for manipulating the data checksum state in the cluster */ @@ -1236,35 +1242,16 @@ ProcessAllDatabases(void) } /* - * DataChecksumStateSize - * Compute required space for datachecksumsworker-related shared memory - */ -Size -DataChecksumsShmemSize(void) -{ - Size size; - - size = sizeof(DataChecksumsStateStruct); - size = MAXALIGN(size); - - return size; -} - -/* - * DataChecksumStateInit - * Allocate and initialize datachecksumsworker-related shared memory + * DataChecksumShmemRequest + * Request datachecksumsworker-related shared memory */ -void -DataChecksumsShmemInit(void) +static void +DataChecksumsShmemRequest(void *arg) { - bool found; - - DataChecksumState = (DataChecksumsStateStruct *) - ShmemInitStruct("DataChecksumsWorker Data", - DataChecksumsShmemSize(), - &found); - if (!found) - MemSet(DataChecksumState, 0, DataChecksumsShmemSize()); + ShmemRequestStruct(.name = "DataChecksumsWorker Data", + .size = sizeof(DataChecksumsStateStruct), + .ptr = (void **) &DataChecksumState, + ); } /* diff --git a/src/backend/postmaster/pgarch.c b/src/backend/postmaster/pgarch.c index fa4bdfe9ab9..0a1a1149d78 100644 --- a/src/backend/postmaster/pgarch.c +++ b/src/backend/postmaster/pgarch.c @@ -48,6 +48,7 @@ #include "storage/proc.h" #include "storage/procsignal.h" #include "storage/shmem.h" +#include "storage/subsystems.h" #include "utils/guc.h" #include "utils/memutils.h" #include "utils/ps_status.h" @@ -154,33 +155,31 @@ static int ready_file_comparator(Datum a, Datum b, void *arg); static void LoadArchiveLibrary(void); static void pgarch_call_module_shutdown_cb(int code, Datum arg); -/* Report shared memory space needed by PgArchShmemInit */ -Size -PgArchShmemSize(void) -{ - Size size = 0; +static void PgArchShmemRequest(void *arg); +static void PgArchShmemInit(void *arg); - size = add_size(size, sizeof(PgArchData)); +const ShmemCallbacks PgArchShmemCallbacks = { + .request_fn = PgArchShmemRequest, + .init_fn = PgArchShmemInit, +}; - return size; +/* Register shared memory space needed by the archiver */ +static void +PgArchShmemRequest(void *arg) +{ + ShmemRequestStruct(.name = "Archiver Data", + .size = sizeof(PgArchData), + .ptr = (void **) &PgArch, + ); } -/* Allocate and initialize archiver-related shared memory */ -void -PgArchShmemInit(void) +/* Initialize archiver-related shared memory */ +static void +PgArchShmemInit(void *arg) { - bool found; - - PgArch = (PgArchData *) - ShmemInitStruct("Archiver Data", PgArchShmemSize(), &found); - - if (!found) - { - /* First time through, so initialize */ - MemSet(PgArch, 0, PgArchShmemSize()); - PgArch->pgprocno = INVALID_PROC_NUMBER; - pg_atomic_init_u32(&PgArch->force_dir_scan, 0); - } + MemSet(PgArch, 0, sizeof(PgArchData)); + PgArch->pgprocno = INVALID_PROC_NUMBER; + pg_atomic_init_u32(&PgArch->force_dir_scan, 0); } /* diff --git a/src/backend/postmaster/walsummarizer.c b/src/backend/postmaster/walsummarizer.c index a37b3018abf..20960f5b633 100644 --- a/src/backend/postmaster/walsummarizer.c +++ b/src/backend/postmaster/walsummarizer.c @@ -47,6 +47,7 @@ #include "storage/proc.h" #include "storage/procsignal.h" #include "storage/shmem.h" +#include "storage/subsystems.h" #include "utils/guc.h" #include "utils/memutils.h" #include "utils/wait_event.h" @@ -109,6 +110,14 @@ typedef struct /* Pointer to shared memory state. */ static WalSummarizerData *WalSummarizerCtl; +static void WalSummarizerShmemRequest(void *arg); +static void WalSummarizerShmemInit(void *arg); + +const ShmemCallbacks WalSummarizerShmemCallbacks = { + .request_fn = WalSummarizerShmemRequest, + .init_fn = WalSummarizerShmemInit, +}; + /* * When we reach end of WAL and need to read more, we sleep for a number of * milliseconds that is an integer multiple of MS_PER_SLEEP_QUANTUM. This is @@ -168,43 +177,34 @@ static void summarizer_wait_for_wal(void); static void MaybeRemoveOldWalSummaries(void); /* - * Amount of shared memory required for this module. + * Register shared memory space needed by this module. */ -Size -WalSummarizerShmemSize(void) +static void +WalSummarizerShmemRequest(void *arg) { - return sizeof(WalSummarizerData); + ShmemRequestStruct(.name = "Wal Summarizer Ctl", + .size = sizeof(WalSummarizerData), + .ptr = (void **) &WalSummarizerCtl, + ); } /* - * Create or attach to shared memory segment for this module. + * Initialize shared memory for this module. */ -void -WalSummarizerShmemInit(void) +static void +WalSummarizerShmemInit(void *arg) { - bool found; - - WalSummarizerCtl = (WalSummarizerData *) - ShmemInitStruct("Wal Summarizer Ctl", WalSummarizerShmemSize(), - &found); - - if (!found) - { - /* - * First time through, so initialize. - * - * We're just filling in dummy values here -- the real initialization - * will happen when GetOldestUnsummarizedLSN() is called for the first - * time. - */ - WalSummarizerCtl->initialized = false; - WalSummarizerCtl->summarized_tli = 0; - WalSummarizerCtl->summarized_lsn = InvalidXLogRecPtr; - WalSummarizerCtl->lsn_is_exact = false; - WalSummarizerCtl->summarizer_pgprocno = INVALID_PROC_NUMBER; - WalSummarizerCtl->pending_lsn = InvalidXLogRecPtr; - ConditionVariableInit(&WalSummarizerCtl->summary_file_cv); - } + /* + * We're just filling in dummy values here -- the real initialization will + * happen when GetOldestUnsummarizedLSN() is called for the first time. + */ + WalSummarizerCtl->initialized = false; + WalSummarizerCtl->summarized_tli = 0; + WalSummarizerCtl->summarized_lsn = InvalidXLogRecPtr; + WalSummarizerCtl->lsn_is_exact = false; + WalSummarizerCtl->summarizer_pgprocno = INVALID_PROC_NUMBER; + WalSummarizerCtl->pending_lsn = InvalidXLogRecPtr; + ConditionVariableInit(&WalSummarizerCtl->summary_file_cv); } /* diff --git a/src/backend/replication/logical/launcher.c b/src/backend/replication/logical/launcher.c index 09964198550..9e75a3e04ee 100644 --- a/src/backend/replication/logical/launcher.c +++ b/src/backend/replication/logical/launcher.c @@ -38,6 +38,7 @@ #include "storage/ipc.h" #include "storage/proc.h" #include "storage/procarray.h" +#include "storage/subsystems.h" #include "tcop/tcopprot.h" #include "utils/builtins.h" #include "utils/memutils.h" @@ -71,6 +72,14 @@ typedef struct LogicalRepCtxStruct static LogicalRepCtxStruct *LogicalRepCtx; +static void ApplyLauncherShmemRequest(void *arg); +static void ApplyLauncherShmemInit(void *arg); + +const ShmemCallbacks ApplyLauncherShmemCallbacks = { + .request_fn = ApplyLauncherShmemRequest, + .init_fn = ApplyLauncherShmemInit, +}; + /* an entry in the last-start-times shared hash table */ typedef struct LauncherLastStartTimesEntry { @@ -972,11 +981,11 @@ logicalrep_pa_worker_count(Oid subid) } /* - * ApplyLauncherShmemSize - * Compute space needed for replication launcher shared memory + * ApplyLauncherShmemRequest + * Register shared memory space needed for replication launcher */ -Size -ApplyLauncherShmemSize(void) +static void +ApplyLauncherShmemRequest(void *arg) { Size size; @@ -987,7 +996,10 @@ ApplyLauncherShmemSize(void) size = MAXALIGN(size); size = add_size(size, mul_size(max_logical_replication_workers, sizeof(LogicalRepWorker))); - return size; + ShmemRequestStruct(.name = "Logical Replication Launcher Data", + .size = size, + .ptr = (void **) &LogicalRepCtx, + ); } /* @@ -1028,35 +1040,23 @@ ApplyLauncherRegister(void) /* * ApplyLauncherShmemInit - * Allocate and initialize replication launcher shared memory + * Initialize replication launcher shared memory */ -void -ApplyLauncherShmemInit(void) +static void +ApplyLauncherShmemInit(void *arg) { - bool found; + int slot; - LogicalRepCtx = (LogicalRepCtxStruct *) - ShmemInitStruct("Logical Replication Launcher Data", - ApplyLauncherShmemSize(), - &found); + LogicalRepCtx->last_start_dsa = DSA_HANDLE_INVALID; + LogicalRepCtx->last_start_dsh = DSHASH_HANDLE_INVALID; - if (!found) + /* Initialize memory and spin locks for each worker slot. */ + for (slot = 0; slot < max_logical_replication_workers; slot++) { - int slot; - - memset(LogicalRepCtx, 0, ApplyLauncherShmemSize()); - - LogicalRepCtx->last_start_dsa = DSA_HANDLE_INVALID; - LogicalRepCtx->last_start_dsh = DSHASH_HANDLE_INVALID; + LogicalRepWorker *worker = &LogicalRepCtx->workers[slot]; - /* Initialize memory and spin locks for each worker slot. */ - for (slot = 0; slot < max_logical_replication_workers; slot++) - { - LogicalRepWorker *worker = &LogicalRepCtx->workers[slot]; - - memset(worker, 0, sizeof(LogicalRepWorker)); - SpinLockInit(&worker->relmutex); - } + memset(worker, 0, sizeof(LogicalRepWorker)); + SpinLockInit(&worker->relmutex); } } diff --git a/src/backend/replication/logical/logicalctl.c b/src/backend/replication/logical/logicalctl.c index 4e292951201..72f68ec58ef 100644 --- a/src/backend/replication/logical/logicalctl.c +++ b/src/backend/replication/logical/logicalctl.c @@ -72,6 +72,7 @@ #include "storage/proc.h" #include "storage/procarray.h" #include "storage/procsignal.h" +#include "storage/subsystems.h" #include "utils/injection_point.h" /* @@ -98,6 +99,12 @@ typedef struct LogicalDecodingCtlData static LogicalDecodingCtlData *LogicalDecodingCtl = NULL; +static void LogicalDecodingCtlShmemRequest(void *arg); + +const ShmemCallbacks LogicalDecodingCtlShmemCallbacks = { + .request_fn = LogicalDecodingCtlShmemRequest, +}; + /* * A process-local cache of LogicalDecodingCtl->xlog_logical_info. This is * initialized at process startup, and updated when processing the process @@ -120,23 +127,13 @@ static void update_xlog_logical_info(void); static void abort_logical_decoding_activation(int code, Datum arg); static void write_logical_decoding_status_update_record(bool status); -Size -LogicalDecodingCtlShmemSize(void) -{ - return sizeof(LogicalDecodingCtlData); -} - -void -LogicalDecodingCtlShmemInit(void) +static void +LogicalDecodingCtlShmemRequest(void *arg) { - bool found; - - LogicalDecodingCtl = ShmemInitStruct("Logical decoding control", - LogicalDecodingCtlShmemSize(), - &found); - - if (!found) - MemSet(LogicalDecodingCtl, 0, LogicalDecodingCtlShmemSize()); + ShmemRequestStruct(.name = "Logical decoding control", + .size = sizeof(LogicalDecodingCtlData), + .ptr = (void **) &LogicalDecodingCtl, + ); } /* diff --git a/src/backend/replication/logical/origin.c b/src/backend/replication/logical/origin.c index 661d68ad653..372d77c475e 100644 --- a/src/backend/replication/logical/origin.c +++ b/src/backend/replication/logical/origin.c @@ -88,6 +88,7 @@ #include "storage/fd.h" #include "storage/ipc.h" #include "storage/lmgr.h" +#include "storage/subsystems.h" #include "utils/builtins.h" #include "utils/fmgroids.h" #include "utils/guc.h" @@ -176,6 +177,16 @@ ReplOriginXactState replorigin_xact_state = { */ static ReplicationState *replication_states; +static void ReplicationOriginShmemRequest(void *arg); +static void ReplicationOriginShmemInit(void *arg); +static void ReplicationOriginShmemAttach(void *arg); + +const ShmemCallbacks ReplicationOriginShmemCallbacks = { + .request_fn = ReplicationOriginShmemRequest, + .init_fn = ReplicationOriginShmemInit, + .attach_fn = ReplicationOriginShmemAttach, +}; + /* * Actual shared memory block (replication_states[] is now part of this). */ @@ -539,50 +550,48 @@ replorigin_by_oid(ReplOriginId roident, bool missing_ok, char **roname) * --------------------------------------------------------------------------- */ -Size -ReplicationOriginShmemSize(void) +static void +ReplicationOriginShmemRequest(void *arg) { Size size = 0; if (max_active_replication_origins == 0) - return size; + return; size = add_size(size, offsetof(ReplicationStateCtl, states)); - size = add_size(size, mul_size(max_active_replication_origins, sizeof(ReplicationState))); - return size; + ShmemRequestStruct(.name = "ReplicationOriginState", + .size = size, + .ptr = (void **) &replication_states_ctl, + ); } -void -ReplicationOriginShmemInit(void) +static void +ReplicationOriginShmemInit(void *arg) { - bool found; - if (max_active_replication_origins == 0) return; - replication_states_ctl = (ReplicationStateCtl *) - ShmemInitStruct("ReplicationOriginState", - ReplicationOriginShmemSize(), - &found); replication_states = replication_states_ctl->states; - if (!found) - { - int i; + replication_states_ctl->tranche_id = LWTRANCHE_REPLICATION_ORIGIN_STATE; - MemSet(replication_states_ctl, 0, ReplicationOriginShmemSize()); + for (int i = 0; i < max_active_replication_origins; i++) + { + LWLockInitialize(&replication_states[i].lock, + replication_states_ctl->tranche_id); + ConditionVariableInit(&replication_states[i].origin_cv); + } +} - replication_states_ctl->tranche_id = LWTRANCHE_REPLICATION_ORIGIN_STATE; +static void +ReplicationOriginShmemAttach(void *arg) +{ + if (max_active_replication_origins == 0) + return; - for (i = 0; i < max_active_replication_origins; i++) - { - LWLockInitialize(&replication_states[i].lock, - replication_states_ctl->tranche_id); - ConditionVariableInit(&replication_states[i].origin_cv); - } - } + replication_states = replication_states_ctl->states; } /* --------------------------------------------------------------------------- diff --git a/src/backend/replication/logical/slotsync.c b/src/backend/replication/logical/slotsync.c index e75db69e3f6..d615ff8a81c 100644 --- a/src/backend/replication/logical/slotsync.c +++ b/src/backend/replication/logical/slotsync.c @@ -73,6 +73,7 @@ #include "storage/lmgr.h" #include "storage/proc.h" #include "storage/procarray.h" +#include "storage/subsystems.h" #include "tcop/tcopprot.h" #include "utils/builtins.h" #include "utils/memutils.h" @@ -118,6 +119,14 @@ typedef struct SlotSyncCtxStruct static SlotSyncCtxStruct *SlotSyncCtx = NULL; +static void SlotSyncShmemRequest(void *arg); +static void SlotSyncShmemInit(void *arg); + +const ShmemCallbacks SlotSyncShmemCallbacks = { + .request_fn = SlotSyncShmemRequest, + .init_fn = SlotSyncShmemInit, +}; + /* GUC variable */ bool sync_replication_slots = false; @@ -1828,32 +1837,26 @@ IsSyncingReplicationSlots(void) } /* - * Amount of shared memory required for slot synchronization. + * Register shared memory space needed for slot synchronization. */ -Size -SlotSyncShmemSize(void) +static void +SlotSyncShmemRequest(void *arg) { - return sizeof(SlotSyncCtxStruct); + ShmemRequestStruct(.name = "Slot Sync Data", + .size = sizeof(SlotSyncCtxStruct), + .ptr = (void **) &SlotSyncCtx, + ); } /* - * Allocate and initialize the shared memory of slot synchronization. + * Initialize shared memory for slot synchronization. */ -void -SlotSyncShmemInit(void) +static void +SlotSyncShmemInit(void *arg) { - Size size = SlotSyncShmemSize(); - bool found; - - SlotSyncCtx = (SlotSyncCtxStruct *) - ShmemInitStruct("Slot Sync Data", size, &found); - - if (!found) - { - memset(SlotSyncCtx, 0, size); - SlotSyncCtx->pid = InvalidPid; - SpinLockInit(&SlotSyncCtx->mutex); - } + memset(SlotSyncCtx, 0, sizeof(SlotSyncCtxStruct)); + SlotSyncCtx->pid = InvalidPid; + SpinLockInit(&SlotSyncCtx->mutex); } /* diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c index a9092fc2382..21a213a0ebf 100644 --- a/src/backend/replication/slot.c +++ b/src/backend/replication/slot.c @@ -55,6 +55,7 @@ #include "storage/ipc.h" #include "storage/proc.h" #include "storage/procarray.h" +#include "storage/subsystems.h" #include "utils/builtins.h" #include "utils/guc_hooks.h" #include "utils/injection_point.h" @@ -145,6 +146,14 @@ StaticAssertDecl(lengthof(SlotInvalidationCauses) == (RS_INVAL_MAX_CAUSES + 1), /* Control array for replication slot management */ ReplicationSlotCtlData *ReplicationSlotCtl = NULL; +static void ReplicationSlotsShmemRequest(void *arg); +static void ReplicationSlotsShmemInit(void *arg); + +const ShmemCallbacks ReplicationSlotsShmemCallbacks = { + .request_fn = ReplicationSlotsShmemRequest, + .init_fn = ReplicationSlotsShmemInit, +}; + /* My backend's replication slot in the shared memory array */ ReplicationSlot *MyReplicationSlot = NULL; @@ -183,56 +192,41 @@ static void CreateSlotOnDisk(ReplicationSlot *slot); static void SaveSlotToPath(ReplicationSlot *slot, const char *dir, int elevel); /* - * Report shared-memory space needed by ReplicationSlotsShmemInit. + * Register shared memory space needed for replication slots. */ -Size -ReplicationSlotsShmemSize(void) +static void +ReplicationSlotsShmemRequest(void *arg) { - Size size = 0; + Size size; if (max_replication_slots == 0) - return size; + return; size = offsetof(ReplicationSlotCtlData, replication_slots); size = add_size(size, mul_size(max_replication_slots, sizeof(ReplicationSlot))); - - return size; + ShmemRequestStruct(.name = "ReplicationSlot Ctl", + .size = size, + .ptr = (void **) &ReplicationSlotCtl, + ); } /* - * Allocate and initialize shared memory for replication slots. + * Initialize shared memory for replication slots. */ -void -ReplicationSlotsShmemInit(void) +static void +ReplicationSlotsShmemInit(void *arg) { - bool found; - - if (max_replication_slots == 0) - return; - - ReplicationSlotCtl = (ReplicationSlotCtlData *) - ShmemInitStruct("ReplicationSlot Ctl", ReplicationSlotsShmemSize(), - &found); - - if (!found) + for (int i = 0; i < max_replication_slots; i++) { - int i; + ReplicationSlot *slot = &ReplicationSlotCtl->replication_slots[i]; - /* First time through, so initialize */ - MemSet(ReplicationSlotCtl, 0, ReplicationSlotsShmemSize()); - - for (i = 0; i < max_replication_slots; i++) - { - ReplicationSlot *slot = &ReplicationSlotCtl->replication_slots[i]; - - /* everything else is zeroed by the memset above */ - slot->active_proc = INVALID_PROC_NUMBER; - SpinLockInit(&slot->mutex); - LWLockInitialize(&slot->io_in_progress_lock, - LWTRANCHE_REPLICATION_SLOT_IO); - ConditionVariableInit(&slot->active_cv); - } + /* everything else is zeroed by the memset above */ + slot->active_proc = INVALID_PROC_NUMBER; + SpinLockInit(&slot->mutex); + LWLockInitialize(&slot->io_in_progress_lock, + LWTRANCHE_REPLICATION_SLOT_IO); + ConditionVariableInit(&slot->active_cv); } } diff --git a/src/backend/replication/walreceiverfuncs.c b/src/backend/replication/walreceiverfuncs.c index 45b9d4f09f2..4e03e721872 100644 --- a/src/backend/replication/walreceiverfuncs.c +++ b/src/backend/replication/walreceiverfuncs.c @@ -29,47 +29,46 @@ #include "storage/pmsignal.h" #include "storage/proc.h" #include "storage/shmem.h" +#include "storage/subsystems.h" #include "utils/timestamp.h" #include "utils/wait_event.h" WalRcvData *WalRcv = NULL; +static void WalRcvShmemRequest(void *arg); +static void WalRcvShmemInit(void *arg); + +const ShmemCallbacks WalRcvShmemCallbacks = { + .request_fn = WalRcvShmemRequest, + .init_fn = WalRcvShmemInit, +}; + /* * How long to wait for walreceiver to start up after requesting * postmaster to launch it. In seconds. */ #define WALRCV_STARTUP_TIMEOUT 10 -/* Report shared memory space needed by WalRcvShmemInit */ -Size -WalRcvShmemSize(void) +/* Register shared memory space needed by walreceiver */ +static void +WalRcvShmemRequest(void *arg) { - Size size = 0; - - size = add_size(size, sizeof(WalRcvData)); - - return size; + ShmemRequestStruct(.name = "Wal Receiver Ctl", + .size = sizeof(WalRcvData), + .ptr = (void **) &WalRcv, + ); } -/* Allocate and initialize walreceiver-related shared memory */ -void -WalRcvShmemInit(void) +/* Initialize walreceiver-related shared memory */ +static void +WalRcvShmemInit(void *arg) { - bool found; - - WalRcv = (WalRcvData *) - ShmemInitStruct("Wal Receiver Ctl", WalRcvShmemSize(), &found); - - if (!found) - { - /* First time through, so initialize */ - MemSet(WalRcv, 0, WalRcvShmemSize()); - WalRcv->walRcvState = WALRCV_STOPPED; - ConditionVariableInit(&WalRcv->walRcvStoppedCV); - SpinLockInit(&WalRcv->mutex); - pg_atomic_init_u64(&WalRcv->writtenUpto, 0); - WalRcv->procno = INVALID_PROC_NUMBER; - } + MemSet(WalRcv, 0, sizeof(WalRcvData)); + WalRcv->walRcvState = WALRCV_STOPPED; + ConditionVariableInit(&WalRcv->walRcvStoppedCV); + SpinLockInit(&WalRcv->mutex); + pg_atomic_init_u64(&WalRcv->writtenUpto, 0); + WalRcv->procno = INVALID_PROC_NUMBER; } /* Is walreceiver running (or starting up)? */ diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c index 2bb3f34dc6d..ec39942bfc1 100644 --- a/src/backend/replication/walsender.c +++ b/src/backend/replication/walsender.c @@ -86,6 +86,7 @@ #include "storage/pmsignal.h" #include "storage/proc.h" #include "storage/procarray.h" +#include "storage/subsystems.h" #include "tcop/dest.h" #include "tcop/tcopprot.h" #include "utils/acl.h" @@ -117,6 +118,14 @@ /* Array of WalSnds in shared memory */ WalSndCtlData *WalSndCtl = NULL; +static void WalSndShmemRequest(void *arg); +static void WalSndShmemInit(void *arg); + +const ShmemCallbacks WalSndShmemCallbacks = { + .request_fn = WalSndShmemRequest, + .init_fn = WalSndShmemInit, +}; + /* My slot in the shared memory array */ WalSnd *MyWalSnd = NULL; @@ -3765,47 +3774,37 @@ WalSndSignals(void) pqsignal(SIGCHLD, SIG_DFL); } -/* Report shared-memory space needed by WalSndShmemInit */ -Size -WalSndShmemSize(void) +/* Register shared-memory space needed by walsender */ +static void +WalSndShmemRequest(void *arg) { - Size size = 0; + Size size; size = offsetof(WalSndCtlData, walsnds); size = add_size(size, mul_size(max_wal_senders, sizeof(WalSnd))); - - return size; + ShmemRequestStruct(.name = "Wal Sender Ctl", + .size = size, + .ptr = (void **) &WalSndCtl, + ); } -/* Allocate and initialize walsender-related shared memory */ -void -WalSndShmemInit(void) +/* Initialize walsender-related shared memory */ +static void +WalSndShmemInit(void *arg) { - bool found; - int i; + for (int i = 0; i < NUM_SYNC_REP_WAIT_MODE; i++) + dlist_init(&(WalSndCtl->SyncRepQueue[i])); - WalSndCtl = (WalSndCtlData *) - ShmemInitStruct("Wal Sender Ctl", WalSndShmemSize(), &found); - - if (!found) + for (int i = 0; i < max_wal_senders; i++) { - /* First time through, so initialize */ - MemSet(WalSndCtl, 0, WalSndShmemSize()); - - for (i = 0; i < NUM_SYNC_REP_WAIT_MODE; i++) - dlist_init(&(WalSndCtl->SyncRepQueue[i])); - - for (i = 0; i < max_wal_senders; i++) - { - WalSnd *walsnd = &WalSndCtl->walsnds[i]; - - SpinLockInit(&walsnd->mutex); - } + WalSnd *walsnd = &WalSndCtl->walsnds[i]; - ConditionVariableInit(&WalSndCtl->wal_flush_cv); - ConditionVariableInit(&WalSndCtl->wal_replay_cv); - ConditionVariableInit(&WalSndCtl->wal_confirm_rcv_cv); + SpinLockInit(&walsnd->mutex); } + + ConditionVariableInit(&WalSndCtl->wal_flush_cv); + ConditionVariableInit(&WalSndCtl->wal_replay_cv); + ConditionVariableInit(&WalSndCtl->wal_confirm_rcv_cv); } /* diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c index f64c1d59fa3..bf6b81e621b 100644 --- a/src/backend/storage/ipc/ipci.c +++ b/src/backend/storage/ipc/ipci.c @@ -14,41 +14,16 @@ */ #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/twophase.h" -#include "access/xlogprefetcher.h" -#include "access/xlogrecovery.h" -#include "access/xlogwait.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/datachecksum_state.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/dsm.h" #include "storage/ipc.h" +#include "storage/lock.h" #include "storage/pg_shmem.h" -#include "storage/predicate.h" #include "storage/proc.h" #include "storage/shmem_internal.h" #include "storage/subsystems.h" #include "utils/guc.h" -#include "utils/injection_point.h" -#include "utils/wait_event.h" /* GUCs */ int shared_memory_type = DEFAULT_SHARED_MEMORY_TYPE; @@ -57,8 +32,6 @@ 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 @@ -97,33 +70,6 @@ CalculateShmemSize(void) size = 100000; size = add_size(size, ShmemGetRequestedSize()); - /* legacy subsystems */ - size = add_size(size, LockManagerShmemSize()); - size = add_size(size, XLogPrefetchShmemSize()); - size = add_size(size, XLOGShmemSize()); - size = add_size(size, XLogRecoveryShmemSize()); - size = add_size(size, TwoPhaseShmemSize()); - size = add_size(size, BackgroundWorkerShmemSize()); - size = add_size(size, BackendStatusShmemSize()); - 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, StatsShmemSize()); - size = add_size(size, WaitEventCustomShmemSize()); - size = add_size(size, InjectionPointShmemSize()); - size = add_size(size, SlotSyncShmemSize()); - size = add_size(size, WaitLSNShmemSize()); - size = add_size(size, LogicalDecodingCtlShmemSize()); - size = add_size(size, DataChecksumsShmemSize()); - /* include additional requested shmem from preload libraries */ size = add_size(size, total_addin_request); @@ -157,7 +103,6 @@ AttachSharedMemoryStructs(void) /* Establish pointers to all shared memory areas in this backend */ ShmemAttachRequested(); - CreateOrAttachShmemStructs(); /* * Now give loadable modules a chance to set up their shmem allocations @@ -204,9 +149,6 @@ CreateSharedMemoryAndSemaphores(void) /* Initialize all shmem areas */ ShmemInitRequested(); - /* Initialize legacy subsystems */ - CreateOrAttachShmemStructs(); - /* Initialize dynamic shared memory facilities. */ dsm_postmaster_startup(shim); @@ -237,70 +179,6 @@ RegisterBuiltinShmemCallbacks(void) #undef PG_SHMEM_SUBSYSTEM } -/* - * 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) -{ - /* - * Set up xlog, clog, and buffers - */ - XLOGShmemInit(); - XLogPrefetchShmemInit(); - XLogRecoveryShmemInit(); - - /* - * Set up lock manager - */ - LockManagerShmemInit(); - - /* - * Set up process table - */ - BackendStatusShmemInit(); - TwoPhaseShmemInit(); - BackgroundWorkerShmemInit(); - - /* - * Set up interprocess signaling mechanisms - */ - CheckpointerShmemInit(); - AutoVacuumShmemInit(); - ReplicationSlotsShmemInit(); - ReplicationOriginShmemInit(); - WalSndShmemInit(); - WalRcvShmemInit(); - WalSummarizerShmemInit(); - PgArchShmemInit(); - ApplyLauncherShmemInit(); - SlotSyncShmemInit(); - DataChecksumsShmemInit(); - - /* - * Set up other modules that need some shared memory space - */ - BTreeShmemInit(); - SyncScanShmemInit(); - StatsShmemInit(); - WaitEventCustomShmemInit(); - InjectionPointShmemInit(); - WaitLSNShmemInit(); - LogicalDecodingCtlShmemInit(); -} - /* * InitializeShmemGUCs * diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 798c453ab38..c221fe96889 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -43,8 +43,10 @@ #include "storage/lmgr.h" #include "storage/proc.h" #include "storage/procarray.h" +#include "storage/shmem.h" #include "storage/spin.h" #include "storage/standby.h" +#include "storage/subsystems.h" #include "utils/memutils.h" #include "utils/ps_status.h" #include "utils/resowner.h" @@ -312,6 +314,14 @@ typedef struct static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks; +static void LockManagerShmemRequest(void *arg); +static void LockManagerShmemInit(void *arg); + +const ShmemCallbacks LockManagerShmemCallbacks = { + .request_fn = LockManagerShmemRequest, + .init_fn = LockManagerShmemInit, +}; + /* * Pointers to hash tables containing lock state @@ -432,21 +442,15 @@ static void GetSingleProcBlockerStatusData(PGPROC *blocked_proc, /* - * Initialize the lock manager's shmem data structures. + * Register the lock manager's shmem data structures. * - * This is called from CreateSharedMemoryAndSemaphores(), which see for more - * comments. In the normal postmaster case, the shared hash tables are - * created here, and backends inherit pointers to them via fork(). In the - * EXEC_BACKEND case, each backend re-executes this code to obtain pointers to - * the already existing shared hash tables. In either case, each backend must - * also call InitLockManagerAccess() to create the locallock hash table. + * In addition to this, each backend must also call InitLockManagerAccess() to + * create the locallock hash table. */ -void -LockManagerShmemInit(void) +static void +LockManagerShmemRequest(void *arg) { - HASHCTL info; int64 max_table_size; - bool found; /* * Compute sizes for lock hashtables. Note that these calculations must @@ -455,45 +459,41 @@ LockManagerShmemInit(void) max_table_size = NLOCKENTS(); /* - * Allocate hash table for LOCK structs. This stores per-locked-object + * Hash table for LOCK structs. This stores per-locked-object * information. */ - info.keysize = sizeof(LOCKTAG); - info.entrysize = sizeof(LOCK); - info.num_partitions = NUM_LOCK_PARTITIONS; - - LockMethodLockHash = ShmemInitHash("LOCK hash", - max_table_size, - &info, - HASH_ELEM | HASH_BLOBS | - HASH_PARTITION | HASH_FIXED_SIZE); + ShmemRequestHash(.name = "LOCK hash", + .nelems = max_table_size, + .ptr = &LockMethodLockHash, + .hash_info.keysize = sizeof(LOCKTAG), + .hash_info.entrysize = sizeof(LOCK), + .hash_info.num_partitions = NUM_LOCK_PARTITIONS, + .hash_flags = HASH_ELEM | HASH_BLOBS | HASH_PARTITION, + ); /* Assume an average of 2 holders per lock */ max_table_size *= 2; - /* - * Allocate hash table for PROCLOCK structs. This stores - * per-lock-per-holder information. - */ - info.keysize = sizeof(PROCLOCKTAG); - info.entrysize = sizeof(PROCLOCK); - info.hash = proclock_hash; - info.num_partitions = NUM_LOCK_PARTITIONS; - - LockMethodProcLockHash = ShmemInitHash("PROCLOCK hash", - max_table_size, - &info, - HASH_ELEM | HASH_FUNCTION | - HASH_FIXED_SIZE | HASH_PARTITION); + ShmemRequestHash(.name = "PROCLOCK hash", + .nelems = max_table_size, + .ptr = &LockMethodProcLockHash, + .hash_info.keysize = sizeof(PROCLOCKTAG), + .hash_info.entrysize = sizeof(PROCLOCK), + .hash_info.hash = proclock_hash, + .hash_info.num_partitions = NUM_LOCK_PARTITIONS, + .hash_flags = HASH_ELEM | HASH_FUNCTION | HASH_PARTITION, + ); + + ShmemRequestStruct(.name = "Fast Path Strong Relation Lock Data", + .size = sizeof(FastPathStrongRelationLockData), + .ptr = (void **) (void *) &FastPathStrongRelationLocks, + ); +} - /* - * Allocate fast-path structures. - */ - FastPathStrongRelationLocks = - ShmemInitStruct("Fast Path Strong Relation Lock Data", - sizeof(FastPathStrongRelationLockData), &found); - if (!found) - SpinLockInit(&FastPathStrongRelationLocks->mutex); +static void +LockManagerShmemInit(void *arg) +{ + SpinLockInit(&FastPathStrongRelationLocks->mutex); } /* @@ -3758,29 +3758,6 @@ PostPrepare_Locks(FullTransactionId fxid) } -/* - * Estimate shared-memory space used for lock tables - */ -Size -LockManagerShmemSize(void) -{ - Size size = 0; - long max_table_size; - - /* lock hash table */ - max_table_size = NLOCKENTS(); - size = add_size(size, hash_estimate_size(max_table_size, sizeof(LOCK))); - - /* proclock hash table */ - max_table_size *= 2; - size = add_size(size, hash_estimate_size(max_table_size, sizeof(PROCLOCK))); - - /* fast-path structures */ - size = add_size(size, sizeof(FastPathStrongRelationLockData)); - - return size; -} - /* * GetLockStatusData - Return a summary of the lock manager's internal * status, for use in a user-level reporting function. diff --git a/src/backend/utils/activity/backend_status.c b/src/backend/utils/activity/backend_status.c index cd087129469..d685fc5cd87 100644 --- a/src/backend/utils/activity/backend_status.c +++ b/src/backend/utils/activity/backend_status.c @@ -19,6 +19,8 @@ #include "storage/ipc.h" #include "storage/proc.h" /* for MyProc */ #include "storage/procarray.h" +#include "storage/shmem.h" +#include "storage/subsystems.h" #include "utils/ascii.h" #include "utils/guc.h" /* for application_name */ #include "utils/memutils.h" @@ -73,133 +75,97 @@ static void pgstat_beshutdown_hook(int code, Datum arg); static void pgstat_read_current_status(void); static void pgstat_setup_backend_status_context(void); +static void BackendStatusShmemRequest(void *arg); +static void BackendStatusShmemInit(void *arg); +static void BackendStatusShmemAttach(void *arg); + +const ShmemCallbacks BackendStatusShmemCallbacks = { + .request_fn = BackendStatusShmemRequest, + .init_fn = BackendStatusShmemInit, + .attach_fn = BackendStatusShmemAttach, +}; /* - * Report shared-memory space needed by BackendStatusShmemInit. + * Register shared memory needs for backend status reporting. */ -Size -BackendStatusShmemSize(void) +static void +BackendStatusShmemRequest(void *arg) { - Size size; - - /* BackendStatusArray: */ - size = mul_size(sizeof(PgBackendStatus), NumBackendStatSlots); - /* BackendAppnameBuffer: */ - size = add_size(size, - mul_size(NAMEDATALEN, NumBackendStatSlots)); - /* BackendClientHostnameBuffer: */ - size = add_size(size, - mul_size(NAMEDATALEN, NumBackendStatSlots)); - /* BackendActivityBuffer: */ - size = add_size(size, - mul_size(pgstat_track_activity_query_size, NumBackendStatSlots)); + ShmemRequestStruct(.name = "Backend Status Array", + .size = mul_size(sizeof(PgBackendStatus), NumBackendStatSlots), + .ptr = (void **) &BackendStatusArray, + ); + + ShmemRequestStruct(.name = "Backend Application Name Buffer", + .size = mul_size(NAMEDATALEN, NumBackendStatSlots), + .ptr = (void **) &BackendAppnameBuffer, + ); + + ShmemRequestStruct(.name = "Backend Client Host Name Buffer", + .size = mul_size(NAMEDATALEN, NumBackendStatSlots), + .ptr = (void **) &BackendClientHostnameBuffer, + ); + + BackendActivityBufferSize = mul_size(pgstat_track_activity_query_size, + NumBackendStatSlots); + ShmemRequestStruct(.name = "Backend Activity Buffer", + .size = BackendActivityBufferSize, + .ptr = (void **) &BackendActivityBuffer + ); + #ifdef USE_SSL - /* BackendSslStatusBuffer: */ - size = add_size(size, - mul_size(sizeof(PgBackendSSLStatus), NumBackendStatSlots)); + ShmemRequestStruct(.name = "Backend SSL Status Buffer", + .size = mul_size(sizeof(PgBackendSSLStatus), NumBackendStatSlots), + .ptr = (void **) &BackendSslStatusBuffer, + ); #endif + #ifdef ENABLE_GSS - /* BackendGssStatusBuffer: */ - size = add_size(size, - mul_size(sizeof(PgBackendGSSStatus), NumBackendStatSlots)); + ShmemRequestStruct(.name = "Backend GSS Status Buffer", + .size = mul_size(sizeof(PgBackendGSSStatus), NumBackendStatSlots), + .ptr = (void **) &BackendGssStatusBuffer, + ); #endif - return size; } /* * Initialize the shared status array and several string buffers * during postmaster startup. */ -void -BackendStatusShmemInit(void) +static void +BackendStatusShmemInit(void *arg) { - Size size; - bool found; int i; char *buffer; - /* Create or attach to the shared array */ - size = mul_size(sizeof(PgBackendStatus), NumBackendStatSlots); - BackendStatusArray = (PgBackendStatus *) - ShmemInitStruct("Backend Status Array", size, &found); - - if (!found) + /* Initialize st_appname pointers. */ + buffer = BackendAppnameBuffer; + for (i = 0; i < NumBackendStatSlots; i++) { - /* - * We're the first - initialize. - */ - MemSet(BackendStatusArray, 0, size); - } - - /* Create or attach to the shared appname buffer */ - size = mul_size(NAMEDATALEN, NumBackendStatSlots); - BackendAppnameBuffer = (char *) - ShmemInitStruct("Backend Application Name Buffer", size, &found); - - if (!found) - { - MemSet(BackendAppnameBuffer, 0, size); - - /* Initialize st_appname pointers. */ - buffer = BackendAppnameBuffer; - for (i = 0; i < NumBackendStatSlots; i++) - { - BackendStatusArray[i].st_appname = buffer; - buffer += NAMEDATALEN; - } + BackendStatusArray[i].st_appname = buffer; + buffer += NAMEDATALEN; } - /* Create or attach to the shared client hostname buffer */ - size = mul_size(NAMEDATALEN, NumBackendStatSlots); - BackendClientHostnameBuffer = (char *) - ShmemInitStruct("Backend Client Host Name Buffer", size, &found); - - if (!found) + /* Initialize st_clienthostname pointers. */ + buffer = BackendClientHostnameBuffer; + for (i = 0; i < NumBackendStatSlots; i++) { - MemSet(BackendClientHostnameBuffer, 0, size); - - /* Initialize st_clienthostname pointers. */ - buffer = BackendClientHostnameBuffer; - for (i = 0; i < NumBackendStatSlots; i++) - { - BackendStatusArray[i].st_clienthostname = buffer; - buffer += NAMEDATALEN; - } + BackendStatusArray[i].st_clienthostname = buffer; + buffer += NAMEDATALEN; } - /* Create or attach to the shared activity buffer */ - BackendActivityBufferSize = mul_size(pgstat_track_activity_query_size, - NumBackendStatSlots); - BackendActivityBuffer = (char *) - ShmemInitStruct("Backend Activity Buffer", - BackendActivityBufferSize, - &found); - - if (!found) + /* Initialize st_activity pointers. */ + buffer = BackendActivityBuffer; + for (i = 0; i < NumBackendStatSlots; i++) { - MemSet(BackendActivityBuffer, 0, BackendActivityBufferSize); - - /* Initialize st_activity pointers. */ - buffer = BackendActivityBuffer; - for (i = 0; i < NumBackendStatSlots; i++) - { - BackendStatusArray[i].st_activity_raw = buffer; - buffer += pgstat_track_activity_query_size; - } + BackendStatusArray[i].st_activity_raw = buffer; + buffer += pgstat_track_activity_query_size; } #ifdef USE_SSL - /* Create or attach to the shared SSL status buffer */ - size = mul_size(sizeof(PgBackendSSLStatus), NumBackendStatSlots); - BackendSslStatusBuffer = (PgBackendSSLStatus *) - ShmemInitStruct("Backend SSL Status Buffer", size, &found); - - if (!found) { PgBackendSSLStatus *ptr; - MemSet(BackendSslStatusBuffer, 0, size); - /* Initialize st_sslstatus pointers. */ ptr = BackendSslStatusBuffer; for (i = 0; i < NumBackendStatSlots; i++) @@ -211,17 +177,9 @@ BackendStatusShmemInit(void) #endif #ifdef ENABLE_GSS - /* Create or attach to the shared GSSAPI status buffer */ - size = mul_size(sizeof(PgBackendGSSStatus), NumBackendStatSlots); - BackendGssStatusBuffer = (PgBackendGSSStatus *) - ShmemInitStruct("Backend GSS Status Buffer", size, &found); - - if (!found) { PgBackendGSSStatus *ptr; - MemSet(BackendGssStatusBuffer, 0, size); - /* Initialize st_gssstatus pointers. */ ptr = BackendGssStatusBuffer; for (i = 0; i < NumBackendStatSlots; i++) @@ -233,6 +191,13 @@ BackendStatusShmemInit(void) #endif } +static void +BackendStatusShmemAttach(void *arg) +{ + BackendActivityBufferSize = mul_size(pgstat_track_activity_query_size, + NumBackendStatSlots); +} + /* * Initialize pgstats backend activity state, and set up our on-proc-exit * hook. Called from InitPostgres and AuxiliaryProcessMain. MyProcNumber must diff --git a/src/backend/utils/activity/pgstat_shmem.c b/src/backend/utils/activity/pgstat_shmem.c index 33fbdca9609..955faf5ebc7 100644 --- a/src/backend/utils/activity/pgstat_shmem.c +++ b/src/backend/utils/activity/pgstat_shmem.c @@ -14,6 +14,7 @@ #include "pgstat.h" #include "storage/shmem.h" +#include "storage/subsystems.h" #include "utils/memutils.h" #include "utils/pgstat_internal.h" @@ -57,6 +58,13 @@ static void pgstat_release_matching_entry_refs(bool discard_pending, ReleaseMatc static void pgstat_setup_memcxt(void); +static void StatsShmemRequest(void *arg); +static void StatsShmemInit(void *arg); + +const ShmemCallbacks StatsShmemCallbacks = { + .request_fn = StatsShmemRequest, + .init_fn = StatsShmemInit, +}; /* parameter for the shared hash */ static const dshash_parameters dsh_params = { @@ -123,7 +131,7 @@ pgstat_dsa_init_size(void) /* * Compute shared memory space needed for cumulative statistics */ -Size +static Size StatsShmemSize(void) { Size sz; @@ -149,102 +157,98 @@ StatsShmemSize(void) return sz; } +/* + * Register shared memory area for cumulative statistics + */ +static void +StatsShmemRequest(void *arg) +{ + ShmemRequestStruct(.name = "Shared Memory Stats", + .size = StatsShmemSize(), + .ptr = (void **) &pgStatLocal.shmem, + ); +} + /* * Initialize cumulative statistics system during startup */ -void -StatsShmemInit(void) +static void +StatsShmemInit(void *arg) { - bool found; - Size sz; + dsa_area *dsa; + dshash_table *dsh; + PgStat_ShmemControl *ctl = pgStatLocal.shmem; + char *p = (char *) ctl; - sz = StatsShmemSize(); - pgStatLocal.shmem = (PgStat_ShmemControl *) - ShmemInitStruct("Shared Memory Stats", sz, &found); + /* the allocation of pgStatLocal.shmem itself */ + p += MAXALIGN(sizeof(PgStat_ShmemControl)); - if (!IsUnderPostmaster) - { - dsa_area *dsa; - dshash_table *dsh; - PgStat_ShmemControl *ctl = pgStatLocal.shmem; - char *p = (char *) ctl; + /* + * Create a small dsa allocation in plain shared memory. This is required + * because postmaster cannot use dsm segments. It also provides a small + * efficiency win. + */ + ctl->raw_dsa_area = p; + dsa = dsa_create_in_place(ctl->raw_dsa_area, + pgstat_dsa_init_size(), + LWTRANCHE_PGSTATS_DSA, NULL); + dsa_pin(dsa); - Assert(!found); + /* + * To ensure dshash is created in "plain" shared memory, temporarily limit + * size of dsa to the initial size of the dsa. + */ + dsa_set_size_limit(dsa, pgstat_dsa_init_size()); - /* the allocation of pgStatLocal.shmem itself */ - p += MAXALIGN(sizeof(PgStat_ShmemControl)); + /* + * With the limit in place, create the dshash table. XXX: It'd be nice if + * there were dshash_create_in_place(). + */ + dsh = dshash_create(dsa, &dsh_params, NULL); + ctl->hash_handle = dshash_get_hash_table_handle(dsh); - /* - * Create a small dsa allocation in plain shared memory. This is - * required because postmaster cannot use dsm segments. It also - * provides a small efficiency win. - */ - ctl->raw_dsa_area = p; - dsa = dsa_create_in_place(ctl->raw_dsa_area, - pgstat_dsa_init_size(), - LWTRANCHE_PGSTATS_DSA, NULL); - dsa_pin(dsa); + /* lift limit set above */ + dsa_set_size_limit(dsa, -1); - /* - * To ensure dshash is created in "plain" shared memory, temporarily - * limit size of dsa to the initial size of the dsa. - */ - dsa_set_size_limit(dsa, pgstat_dsa_init_size()); + /* + * Postmaster will never access these again, thus free the local + * dsa/dshash references. + */ + dshash_detach(dsh); + dsa_detach(dsa); - /* - * With the limit in place, create the dshash table. XXX: It'd be nice - * if there were dshash_create_in_place(). - */ - dsh = dshash_create(dsa, &dsh_params, NULL); - ctl->hash_handle = dshash_get_hash_table_handle(dsh); + pg_atomic_init_u64(&ctl->gc_request_count, 1); - /* lift limit set above */ - dsa_set_size_limit(dsa, -1); + /* Do the per-kind initialization */ + for (PgStat_Kind kind = PGSTAT_KIND_MIN; kind <= PGSTAT_KIND_MAX; kind++) + { + const PgStat_KindInfo *kind_info = pgstat_get_kind_info(kind); + char *ptr; - /* - * Postmaster will never access these again, thus free the local - * dsa/dshash references. - */ - dshash_detach(dsh); - dsa_detach(dsa); + if (!kind_info) + continue; - pg_atomic_init_u64(&ctl->gc_request_count, 1); + /* initialize entry count tracking */ + if (kind_info->track_entry_count) + pg_atomic_init_u64(&ctl->entry_counts[kind - 1], 0); - /* Do the per-kind initialization */ - for (PgStat_Kind kind = PGSTAT_KIND_MIN; kind <= PGSTAT_KIND_MAX; kind++) + /* initialize fixed-numbered stats */ + if (kind_info->fixed_amount) { - const PgStat_KindInfo *kind_info = pgstat_get_kind_info(kind); - char *ptr; - - if (!kind_info) - continue; - - /* initialize entry count tracking */ - if (kind_info->track_entry_count) - pg_atomic_init_u64(&ctl->entry_counts[kind - 1], 0); - - /* initialize fixed-numbered stats */ - if (kind_info->fixed_amount) + if (pgstat_is_kind_builtin(kind)) + ptr = ((char *) ctl) + kind_info->shared_ctl_off; + else { - if (pgstat_is_kind_builtin(kind)) - ptr = ((char *) ctl) + kind_info->shared_ctl_off; - else - { - int idx = kind - PGSTAT_KIND_CUSTOM_MIN; - - Assert(kind_info->shared_size != 0); - ctl->custom_data[idx] = ShmemAlloc(kind_info->shared_size); - ptr = ctl->custom_data[idx]; - } - - kind_info->init_shmem_cb(ptr); + int idx = kind - PGSTAT_KIND_CUSTOM_MIN; + + Assert(kind_info->shared_size != 0); + ctl->custom_data[idx] = ShmemAlloc(kind_info->shared_size); + ptr = ctl->custom_data[idx]; } + + kind_info->init_shmem_cb(ptr); } } - else - { - Assert(found); - } } void diff --git a/src/backend/utils/activity/wait_event.c b/src/backend/utils/activity/wait_event.c index 2b76967776c..95635c7f56c 100644 --- a/src/backend/utils/activity/wait_event.c +++ b/src/backend/utils/activity/wait_event.c @@ -25,6 +25,7 @@ #include "storage/lmgr.h" #include "storage/lwlock.h" #include "storage/shmem.h" +#include "storage/subsystems.h" #include "storage/spin.h" #include "utils/wait_event.h" @@ -95,59 +96,47 @@ 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_SIZE, - sizeof(WaitEventCustomEntryByInfo))); - sz = add_size(sz, hash_estimate_size(WAIT_EVENT_CUSTOM_HASH_SIZE, - sizeof(WaitEventCustomEntryByName))); - return sz; + ShmemRequestStruct(.name = "WaitEventCustomCounterData", + .size = sizeof(WaitEventCustomCounterData), + .ptr = (void **) &WaitEventCustomCounter, + ); + ShmemRequestHash(.name = "WaitEventCustom hash by wait event information", + .ptr = &WaitEventCustomHashByInfo, + .nelems = WAIT_EVENT_CUSTOM_HASH_SIZE, + .hash_info.keysize = sizeof(uint32), + .hash_info.entrysize = sizeof(WaitEventCustomEntryByInfo), + .hash_flags = HASH_ELEM | HASH_BLOBS, + ); + ShmemRequestHash(.name = "WaitEventCustom hash by name", + .ptr = &WaitEventCustomHashByName, + .nelems = WAIT_EVENT_CUSTOM_HASH_SIZE, + /* key is a NULL-terminated string */ + .hash_info.keysize = sizeof(char[NAMEDATALEN]), + .hash_info.entrysize = sizeof(WaitEventCustomEntryByName), + .hash_flags = HASH_ELEM | HASH_STRINGS, + ); } -/* - * 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_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_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/backend/utils/misc/injection_point.c b/src/backend/utils/misc/injection_point.c index c06b0e9b800..a7c99e097ea 100644 --- a/src/backend/utils/misc/injection_point.c +++ b/src/backend/utils/misc/injection_point.c @@ -17,6 +17,7 @@ */ #include "postgres.h" +#include "storage/subsystems.h" #include "utils/injection_point.h" #ifdef USE_INJECTION_POINTS @@ -109,6 +110,11 @@ typedef struct InjectionPointCacheEntry static HTAB *InjectionPointCache = NULL; +#ifdef USE_INJECTION_POINTS +static void InjectionPointShmemRequest(void *arg); +static void InjectionPointShmemInit(void *arg); +#endif + /* * injection_point_cache_add * @@ -226,45 +232,34 @@ injection_point_cache_get(const char *name) } #endif /* USE_INJECTION_POINTS */ -/* - * Return the space for dynamic shared hash table. - */ -Size -InjectionPointShmemSize(void) -{ +const ShmemCallbacks InjectionPointShmemCallbacks = { #ifdef USE_INJECTION_POINTS - Size sz = 0; - - sz = add_size(sz, sizeof(InjectionPointsCtl)); - return sz; -#else - return 0; + .request_fn = InjectionPointShmemRequest, + .init_fn = InjectionPointShmemInit, #endif -} +}; /* - * Allocate shmem space for dynamic shared hash. + * Reserve space for the dynamic shared hash table */ -void -InjectionPointShmemInit(void) -{ #ifdef USE_INJECTION_POINTS - bool found; +static void +InjectionPointShmemRequest(void *arg) +{ + ShmemRequestStruct(.name = "InjectionPoint hash", + .size = sizeof(InjectionPointsCtl), + .ptr = (void **) &ActiveInjectionPoints, + ); +} - ActiveInjectionPoints = ShmemInitStruct("InjectionPoint hash", - sizeof(InjectionPointsCtl), - &found); - if (!IsUnderPostmaster) - { - Assert(!found); - pg_atomic_init_u32(&ActiveInjectionPoints->max_inuse, 0); - for (int i = 0; i < MAX_INJECTION_POINTS; i++) - pg_atomic_init_u64(&ActiveInjectionPoints->entries[i].generation, 0); - } - else - Assert(found); -#endif +static void +InjectionPointShmemInit(void *arg) +{ + pg_atomic_init_u32(&ActiveInjectionPoints->max_inuse, 0); + for (int i = 0; i < MAX_INJECTION_POINTS; i++) + pg_atomic_init_u64(&ActiveInjectionPoints->entries[i].generation, 0); } +#endif /* * Attach a new injection point. diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h index da7503c57b6..3097e9bb1af 100644 --- a/src/include/access/nbtree.h +++ b/src/include/access/nbtree.h @@ -1300,8 +1300,6 @@ extern BTCycleId _bt_vacuum_cycleid(Relation rel); extern BTCycleId _bt_start_vacuum(Relation rel); extern void _bt_end_vacuum(Relation rel); extern void _bt_end_vacuum_callback(int code, Datum arg); -extern Size BTreeShmemSize(void); -extern void BTreeShmemInit(void); extern bytea *btoptions(Datum reloptions, bool validate); extern bool btproperty(Oid index_oid, int attno, IndexAMProperty prop, const char *propname, diff --git a/src/include/access/syncscan.h b/src/include/access/syncscan.h index 24cf33294e5..32f8332aaee 100644 --- a/src/include/access/syncscan.h +++ b/src/include/access/syncscan.h @@ -24,7 +24,5 @@ extern PGDLLIMPORT bool trace_syncscan; extern void ss_report_location(Relation rel, BlockNumber location); extern BlockNumber ss_get_location(Relation rel, BlockNumber relnblocks); -extern void SyncScanShmemInit(void); -extern Size SyncScanShmemSize(void); #endif diff --git a/src/include/access/twophase.h b/src/include/access/twophase.h index 761d56a5f3d..1d2ff42c9b7 100644 --- a/src/include/access/twophase.h +++ b/src/include/access/twophase.h @@ -33,9 +33,6 @@ typedef struct GlobalTransactionData *GlobalTransaction; /* GUC variable */ extern PGDLLIMPORT int max_prepared_xacts; -extern Size TwoPhaseShmemSize(void); -extern void TwoPhaseShmemInit(void); - extern void AtAbort_Twophase(void); extern void PostPrepare_Twophase(void); diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index 4af38e74ce4..437b4f32349 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -259,8 +259,6 @@ extern void InitLocalDataChecksumState(void); extern void SetLocalDataChecksumState(uint32 data_checksum_version); extern bool GetDefaultCharSignedness(void); extern XLogRecPtr GetFakeLSNForUnloggedRel(void); -extern Size XLOGShmemSize(void); -extern void XLOGShmemInit(void); extern void BootStrapXLOG(uint32 data_checksum_version); extern void InitializeWalConsistencyChecking(void); extern void LocalProcessControlFile(bool reset); diff --git a/src/include/access/xlogprefetcher.h b/src/include/access/xlogprefetcher.h index 7ec40c4b78b..56a81676d92 100644 --- a/src/include/access/xlogprefetcher.h +++ b/src/include/access/xlogprefetcher.h @@ -34,9 +34,6 @@ typedef struct XLogPrefetcher XLogPrefetcher; extern void XLogPrefetchReconfigure(void); -extern size_t XLogPrefetchShmemSize(void); -extern void XLogPrefetchShmemInit(void); - extern void XLogPrefetchResetStats(void); extern XLogPrefetcher *XLogPrefetcherAllocate(XLogReaderState *reader); diff --git a/src/include/access/xlogrecovery.h b/src/include/access/xlogrecovery.h index 2842106b285..ba7750dca0b 100644 --- a/src/include/access/xlogrecovery.h +++ b/src/include/access/xlogrecovery.h @@ -153,9 +153,6 @@ extern PGDLLIMPORT bool reachedConsistency; /* Are we currently in standby mode? */ extern PGDLLIMPORT bool StandbyMode; -extern Size XLogRecoveryShmemSize(void); -extern void XLogRecoveryShmemInit(void); - extern void InitWalRecovery(ControlFileData *ControlFile, bool *wasShutdown_ptr, bool *haveBackupLabel_ptr, bool *haveTblspcMap_ptr); diff --git a/src/include/access/xlogwait.h b/src/include/access/xlogwait.h index d12531d32b8..07157f220ea 100644 --- a/src/include/access/xlogwait.h +++ b/src/include/access/xlogwait.h @@ -100,8 +100,6 @@ typedef struct WaitLSNState extern PGDLLIMPORT WaitLSNState *waitLSNState; -extern Size WaitLSNShmemSize(void); -extern void WaitLSNShmemInit(void); extern XLogRecPtr GetCurrentLSNForWaitType(WaitLSNType lsnType); extern void WaitLSNWakeup(WaitLSNType lsnType, XLogRecPtr currentLSN); extern void WaitLSNCleanup(void); diff --git a/src/include/pgstat.h b/src/include/pgstat.h index 8e3549c3752..2786a7c5ffb 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -541,10 +541,6 @@ typedef struct PgStat_BackendPending * Functions in pgstat.c */ -/* functions called from postmaster */ -extern Size StatsShmemSize(void); -extern void StatsShmemInit(void); - /* Functions called during server startup / shutdown */ extern void pgstat_restore_stats(void); extern void pgstat_discard_stats(void); diff --git a/src/include/postmaster/autovacuum.h b/src/include/postmaster/autovacuum.h index b21d111d4d5..8954f6b28ee 100644 --- a/src/include/postmaster/autovacuum.h +++ b/src/include/postmaster/autovacuum.h @@ -66,8 +66,4 @@ pg_noreturn extern void AutoVacWorkerMain(const void *startup_data, size_t start extern bool AutoVacuumRequestWork(AutoVacuumWorkItemType type, Oid relationId, BlockNumber blkno); -/* shared memory stuff */ -extern Size AutoVacuumShmemSize(void); -extern void AutoVacuumShmemInit(void); - #endif /* AUTOVACUUM_H */ diff --git a/src/include/postmaster/bgworker_internals.h b/src/include/postmaster/bgworker_internals.h index b789caf4034..b6261bc01df 100644 --- a/src/include/postmaster/bgworker_internals.h +++ b/src/include/postmaster/bgworker_internals.h @@ -41,8 +41,6 @@ typedef struct RegisteredBgWorker extern PGDLLIMPORT dlist_head BackgroundWorkerList; -extern Size BackgroundWorkerShmemSize(void); -extern void BackgroundWorkerShmemInit(void); extern void BackgroundWorkerStateChange(bool allow_new_workers); extern void ForgetBackgroundWorker(RegisteredBgWorker *rw); extern void ReportBackgroundWorkerPID(RegisteredBgWorker *rw); diff --git a/src/include/postmaster/bgwriter.h b/src/include/postmaster/bgwriter.h index 47470cba893..36eea0b1ab0 100644 --- a/src/include/postmaster/bgwriter.h +++ b/src/include/postmaster/bgwriter.h @@ -39,9 +39,6 @@ extern bool ForwardSyncRequest(const FileTag *ftag, SyncRequestType type); extern void AbsorbSyncRequests(void); -extern Size CheckpointerShmemSize(void); -extern void CheckpointerShmemInit(void); - extern bool FirstCallSinceLastCheckpoint(void); #endif /* _BGWRITER_H */ diff --git a/src/include/postmaster/datachecksum_state.h b/src/include/postmaster/datachecksum_state.h index 343494edcc8..05625539604 100644 --- a/src/include/postmaster/datachecksum_state.h +++ b/src/include/postmaster/datachecksum_state.h @@ -17,10 +17,6 @@ #include "storage/procsignal.h" -/* Shared memory */ -extern Size DataChecksumsShmemSize(void); -extern void DataChecksumsShmemInit(void); - /* Possible operations the Datachecksumsworker can perform */ typedef enum DataChecksumsWorkerOperation { diff --git a/src/include/postmaster/pgarch.h b/src/include/postmaster/pgarch.h index faa7609cd81..9772bb573a1 100644 --- a/src/include/postmaster/pgarch.h +++ b/src/include/postmaster/pgarch.h @@ -26,8 +26,6 @@ #define MAX_XFN_CHARS 40 #define VALID_XFN_CHARS "0123456789ABCDEF.history.backup.partial" -extern Size PgArchShmemSize(void); -extern void PgArchShmemInit(void); extern bool PgArchCanRestart(void); pg_noreturn extern void PgArchiverMain(const void *startup_data, size_t startup_data_len); extern void PgArchWakeup(void); diff --git a/src/include/postmaster/walsummarizer.h b/src/include/postmaster/walsummarizer.h index a4c055066b4..b9a755fadbc 100644 --- a/src/include/postmaster/walsummarizer.h +++ b/src/include/postmaster/walsummarizer.h @@ -19,8 +19,6 @@ extern PGDLLIMPORT bool summarize_wal; extern PGDLLIMPORT int wal_summary_keep_time; -extern Size WalSummarizerShmemSize(void); -extern void WalSummarizerShmemInit(void); pg_noreturn extern void WalSummarizerMain(const void *startup_data, size_t startup_data_len); extern void GetWalSummarizerState(TimeLineID *summarized_tli, diff --git a/src/include/replication/logicalctl.h b/src/include/replication/logicalctl.h index 495554c532c..0bc1302f130 100644 --- a/src/include/replication/logicalctl.h +++ b/src/include/replication/logicalctl.h @@ -14,8 +14,6 @@ #ifndef LOGICALCTL_H #define LOGICALCTL_H -extern Size LogicalDecodingCtlShmemSize(void); -extern void LogicalDecodingCtlShmemInit(void); extern void StartupLogicalDecodingStatus(bool last_status); extern void InitializeProcessXLogLogicalInfo(void); extern bool ProcessBarrierUpdateXLogLogicalInfo(void); diff --git a/src/include/replication/logicallauncher.h b/src/include/replication/logicallauncher.h index 504b710536a..5f0c1b9c682 100644 --- a/src/include/replication/logicallauncher.h +++ b/src/include/replication/logicallauncher.h @@ -19,9 +19,6 @@ extern PGDLLIMPORT int max_parallel_apply_workers_per_subscription; extern void ApplyLauncherRegister(void); extern void ApplyLauncherMain(Datum main_arg); -extern Size ApplyLauncherShmemSize(void); -extern void ApplyLauncherShmemInit(void); - extern void ApplyLauncherForgetWorkerStartTime(Oid subid); extern void ApplyLauncherWakeupAtCommit(void); diff --git a/src/include/replication/origin.h b/src/include/replication/origin.h index eb46b41b4b7..a69faf6eaaf 100644 --- a/src/include/replication/origin.h +++ b/src/include/replication/origin.h @@ -84,8 +84,4 @@ extern void replorigin_redo(XLogReaderState *record); extern void replorigin_desc(StringInfo buf, XLogReaderState *record); extern const char *replorigin_identify(uint8 info); -/* shared memory allocation */ -extern Size ReplicationOriginShmemSize(void); -extern void ReplicationOriginShmemInit(void); - #endif /* PG_ORIGIN_H */ diff --git a/src/include/replication/slot.h b/src/include/replication/slot.h index 4b4709f6e2c..1a3557de607 100644 --- a/src/include/replication/slot.h +++ b/src/include/replication/slot.h @@ -327,10 +327,6 @@ extern PGDLLIMPORT int max_replication_slots; extern PGDLLIMPORT char *synchronized_standby_slots; extern PGDLLIMPORT int idle_replication_slot_timeout_secs; -/* shmem initialization functions */ -extern Size ReplicationSlotsShmemSize(void); -extern void ReplicationSlotsShmemInit(void); - /* management of individual slots */ extern void ReplicationSlotCreate(const char *name, bool db_specific, ReplicationSlotPersistency persistency, diff --git a/src/include/replication/slotsync.h b/src/include/replication/slotsync.h index e546d0d050d..d2121cd3ed7 100644 --- a/src/include/replication/slotsync.h +++ b/src/include/replication/slotsync.h @@ -31,8 +31,6 @@ pg_noreturn extern void ReplSlotSyncWorkerMain(const void *startup_data, size_t extern void ShutDownSlotSync(void); extern bool SlotSyncWorkerCanRestart(void); extern bool IsSyncingReplicationSlots(void); -extern Size SlotSyncShmemSize(void); -extern void SlotSyncShmemInit(void); extern void SyncReplicationSlots(WalReceiverConn *wrconn); #endif /* SLOTSYNC_H */ diff --git a/src/include/replication/walreceiver.h b/src/include/replication/walreceiver.h index 85d24c87298..47c07574d4d 100644 --- a/src/include/replication/walreceiver.h +++ b/src/include/replication/walreceiver.h @@ -491,8 +491,6 @@ pg_noreturn extern void WalReceiverMain(const void *startup_data, size_t startup extern void WalRcvRequestApplyReply(void); /* prototypes for functions in walreceiverfuncs.c */ -extern Size WalRcvShmemSize(void); -extern void WalRcvShmemInit(void); extern void ShutdownWalRcv(void); extern bool WalRcvStreaming(void); extern bool WalRcvRunning(void); diff --git a/src/include/replication/walsender.h b/src/include/replication/walsender.h index a4df3b8e0ae..8952c848d19 100644 --- a/src/include/replication/walsender.h +++ b/src/include/replication/walsender.h @@ -41,8 +41,6 @@ extern void WalSndErrorCleanup(void); extern void PhysicalWakeupLogicalWalSnd(void); extern XLogRecPtr GetStandbyFlushRecPtr(TimeLineID *tli); extern void WalSndSignals(void); -extern Size WalSndShmemSize(void); -extern void WalSndShmemInit(void); extern void WalSndWakeup(bool physical, bool logical); extern void WalSndInitStopping(void); extern void WalSndWaitStopping(void); diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h index fa68e6ecece..ee3cb1dc203 100644 --- a/src/include/storage/lock.h +++ b/src/include/storage/lock.h @@ -375,8 +375,6 @@ typedef enum /* * function prototypes */ -extern void LockManagerShmemInit(void); -extern Size LockManagerShmemSize(void); extern void InitLockManagerAccess(void); extern LockMethod GetLocksMethodTable(const LOCK *lock); extern LockMethod GetLockTagsMethodTable(const LOCKTAG *locktag); diff --git a/src/include/storage/subsystemlist.h b/src/include/storage/subsystemlist.h index d8e11756a61..5e092552c72 100644 --- a/src/include/storage/subsystemlist.h +++ b/src/include/storage/subsystemlist.h @@ -32,6 +32,9 @@ PG_SHMEM_SUBSYSTEM(DSMRegistryShmemCallbacks) /* xlog, clog, and buffers */ PG_SHMEM_SUBSYSTEM(VarsupShmemCallbacks) +PG_SHMEM_SUBSYSTEM(XLOGShmemCallbacks) +PG_SHMEM_SUBSYSTEM(XLogPrefetchShmemCallbacks) +PG_SHMEM_SUBSYSTEM(XLogRecoveryShmemCallbacks) PG_SHMEM_SUBSYSTEM(CLOGShmemCallbacks) PG_SHMEM_SUBSYSTEM(CommitTsShmemCallbacks) PG_SHMEM_SUBSYSTEM(SUBTRANSShmemCallbacks) @@ -40,12 +43,18 @@ PG_SHMEM_SUBSYSTEM(BufferManagerShmemCallbacks) PG_SHMEM_SUBSYSTEM(StrategyCtlShmemCallbacks) PG_SHMEM_SUBSYSTEM(BufTableShmemCallbacks) +/* lock manager */ +PG_SHMEM_SUBSYSTEM(LockManagerShmemCallbacks) + /* predicate lock manager */ PG_SHMEM_SUBSYSTEM(PredicateLockShmemCallbacks) /* process table */ PG_SHMEM_SUBSYSTEM(ProcGlobalShmemCallbacks) PG_SHMEM_SUBSYSTEM(ProcArrayShmemCallbacks) +PG_SHMEM_SUBSYSTEM(BackendStatusShmemCallbacks) +PG_SHMEM_SUBSYSTEM(TwoPhaseShmemCallbacks) +PG_SHMEM_SUBSYSTEM(BackgroundWorkerShmemCallbacks) /* shared-inval messaging */ PG_SHMEM_SUBSYSTEM(SharedInvalShmemCallbacks) @@ -53,9 +62,27 @@ PG_SHMEM_SUBSYSTEM(SharedInvalShmemCallbacks) /* interprocess signaling mechanisms */ PG_SHMEM_SUBSYSTEM(PMSignalShmemCallbacks) PG_SHMEM_SUBSYSTEM(ProcSignalShmemCallbacks) +PG_SHMEM_SUBSYSTEM(CheckpointerShmemCallbacks) +PG_SHMEM_SUBSYSTEM(AutoVacuumShmemCallbacks) +PG_SHMEM_SUBSYSTEM(ReplicationSlotsShmemCallbacks) +PG_SHMEM_SUBSYSTEM(ReplicationOriginShmemCallbacks) +PG_SHMEM_SUBSYSTEM(WalSndShmemCallbacks) +PG_SHMEM_SUBSYSTEM(WalRcvShmemCallbacks) +PG_SHMEM_SUBSYSTEM(WalSummarizerShmemCallbacks) +PG_SHMEM_SUBSYSTEM(PgArchShmemCallbacks) +PG_SHMEM_SUBSYSTEM(ApplyLauncherShmemCallbacks) +PG_SHMEM_SUBSYSTEM(SlotSyncShmemCallbacks) /* other modules that need some shared memory space */ +PG_SHMEM_SUBSYSTEM(BTreeShmemCallbacks) +PG_SHMEM_SUBSYSTEM(SyncScanShmemCallbacks) PG_SHMEM_SUBSYSTEM(AsyncShmemCallbacks) +PG_SHMEM_SUBSYSTEM(StatsShmemCallbacks) +PG_SHMEM_SUBSYSTEM(WaitEventCustomShmemCallbacks) +PG_SHMEM_SUBSYSTEM(InjectionPointShmemCallbacks) +PG_SHMEM_SUBSYSTEM(WaitLSNShmemCallbacks) +PG_SHMEM_SUBSYSTEM(LogicalDecodingCtlShmemCallbacks) +PG_SHMEM_SUBSYSTEM(DataChecksumsShmemCallbacks) /* AIO subsystem. This delegates to the method-specific callbacks */ PG_SHMEM_SUBSYSTEM(AioShmemCallbacks) diff --git a/src/include/utils/backend_status.h b/src/include/utils/backend_status.h index ddd06304e97..a334e096e4a 100644 --- a/src/include/utils/backend_status.h +++ b/src/include/utils/backend_status.h @@ -298,14 +298,6 @@ extern PGDLLIMPORT int pgstat_track_activity_query_size; extern PGDLLIMPORT PgBackendStatus *MyBEEntry; -/* ---------- - * Functions called from postmaster - * ---------- - */ -extern Size BackendStatusShmemSize(void); -extern void BackendStatusShmemInit(void); - - /* ---------- * Functions called from backends * ---------- diff --git a/src/include/utils/injection_point.h b/src/include/utils/injection_point.h index 27a2526524f..fabd1455c3c 100644 --- a/src/include/utils/injection_point.h +++ b/src/include/utils/injection_point.h @@ -46,9 +46,6 @@ typedef void (*InjectionPointCallback) (const char *name, const void *private_data, void *arg); -extern Size InjectionPointShmemSize(void); -extern void InjectionPointShmemInit(void); - extern void InjectionPointAttach(const char *name, const char *library, const char *function, diff --git a/src/include/utils/wait_event.h b/src/include/utils/wait_event.h index 34c27cc3dc3..86ee348220d 100644 --- a/src/include/utils/wait_event.h +++ b/src/include/utils/wait_event.h @@ -42,8 +42,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); /* ---------- diff --git a/src/test/modules/injection_points/injection_points.c b/src/test/modules/injection_points/injection_points.c index d59c5ad0582..0f1af513673 100644 --- a/src/test/modules/injection_points/injection_points.c +++ b/src/test/modules/injection_points/injection_points.c @@ -107,9 +107,13 @@ extern PGDLLEXPORT void injection_wait(const char *name, /* track if injection points attached in this process are linked to it */ static bool injection_point_local = false; -/* Shared memory init callbacks */ -static shmem_request_hook_type prev_shmem_request_hook = NULL; -static shmem_startup_hook_type prev_shmem_startup_hook = NULL; +static void injection_shmem_request(void *arg); +static void injection_shmem_init(void *arg); + +static const ShmemCallbacks injection_shmem_callbacks = { + .request_fn = injection_shmem_request, + .init_fn = injection_shmem_init, +}; /* * Routine for shared memory area initialization, used as a callback @@ -126,44 +130,23 @@ injection_point_init_state(void *ptr, void *arg) ConditionVariableInit(&state->wait_point); } -/* Shared memory initialization when loading module */ static void -injection_shmem_request(void) +injection_shmem_request(void *arg) { - Size size; - - if (prev_shmem_request_hook) - prev_shmem_request_hook(); - - size = MAXALIGN(sizeof(InjectionPointSharedState)); - RequestAddinShmemSpace(size); + ShmemRequestStruct(.name = "injection_points", + .size = sizeof(InjectionPointSharedState), + .ptr = (void **) &inj_state, + ); } static void -injection_shmem_startup(void) +injection_shmem_init(void *arg) { - bool found; - - if (prev_shmem_startup_hook) - prev_shmem_startup_hook(); - - /* Create or attach to the shared memory state */ - LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE); - - inj_state = ShmemInitStruct("injection_points", - sizeof(InjectionPointSharedState), - &found); - - if (!found) - { - /* - * First time through, so initialize. This is shared with the dynamic - * initialization using a DSM. - */ - injection_point_init_state(inj_state, NULL); - } - - LWLockRelease(AddinShmemInitLock); + /* + * First time through, so initialize. This is shared with the dynamic + * initialization using a DSM. + */ + injection_point_init_state(inj_state, NULL); } /* @@ -601,9 +584,5 @@ _PG_init(void) if (!process_shared_preload_libraries_in_progress) return; - /* Shared memory initialization */ - prev_shmem_request_hook = shmem_request_hook; - shmem_request_hook = injection_shmem_request; - prev_shmem_startup_hook = shmem_startup_hook; - shmem_startup_hook = injection_shmem_startup; + RegisterShmemCallbacks(&injection_shmem_callbacks); } diff --git a/src/test/modules/test_aio/test_aio.c b/src/test/modules/test_aio/test_aio.c index d7530681192..35efba1a5e3 100644 --- a/src/test/modules/test_aio/test_aio.c +++ b/src/test/modules/test_aio/test_aio.c @@ -28,7 +28,6 @@ #include "storage/bufmgr.h" #include "storage/checksum.h" #include "storage/condition_variable.h" -#include "storage/ipc.h" #include "storage/lwlock.h" #include "storage/proc.h" #include "storage/procnumber.h" @@ -44,6 +43,7 @@ PG_MODULE_MAGIC; +/* In shared memory */ typedef struct InjIoErrorState { ConditionVariable cv; @@ -74,8 +74,15 @@ typedef struct BlocksReadStreamData static InjIoErrorState *inj_io_error_state; /* Shared memory init callbacks */ -static shmem_request_hook_type prev_shmem_request_hook = NULL; -static shmem_startup_hook_type prev_shmem_startup_hook = NULL; +static void test_aio_shmem_request(void *arg); +static void test_aio_shmem_init(void *arg); +static void test_aio_shmem_attach(void *arg); + +static const ShmemCallbacks inj_io_shmem_callbacks = { + .request_fn = test_aio_shmem_request, + .init_fn = test_aio_shmem_init, + .attach_fn = test_aio_shmem_attach, +}; static PgAioHandle *last_handle; @@ -83,70 +90,55 @@ static PgAioHandle *last_handle; static void -test_aio_shmem_request(void) +test_aio_shmem_request(void *arg) { - if (prev_shmem_request_hook) - prev_shmem_request_hook(); - - RequestAddinShmemSpace(sizeof(InjIoErrorState)); + ShmemRequestStruct(.name = "test_aio injection points", + .size = sizeof(InjIoErrorState), + .ptr = (void **) &inj_io_error_state, + ); } static void -test_aio_shmem_startup(void) +test_aio_shmem_init(void *arg) { - bool found; - - if (prev_shmem_startup_hook) - prev_shmem_startup_hook(); - - /* Create or attach to the shared memory state */ - LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE); - - inj_io_error_state = ShmemInitStruct("injection_points", - sizeof(InjIoErrorState), - &found); - - if (!found) - { - /* First time through, initialize */ - inj_io_error_state->enabled_short_read = false; - inj_io_error_state->enabled_reopen = false; - inj_io_error_state->enabled_completion_wait = false; + /* First time through, initialize */ + inj_io_error_state->enabled_short_read = false; + inj_io_error_state->enabled_reopen = false; + inj_io_error_state->enabled_completion_wait = false; - ConditionVariableInit(&inj_io_error_state->cv); - inj_io_error_state->completion_wait_event = WaitEventInjectionPointNew("completion_wait"); + ConditionVariableInit(&inj_io_error_state->cv); + inj_io_error_state->completion_wait_event = WaitEventInjectionPointNew("completion_wait"); #ifdef USE_INJECTION_POINTS - InjectionPointAttach("aio-process-completion-before-shared", - "test_aio", - "inj_io_completion_hook", - NULL, - 0); - InjectionPointLoad("aio-process-completion-before-shared"); - - InjectionPointAttach("aio-worker-after-reopen", - "test_aio", - "inj_io_reopen", - NULL, - 0); - InjectionPointLoad("aio-worker-after-reopen"); + InjectionPointAttach("aio-process-completion-before-shared", + "test_aio", + "inj_io_completion_hook", + NULL, + 0); + InjectionPointLoad("aio-process-completion-before-shared"); + + InjectionPointAttach("aio-worker-after-reopen", + "test_aio", + "inj_io_reopen", + NULL, + 0); + InjectionPointLoad("aio-worker-after-reopen"); #endif - } - else - { - /* - * Pre-load the injection points now, so we can call them in a - * critical section. - */ +} + +static void +test_aio_shmem_attach(void *arg) +{ + /* + * Pre-load the injection points now, so we can call them in a critical + * section. + */ #ifdef USE_INJECTION_POINTS - InjectionPointLoad("aio-process-completion-before-shared"); - InjectionPointLoad("aio-worker-after-reopen"); - elog(LOG, "injection point loaded"); + InjectionPointLoad("aio-process-completion-before-shared"); + InjectionPointLoad("aio-worker-after-reopen"); + elog(LOG, "injection point loaded"); #endif - } - - LWLockRelease(AddinShmemInitLock); } void @@ -155,10 +147,7 @@ _PG_init(void) if (!process_shared_preload_libraries_in_progress) return; - prev_shmem_request_hook = shmem_request_hook; - shmem_request_hook = test_aio_shmem_request; - prev_shmem_startup_hook = shmem_startup_hook; - shmem_startup_hook = test_aio_shmem_startup; + RegisterShmemCallbacks(&inj_io_shmem_callbacks); }