From 69b652f73dff61e949a1d4cb857a61f210cecc90 Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Fri, 20 Mar 2026 20:16:56 +0200 Subject: [PATCH v7 18/18] Convert all remaining subsystems to use the new API --- src/backend/access/common/syncscan.c | 78 +++---- src/backend/access/nbtree/nbtutils.c | 55 +++-- src/backend/access/transam/twophase.c | 77 +++---- src/backend/access/transam/xlog.c | 90 ++++---- src/backend/access/transam/xlogprefetcher.c | 53 ++--- src/backend/access/transam/xlogrecovery.c | 37 ++-- src/backend/access/transam/xlogwait.c | 52 ++--- src/backend/postmaster/autovacuum.c | 80 ++++--- src/backend/postmaster/bgworker.c | 107 +++++----- src/backend/postmaster/checkpointer.c | 58 +++--- src/backend/postmaster/pgarch.c | 45 ++-- src/backend/postmaster/walsummarizer.c | 63 +++--- src/backend/replication/logical/launcher.c | 58 +++--- src/backend/replication/logical/logicalctl.c | 31 ++- src/backend/replication/logical/origin.c | 61 +++--- src/backend/replication/logical/slotsync.c | 43 ++-- src/backend/replication/slot.c | 66 +++--- src/backend/replication/walreceiverfuncs.c | 53 ++--- src/backend/replication/walsender.c | 61 +++--- src/backend/storage/buffer/buf_init.c | 164 +++++++-------- src/backend/storage/buffer/buf_table.c | 39 ++-- src/backend/storage/buffer/freelist.c | 95 ++++----- src/backend/storage/ipc/ipci.c | 119 +---------- src/backend/storage/lmgr/lock.c | 140 ++++++------- src/backend/utils/activity/backend_status.c | 195 ++++++++---------- src/backend/utils/activity/pgstat_shmem.c | 160 +++++++------- src/include/access/nbtree.h | 2 - src/include/access/syncscan.h | 2 - src/include/access/twophase.h | 3 - src/include/access/xlog.h | 2 - src/include/access/xlogprefetcher.h | 3 - src/include/access/xlogrecovery.h | 3 - src/include/access/xlogwait.h | 2 - src/include/pgstat.h | 4 - src/include/postmaster/autovacuum.h | 4 - src/include/postmaster/bgworker_internals.h | 2 - src/include/postmaster/bgwriter.h | 3 - src/include/postmaster/pgarch.h | 2 - src/include/postmaster/walsummarizer.h | 2 - src/include/replication/logicalctl.h | 2 - src/include/replication/logicallauncher.h | 3 - src/include/replication/origin.h | 4 - src/include/replication/slot.h | 4 - src/include/replication/slotsync.h | 2 - src/include/replication/walreceiver.h | 2 - src/include/replication/walsender.h | 2 - src/include/storage/buf_internals.h | 6 +- src/include/storage/bufmgr.h | 4 - src/include/storage/lock.h | 2 - src/include/storage/subsystemlist.h | 26 +++ src/include/utils/backend_status.h | 8 - .../injection_points/injection_points.c | 61 ++---- 52 files changed, 1010 insertions(+), 1230 deletions(-) diff --git a/src/backend/access/common/syncscan.c b/src/backend/access/common/syncscan.c index 6fcfcb0e560..fc1889cbeb2 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,49 @@ 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); + static ShmemStructDesc SyncScanShmemDesc = { + .name = "Sync Scan Locations List", + .ptr = (void **) &scan_locations, + }; + SyncScanShmemDesc.size = SizeOfScanLocations(SYNC_SCAN_NELEM); + ShmemRequestStruct(&SyncScanShmemDesc); } /* * 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 9b091858997..a1a9faa2c78 100644 --- a/src/backend/access/nbtree/nbtutils.c +++ b/src/backend/access/nbtree/nbtutils.c @@ -24,6 +24,7 @@ #include "common/int.h" #include "lib/qunique.h" #include "miscadmin.h" +#include "storage/subsystems.h" #include "utils/datum.h" #include "utils/lsyscache.h" #include "utils/rel.h" @@ -416,6 +417,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, @@ -552,47 +560,38 @@ _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) { + static ShmemStructDesc BTreeShmemDesc = { + .name = "BTree Vacuum State", + .ptr = (void **) &btvacinfo, + }; Size size; size = offsetof(BTVacInfo, vacuums); size = add_size(size, mul_size(MaxBackends, sizeof(BTOneVacInfo))); - return size; + BTreeShmemDesc.size = size; + ShmemRequestStruct(&BTreeShmemDesc); } /* * 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 d468c9774b3..cc7c6beab42 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" @@ -187,8 +188,16 @@ typedef struct TwoPhaseStateData GlobalTransaction prepXacts[FLEXIBLE_ARRAY_MEMBER]; } TwoPhaseStateData; +static void TwoPhaseShmemRequest(void *arg); +static void TwoPhaseShmemInit(void *arg); + static TwoPhaseStateData *TwoPhaseState; +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,11 +243,15 @@ 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) { + static ShmemStructDesc TwoPhaseShmemDesc = { + .name = "Prepared Transaction Table", + .ptr = (void **) &TwoPhaseState, + }; Size size; /* Need the fixed struct, the array of pointers, and the GTD structs */ @@ -248,46 +261,38 @@ TwoPhaseShmemSize(void) size = MAXALIGN(size); size = add_size(size, mul_size(max_prepared_xacts, sizeof(GlobalTransactionData))); - - return size; + TwoPhaseShmemDesc.size = size; + ShmemRequestStruct(&TwoPhaseShmemDesc); } -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 InitProcGlobal */ - gxacts[i].pgprocno = GetNumberFromPGProc(&PreparedXactProcs[i]); - } + /* associate it with a PGPROC assigned by InitProcGlobal */ + 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 35d9a09f5da..39791629a6f 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -94,6 +94,7 @@ #include "storage/procarray.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" @@ -566,6 +567,16 @@ typedef enum WALINSERT_SPECIAL_CHECKPOINT } WalInsertClass; +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, +}; + static XLogCtlData *XLogCtl = NULL; /* a private copy of XLogCtl->Insert.WALInsertLocks, for convenience */ @@ -574,6 +585,7 @@ static WALInsertLockPadded *WALInsertLocks = NULL; /* * We maintain an image of pg_control in shared memory. */ +static ControlFileData *LocalControlFile = NULL; static ControlFileData *ControlFile = NULL; /* @@ -4923,7 +4935,8 @@ void LocalProcessControlFile(bool reset) { Assert(reset || ControlFile == NULL); - ControlFile = palloc_object(ControlFileData); + LocalControlFile = palloc_object(ControlFileData); + ControlFile = LocalControlFile; ReadControlFile(); } @@ -4939,11 +4952,22 @@ GetActiveWalLevelOnStandby(void) } /* - * Initialization of shared memory for XLOG + * Register shared memory for XLOG. */ -Size -XLOGShmemSize(void) -{ +static void +XLOGShmemRequest(void *arg) +{ + static ShmemStructDesc XLogCtlShmemDesc = { + .name = "XLOG Ctl", + .size = 0, /* calculated later */ + .ptr = (void **) &XLogCtl, + }; + + static ShmemStructDesc ControlFileShmemDesc = { + .name = "Control File", + .size = sizeof(ControlFileData), + .ptr = (void **) &ControlFile, + }; Size size; /* @@ -4982,23 +5006,19 @@ 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; + XLogCtlShmemDesc.size = size; + ShmemRequestStruct(&XLogCtlShmemDesc); + ShmemRequestStruct(&ControlFileShmemDesc); } -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 @@ -5016,36 +5036,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; } /* @@ -5102,6 +5103,15 @@ XLOGShmemInit(void) pg_atomic_init_u64(&XLogCtl->unloggedLSN, InvalidXLogRecPtr); } +/* + * XLOGShmemAttach - set up 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..9ea79a49851 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,27 @@ lrq_complete_lsn(LsnReadQueue *lrq, XLogRecPtr lsn) lrq_prefetch(lrq); } -size_t -XLogPrefetchShmemSize(void) +static void +XLogPrefetchShmemRequest(void *arg) +{ + static ShmemStructDesc XLogPrefetchShmemDesc = { + .name = "XLogPrefetchStats", + .size = sizeof(XLogPrefetchStats), + .ptr = (void **) &SharedStats, + }; + ShmemRequestStruct(&XLogPrefetchShmemDesc); +} + +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 +339,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 6d2c4a86b96..fbbbec8b6ff 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,22 @@ 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; + static ShmemStructDesc XLogRecoveryShmemDesc = { + .name = "XLOG Recovery Ctl", + .size = sizeof(XLogRecoveryCtlData), + .ptr = (void **) &XLogRecoveryCtl, + }; + ShmemRequestStruct(&XLogRecoveryShmemDesc); } -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..cc633c70554 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,36 @@ 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) { + static ShmemStructDesc WaitLSNShmemDesc = { + .name = "WaitLSNState", + .ptr = (void **) &waitLSNState, + }; Size size; size = offsetof(WaitLSNState, procInfos); size = add_size(size, mul_size(MaxBackends + NUM_AUXILIARY_PROCS, sizeof(WaitLSNProcInfo))); - return size; + WaitLSNShmemDesc.size = size; + ShmemRequestStruct(&WaitLSNShmemDesc); } /* 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 219673db930..26b38394e8a 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -97,6 +97,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" @@ -305,6 +306,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 @@ -3356,12 +3365,16 @@ 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) { + static ShmemStructDesc AutoVacuumShmemDesc = { + .name = "AutoVacuum Data", + .ptr = (void **) &AutoVacuumShmem, + }; Size size; /* @@ -3371,53 +3384,38 @@ AutoVacuumShmemSize(void) size = MAXALIGN(size); size = add_size(size, mul_size(autovacuum_worker_slots, sizeof(WorkerInfoData))); - return size; + AutoVacuumShmemDesc.size = size; + ShmemRequestStruct(&AutoVacuumShmemDesc); } /* * 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; - - Assert(!found); + WorkerInfo worker; - 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 d1fe3cc71ce..a93589018b5 100644 --- a/src/backend/postmaster/bgworker.c +++ b/src/backend/postmaster/bgworker.c @@ -29,6 +29,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" @@ -109,6 +110,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. @@ -151,77 +160,71 @@ 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) { + static ShmemStructDesc BackgroundWorkerShmemDesc = { + .name = "Background Worker Data", + .ptr = (void **) &BackgroundWorkerData, + }; Size size; /* Array of workers is variably sized. */ size = offsetof(BackgroundWorkerArray, slot); size = add_size(size, mul_size(max_worker_processes, sizeof(BackgroundWorkerSlot))); - - return size; + BackgroundWorkerShmemDesc.size = size; + ShmemRequestStruct(&BackgroundWorkerShmemDesc); } /* - * 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..08999c2a459 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,12 +959,16 @@ 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) { + static ShmemStructDesc CheckpointerShmemDesc = { + .name = "Checkpointer Data", + .ptr = (void **) &CheckpointerShmem, + }; Size size; /* @@ -967,39 +980,22 @@ CheckpointerShmemSize(void) size = add_size(size, mul_size(Min(NBuffers, MAX_CHECKPOINT_REQUESTS), sizeof(CheckpointerRequest))); - - return size; + CheckpointerShmemDesc.size = size; + ShmemRequestStruct(&CheckpointerShmemDesc); } /* * 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/pgarch.c b/src/backend/postmaster/pgarch.c index fa4bdfe9ab9..2078e1fbcec 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,33 @@ 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) +{ + static ShmemStructDesc PgArchShmemDesc = { + .name = "Archiver Data", + .size = sizeof(PgArchData), + .ptr = (void **) &PgArch, + }; + ShmemRequestStruct(&PgArchShmemDesc); } -/* 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 e1aa102f41d..f01ec027089 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,37 @@ 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); + static ShmemStructDesc WalSummarizerShmemDesc = { + .name = "Wal Summarizer Ctl", + .size = sizeof(WalSummarizerData), + .ptr = (void **) &WalSummarizerCtl, + }; + ShmemRequestStruct(&WalSummarizerShmemDesc); } /* - * 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..76245d056ca 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,12 +981,16 @@ 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) { + static ShmemStructDesc ApplyLauncherShmemDesc = { + .name = "Logical Replication Launcher Data", + .ptr = (void **) &LogicalRepCtx, + }; Size size; /* @@ -987,7 +1000,8 @@ ApplyLauncherShmemSize(void) size = MAXALIGN(size); size = add_size(size, mul_size(max_logical_replication_workers, sizeof(LogicalRepWorker))); - return size; + ApplyLauncherShmemDesc.size = size; + ShmemRequestStruct(&ApplyLauncherShmemDesc); } /* @@ -1028,35 +1042,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..af2d44eb386 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,15 @@ 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()); + static ShmemStructDesc LogicalDecodingCtlShmemDesc = { + .name = "Logical decoding control", + .size = sizeof(LogicalDecodingCtlData), + .ptr = (void **) &LogicalDecodingCtl, + }; + ShmemRequestStruct(&LogicalDecodingCtlShmemDesc); } /* diff --git a/src/backend/replication/logical/origin.c b/src/backend/replication/logical/origin.c index 26afd8f0af9..48582c60c89 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,50 @@ replorigin_by_oid(ReplOriginId roident, bool missing_ok, char **roname) * --------------------------------------------------------------------------- */ -Size -ReplicationOriginShmemSize(void) +static void +ReplicationOriginShmemRequest(void *arg) { + static ShmemStructDesc ReplicationOriginShmemDesc = { + .name = "ReplicationOriginState", + .ptr = (void **) &replication_states_ctl, + }; 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; + ReplicationOriginShmemDesc.size = size; + ShmemRequestStruct(&ReplicationOriginShmemDesc); } -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..f0664dc4890 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,28 @@ 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); + static ShmemStructDesc SlotSyncShmemDesc = { + .name = "Slot Sync Data", + .size = sizeof(SlotSyncCtxStruct), + .ptr = (void **) &SlotSyncCtx, + }; + ShmemRequestStruct(&SlotSyncShmemDesc); } /* - * 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..1ae161e6288 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,43 @@ 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; + static ShmemStructDesc ReplicationSlotsShmemDesc = { + .name = "ReplicationSlot Ctl", + .ptr = (void **) &ReplicationSlotCtl, + }; + 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; + ReplicationSlotsShmemDesc.size = size; + ShmemRequestStruct(&ReplicationSlotsShmemDesc); } /* - * 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..16d94a706ea 100644 --- a/src/backend/replication/walreceiverfuncs.c +++ b/src/backend/replication/walreceiverfuncs.c @@ -29,47 +29,48 @@ #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; + static ShmemStructDesc WalRcvShmemDesc = { + .name = "Wal Receiver Ctl", + .size = sizeof(WalRcvData), + .ptr = (void **) &WalRcv, + }; + ShmemRequestStruct(&WalRcvShmemDesc); } -/* 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 08253103cb3..86170c2fd29 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; @@ -3760,47 +3769,39 @@ 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; + static ShmemStructDesc WalSndShmemDesc = { + .name = "Wal Sender Ctl", + .ptr = (void **) &WalSndCtl, + }; + Size size; size = offsetof(WalSndCtlData, walsnds); size = add_size(size, mul_size(max_wal_senders, sizeof(WalSnd))); - - return size; + WalSndShmemDesc.size = size; + ShmemRequestStruct(&WalSndShmemDesc); } -/* 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/buffer/buf_init.c b/src/backend/storage/buffer/buf_init.c index c0c223b2e32..cb9f86dab5c 100644 --- a/src/backend/storage/buffer/buf_init.c +++ b/src/backend/storage/buffer/buf_init.c @@ -18,6 +18,8 @@ #include "storage/buf_internals.h" #include "storage/bufmgr.h" #include "storage/proclist.h" +#include "storage/shmem.h" +#include "storage/subsystems.h" BufferDescPadded *BufferDescriptors; char *BufferBlocks; @@ -25,6 +27,15 @@ ConditionVariableMinimallyPadded *BufferIOCVArray; WritebackContext BackendWritebackContext; CkptSortItem *CkptBufferIds; +static void BufferManagerShmemRequest(void *arg); +static void BufferManagerShmemInit(void *arg); +static void BufferManagerShmemAttach(void *arg); + +const ShmemCallbacks BufferManagerShmemCallbacks = { + .request_fn = BufferManagerShmemRequest, + .init_fn = BufferManagerShmemInit, + .attach_fn = BufferManagerShmemAttach, +}; /* * Data Structures: @@ -60,37 +71,42 @@ CkptSortItem *CkptBufferIds; /* - * Initialize shared buffer pool - * - * This is called once during shared-memory initialization (either in the - * postmaster, or in a standalone backend). + * Register shared memory area for the buffer pool. */ -void -BufferManagerShmemInit(void) +static void +BufferManagerShmemRequest(void *arg) { - bool foundBufs, - foundDescs, - foundIOCV, - foundBufCkpt; - - /* Align descriptors to a cacheline boundary. */ - BufferDescriptors = (BufferDescPadded *) - ShmemInitStruct("Buffer Descriptors", - NBuffers * sizeof(BufferDescPadded), - &foundDescs); - - /* Align buffer pool on IO page size boundary. */ - BufferBlocks = (char *) - TYPEALIGN(PG_IO_ALIGN_SIZE, - ShmemInitStruct("Buffer Blocks", - NBuffers * (Size) BLCKSZ + PG_IO_ALIGN_SIZE, - &foundBufs)); - - /* Align condition variables to cacheline boundary. */ - BufferIOCVArray = (ConditionVariableMinimallyPadded *) - ShmemInitStruct("Buffer IO Condition Variables", - NBuffers * sizeof(ConditionVariableMinimallyPadded), - &foundIOCV); + static ShmemStructDesc BufferDescriptorsShmemDesc = { + .name = "Buffer Descriptors", + /* Align descriptors to a cacheline boundary. */ + .alignment = PG_CACHE_LINE_SIZE, + .ptr = (void **) &BufferDescriptors, + }; + static ShmemStructDesc BufferBlocksShmemDesc = { + .name = "Buffer Blocks", + /* Align buffer pool on IO page size boundary. */ + .alignment = PG_IO_ALIGN_SIZE, + .ptr = (void **) &BufferBlocks, + }; + static ShmemStructDesc BufferIOCVArrayShmemDesc = { + .name = "Buffer IO Condition Variables", + /* Align descriptors to a cacheline boundary. */ + .alignment = PG_CACHE_LINE_SIZE, + .ptr = (void **) &BufferIOCVArray, + }; + static ShmemStructDesc CkptBufferIdsShmemDesc = { + .name = "Checkpoint BufferIds", + .ptr = (void **) &CkptBufferIds, + }; + + BufferDescriptorsShmemDesc.size = NBuffers * sizeof(BufferDescPadded); + ShmemRequestStruct(&BufferDescriptorsShmemDesc); + + BufferBlocksShmemDesc.size = NBuffers * (Size) BLCKSZ; + ShmemRequestStruct(&BufferBlocksShmemDesc); + + BufferIOCVArrayShmemDesc.size = NBuffers * sizeof(ConditionVariableMinimallyPadded); + ShmemRequestStruct(&BufferIOCVArrayShmemDesc); /* * The array used to sort to-be-checkpointed buffer ids is located in @@ -99,80 +115,48 @@ BufferManagerShmemInit(void) * the checkpointer is restarted, memory allocation failures would be * painful. */ - CkptBufferIds = (CkptSortItem *) - ShmemInitStruct("Checkpoint BufferIds", - NBuffers * sizeof(CkptSortItem), &foundBufCkpt); + CkptBufferIdsShmemDesc.size = NBuffers * sizeof(CkptSortItem); + ShmemRequestStruct(&CkptBufferIdsShmemDesc); +} - if (foundDescs || foundBufs || foundIOCV || foundBufCkpt) - { - /* should find all of these, or none of them */ - Assert(foundDescs && foundBufs && foundIOCV && foundBufCkpt); - /* note: this path is only taken in EXEC_BACKEND case */ - } - else +/* + * Initialize shared buffer pool + * + * This is called once during shared-memory initialization (either in the + * postmaster, or in a standalone backend). + */ +static void +BufferManagerShmemInit(void *arg) +{ + /* + * Initialize all the buffer headers. + */ + for (int i = 0; i < NBuffers; i++) { - int i; - - /* - * Initialize all the buffer headers. - */ - for (i = 0; i < NBuffers; i++) - { - BufferDesc *buf = GetBufferDescriptor(i); + BufferDesc *buf = GetBufferDescriptor(i); - ClearBufferTag(&buf->tag); + ClearBufferTag(&buf->tag); - pg_atomic_init_u64(&buf->state, 0); - buf->wait_backend_pgprocno = INVALID_PROC_NUMBER; + pg_atomic_init_u64(&buf->state, 0); + buf->wait_backend_pgprocno = INVALID_PROC_NUMBER; - buf->buf_id = i; + buf->buf_id = i; - pgaio_wref_clear(&buf->io_wref); + pgaio_wref_clear(&buf->io_wref); - proclist_init(&buf->lock_waiters); - ConditionVariableInit(BufferDescriptorGetIOCV(buf)); - } + proclist_init(&buf->lock_waiters); + ConditionVariableInit(BufferDescriptorGetIOCV(buf)); } - /* Init other shared buffer-management stuff */ - StrategyInitialize(!foundDescs); - /* Initialize per-backend file flush context */ WritebackContextInit(&BackendWritebackContext, &backend_flush_after); } -/* - * BufferManagerShmemSize - * - * compute the size of shared memory for the buffer pool including - * data pages, buffer descriptors, hash tables, etc. - */ -Size -BufferManagerShmemSize(void) +static void +BufferManagerShmemAttach(void *arg) { - Size size = 0; - - /* size of buffer descriptors */ - size = add_size(size, mul_size(NBuffers, sizeof(BufferDescPadded))); - /* to allow aligning buffer descriptors */ - size = add_size(size, PG_CACHE_LINE_SIZE); - - /* size of data pages, plus alignment padding */ - size = add_size(size, PG_IO_ALIGN_SIZE); - size = add_size(size, mul_size(NBuffers, BLCKSZ)); - - /* size of stuff controlled by freelist.c */ - size = add_size(size, StrategyShmemSize()); - - /* size of I/O condition variables */ - size = add_size(size, mul_size(NBuffers, - sizeof(ConditionVariableMinimallyPadded))); - /* to allow aligning the above */ - size = add_size(size, PG_CACHE_LINE_SIZE); - - /* size of checkpoint sort array in bufmgr.c */ - size = add_size(size, mul_size(NBuffers, sizeof(CkptSortItem))); - - return size; + /* Initialize per-backend file flush context */ + WritebackContextInit(&BackendWritebackContext, + &backend_flush_after); } diff --git a/src/backend/storage/buffer/buf_table.c b/src/backend/storage/buffer/buf_table.c index 23d85fd32e2..67487fe0652 100644 --- a/src/backend/storage/buffer/buf_table.c +++ b/src/backend/storage/buffer/buf_table.c @@ -32,37 +32,24 @@ typedef struct static HTAB *SharedBufHash; - -/* - * Estimate space needed for mapping hashtable - * size is the desired hash table size (possibly more than NBuffers) - */ -Size -BufTableShmemSize(int size) -{ - return hash_estimate_size(size, sizeof(BufferLookupEnt)); -} - /* - * Initialize shmem hash table for mapping buffers + * Register shmem hash table for mapping buffers. * size is the desired hash table size (possibly more than NBuffers) */ void -InitBufTable(int size) +BufTableShmemRequest(int size) { - HASHCTL info; - - /* assume no locking is needed yet */ - - /* BufferTag maps to Buffer */ - info.keysize = sizeof(BufferTag); - info.entrysize = sizeof(BufferLookupEnt); - info.num_partitions = NUM_BUFFER_PARTITIONS; - - SharedBufHash = ShmemInitHash("Shared Buffer Lookup Table", - size, size, - &info, - HASH_ELEM | HASH_BLOBS | HASH_PARTITION | HASH_FIXED_SIZE); + static ShmemHashDesc SharedBufHashDesc = { + .name = "Shared Buffer Lookup Table", + .ptr = &SharedBufHash, + .hash_info.keysize = sizeof(BufferTag), + .hash_info.entrysize = sizeof(BufferLookupEnt), + .hash_info.num_partitions = NUM_BUFFER_PARTITIONS, + .hash_flags = HASH_ELEM | HASH_BLOBS | HASH_PARTITION | HASH_FIXED_SIZE, + }; + SharedBufHashDesc.max_size = size; + SharedBufHashDesc.init_size = size; + ShmemRequestHash(&SharedBufHashDesc); } /* diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c index b7687836188..d9bc3c1a113 100644 --- a/src/backend/storage/buffer/freelist.c +++ b/src/backend/storage/buffer/freelist.c @@ -20,6 +20,8 @@ #include "storage/buf_internals.h" #include "storage/bufmgr.h" #include "storage/proc.h" +#include "storage/shmem.h" +#include "storage/subsystems.h" #define INT_ACCESS_ONCE(var) ((int)(*((volatile int *)&(var)))) @@ -56,6 +58,14 @@ typedef struct /* Pointers to shared state */ static BufferStrategyControl *StrategyControl = NULL; +static void StrategyCtlShmemRequest(void *arg); +static void StrategyCtlShmemInit(void *arg); + +const ShmemCallbacks StrategyCtlShmemCallbacks = { + .request_fn = StrategyCtlShmemRequest, + .init_fn = StrategyCtlShmemInit, +}; + /* * Private (non-shared) state for managing a ring of shared buffers to re-use. * This is currently the only kind of BufferAccessStrategy object, but someday @@ -369,41 +379,21 @@ StrategyNotifyBgWriter(int bgwprocno) /* - * StrategyShmemSize - * - * estimate the size of shared memory used by the freelist-related structures. - * - * Note: for somewhat historical reasons, the buffer lookup hashtable size - * is also determined here. + * StrategyCtlShmemRequest -- register shared memory for the buffer + * cache replacement strategy. */ -Size -StrategyShmemSize(void) -{ - Size size = 0; - - /* size of lookup hash table ... see comment in StrategyInitialize */ - size = add_size(size, BufTableShmemSize(NBuffers + NUM_BUFFER_PARTITIONS)); - - /* size of the shared replacement strategy control block */ - size = add_size(size, MAXALIGN(sizeof(BufferStrategyControl))); - - return size; -} - -/* - * StrategyInitialize -- initialize the buffer cache replacement - * strategy. - * - * Assumes: All of the buffers are already built into a linked list. - * Only called by postmaster and only during initialization. - */ -void -StrategyInitialize(bool init) +static void +StrategyCtlShmemRequest(void *arg) { - bool found; + static ShmemStructDesc StrategyCtlShmemDesc = { + .name = "Buffer Strategy Status", + .size = sizeof(BufferStrategyControl), + .ptr = (void **) &StrategyControl, + }; + ShmemRequestStruct(&StrategyCtlShmemDesc); /* - * Initialize the shared buffer lookup hashtable. + * Request the shared buffer lookup hashtable. * * Since we can't tolerate running out of lookup table entries, we must be * sure to specify an adequate table size here. The maximum steady-state @@ -412,37 +402,26 @@ StrategyInitialize(bool init) * happening in each partition concurrently, so we could need as many as * NBuffers + NUM_BUFFER_PARTITIONS entries. */ - InitBufTable(NBuffers + NUM_BUFFER_PARTITIONS); - - /* - * Get or create the shared strategy control block - */ - StrategyControl = (BufferStrategyControl *) - ShmemInitStruct("Buffer Strategy Status", - sizeof(BufferStrategyControl), - &found); - - if (!found) - { - /* - * Only done once, usually in postmaster - */ - Assert(init); + BufTableShmemRequest(NBuffers + NUM_BUFFER_PARTITIONS); +} - SpinLockInit(&StrategyControl->buffer_strategy_lock); +/* + * StrategyCtlShmemInit -- initialize the buffer cache replacement strategy. + */ +static void +StrategyCtlShmemInit(void *arg) +{ + SpinLockInit(&StrategyControl->buffer_strategy_lock); - /* Initialize the clock-sweep pointer */ - pg_atomic_init_u32(&StrategyControl->nextVictimBuffer, 0); + /* Initialize the clock-sweep pointer */ + pg_atomic_init_u32(&StrategyControl->nextVictimBuffer, 0); - /* Clear statistics */ - StrategyControl->completePasses = 0; - pg_atomic_init_u32(&StrategyControl->numBufferAllocs, 0); + /* Clear statistics */ + StrategyControl->completePasses = 0; + pg_atomic_init_u32(&StrategyControl->numBufferAllocs, 0); - /* No pending notification */ - StrategyControl->bgwprocno = -1; - } - else - Assert(!init); + /* No pending notification */ + StrategyControl->bgwprocno = -1; } diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c index b5f3df68963..02618684ea2 100644 --- a/src/backend/storage/ipc/ipci.c +++ b/src/backend/storage/ipc/ipci.c @@ -14,36 +14,13 @@ */ #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/walsummarizer.h" -#include "replication/logicallauncher.h" -#include "replication/origin.h" -#include "replication/slot.h" -#include "replication/slotsync.h" -#include "replication/walreceiver.h" -#include "replication/walsender.h" -#include "storage/aio_subsys.h" -#include "storage/bufmgr.h" #include "storage/dsm.h" #include "storage/ipc.h" +#include "storage/lock.h" #include "storage/pg_shmem.h" #include "storage/pmsignal.h" -#include "storage/predicate.h" #include "storage/proc.h" #include "storage/subsystems.h" #include "utils/guc.h" @@ -55,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 @@ -95,32 +70,6 @@ CalculateShmemSize(void) size = 100000; size = add_size(size, ShmemGetRequestedSize()); - /* legacy subsystems */ - size = add_size(size, BufferManagerShmemSize()); - 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, LWLockShmemSize()); - 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, SlotSyncShmemSize()); - size = add_size(size, WaitLSNShmemSize()); - size = add_size(size, LogicalDecodingCtlShmemSize()); - /* include additional requested shmem from preload libraries */ size = add_size(size, total_addin_request); @@ -154,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 @@ -212,9 +160,6 @@ CreateSharedMemoryAndSemaphores(void) /* Initialize all shmem areas */ ShmemInitRequested(); - /* Initialize legacy subsystems */ - CreateOrAttachShmemStructs(); - /* Initialize dynamic shared memory facilities. */ dsm_postmaster_startup(shim); @@ -243,68 +188,6 @@ RegisterBuiltinShmemCallbacks(void) RegisterShmemCallbacks(builtin_subsystems[i]); } -/* - * 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(); - BufferManagerShmemInit(); - - /* - * 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(); - - /* - * Set up other modules that need some shared memory space - */ - BTreeShmemInit(); - SyncScanShmemInit(); - StatsShmemInit(); - WaitLSNShmemInit(); - LogicalDecodingCtlShmemInit(); -} - /* * InitializeShmemGUCs * diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index d930c66cdbd..1e9353f2b1b 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -42,8 +42,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" @@ -311,6 +313,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 @@ -408,6 +418,7 @@ PROCLOCK_PRINT(const char *where, const PROCLOCK *proclockP) static uint32 proclock_hash(const void *key, Size keysize); + static void RemoveLocalLock(LOCALLOCK *locallock); static PROCLOCK *SetupLockInTable(LockMethod lockMethodTable, PGPROC *proc, const LOCKTAG *locktag, uint32 hashcode, LOCKMODE lockmode); @@ -431,71 +442,60 @@ 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 init_table_size, - max_table_size; - bool found; + static ShmemHashDesc LockHashDesc = { + .name = "LOCK hash", + .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, + }; + static ShmemHashDesc ProcLockHashDesc = { + .name = "PROCLOCK hash", + .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, + }; + static ShmemStructDesc FastPathShmemDesc = { + .name = "Fast Path Strong Relation Lock Data", + .size = sizeof(FastPathStrongRelationLockData), + .ptr = (void **) (void *) &FastPathStrongRelationLocks, + }; + long max_table_size = NLOCKENTS(); + + LockHashDesc.max_size = max_table_size; + LockHashDesc.init_size = max_table_size / 2; + ShmemRequestHash(&LockHashDesc); + + ProcLockHashDesc.max_size = max_table_size * 2; + ProcLockHashDesc.init_size = max_table_size; + ShmemRequestHash(&ProcLockHashDesc); + + ShmemRequestStruct(&FastPathShmemDesc); /* - * Compute init/max size to request for lock hashtables. Note these - * calculations must agree with LockManagerShmemSize! - */ - max_table_size = NLOCKENTS(); - init_table_size = max_table_size / 2; - - /* - * Allocate 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", - init_table_size, - max_table_size, - &info, - HASH_ELEM | HASH_BLOBS | HASH_PARTITION); - - /* Assume an average of 2 holders per lock */ - max_table_size *= 2; - init_table_size *= 2; - - /* - * Allocate hash table for PROCLOCK structs. This stores - * per-lock-per-holder information. + * FIXME: we used to do this in the size calculation: + * + * // Since NLOCKENTS is only an estimate, add 10% safety margin. + * size = add_size(size, size / 10); */ - info.keysize = sizeof(PROCLOCKTAG); - info.entrysize = sizeof(PROCLOCK); - info.hash = proclock_hash; - info.num_partitions = NUM_LOCK_PARTITIONS; - - LockMethodProcLockHash = ShmemInitHash("PROCLOCK hash", - init_table_size, - max_table_size, - &info, - HASH_ELEM | HASH_FUNCTION | HASH_PARTITION); +} - /* - * 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); } /* @@ -3749,30 +3749,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))); - - /* - * Since NLOCKENTS is only an estimate, add 10% safety margin. - */ - size = add_size(size, size / 10); - - return size; -} /* * GetLockStatusData - Return a summary of the lock manager's internal diff --git a/src/backend/utils/activity/backend_status.c b/src/backend/utils/activity/backend_status.c index cd087129469..e986219e534 100644 --- a/src/backend/utils/activity/backend_status.c +++ b/src/backend/utils/activity/backend_status.c @@ -18,7 +18,9 @@ #include "pgstat.h" #include "storage/ipc.h" #include "storage/proc.h" /* for MyProc */ +#include "storage/shmem.h" #include "storage/procarray.h" +#include "storage/subsystems.h" #include "utils/ascii.h" #include "utils/guc.h" /* for application_name */ #include "utils/memutils.h" @@ -73,133 +75,119 @@ 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)); + static ShmemStructDesc BackendStatusArrayShmemDesc = { + .name = "Backend Status Array", + .ptr = (void **) &BackendStatusArray, + }; + static ShmemStructDesc BackendAppnameBufferShmemDesc = { + .name = "Backend Application Name Buffer", + .ptr = (void **) &BackendAppnameBuffer, + }; + static ShmemStructDesc BackendClientHostnameBufferShmemDesc = { + .name = "Backend Client Host Name Buffer", + .ptr = (void **) &BackendClientHostnameBuffer, + }; + static ShmemStructDesc BackendActivityBufferSizeShmemDesc = { + .name = "Backend Activity Buffer", + .ptr = (void **) &BackendActivityBuffer + }; + + BackendStatusArrayShmemDesc.size = + mul_size(sizeof(PgBackendStatus), NumBackendStatSlots); + ShmemRequestStruct(&BackendStatusArrayShmemDesc); + + BackendAppnameBufferShmemDesc.size = + mul_size(NAMEDATALEN, NumBackendStatSlots); + ShmemRequestStruct(&BackendAppnameBufferShmemDesc); + + BackendClientHostnameBufferShmemDesc.size = + mul_size(NAMEDATALEN, NumBackendStatSlots); + ShmemRequestStruct(&BackendClientHostnameBufferShmemDesc); + + BackendActivityBufferSize = mul_size(pgstat_track_activity_query_size, + NumBackendStatSlots); + BackendActivityBufferSizeShmemDesc.size = BackendActivityBufferSize; + ShmemRequestStruct(&BackendActivityBufferSizeShmemDesc); + #ifdef USE_SSL - /* BackendSslStatusBuffer: */ - size = add_size(size, - mul_size(sizeof(PgBackendSSLStatus), NumBackendStatSlots)); + { + static ShmemStructDesc BackendSslStatusBufferShmemDesc = { + .name = "Backend SSL Status Buffer", + .ptr = (void **) &BackendSslStatusBuffer, + }; + BackendSslStatusBufferShmemDesc.size = + mul_size(sizeof(PgBackendSSLStatus), NumBackendStatSlots); + ShmemRequestStruct(&BackendSslStatusBufferShmemDesc); + } #endif + #ifdef ENABLE_GSS - /* BackendGssStatusBuffer: */ - size = add_size(size, - mul_size(sizeof(PgBackendGSSStatus), NumBackendStatSlots)); + { + static ShmemStructDesc BackendGssStatusBufferShmemDesc = { + .name = "Backend GSS Status Buffer", + .ptr = (void **) &BackendGssStatusBuffer, + }; + BackendGssStatusBufferShmemDesc.size = + mul_size(sizeof(PgBackendGSSStatus), NumBackendStatSlots); + ShmemRequestStruct(&BackendGssStatusBufferShmemDesc); + } #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 +199,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 +213,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..765b04c687b 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,100 @@ StatsShmemSize(void) return sz; } +/* + * Register shared memory area for cumulative statistics + */ +static void +StatsShmemRequest(void *arg) +{ + static ShmemStructDesc StatsShmemDesc = { + .name = "Shared Memory Stats", + .ptr = (void **) &pgStatLocal.shmem, + }; + StatsShmemDesc.size = StatsShmemSize(); + ShmemRequestStruct(&StatsShmemDesc); +} + /* * 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/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 e312514ba87..f8622cc1add 100644 --- a/src/include/access/twophase.h +++ b/src/include/access/twophase.h @@ -28,9 +28,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 dcc12eb8cbe..1a098a91444 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -246,8 +246,6 @@ extern char *GetMockAuthenticationNonce(void); extern bool DataChecksumsEnabled(void); 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 216b93492ba..7fbf036bb9b 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -522,10 +522,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 5aa0f3a8ac1..6ebfafe640d 100644 --- a/src/include/postmaster/autovacuum.h +++ b/src/include/postmaster/autovacuum.h @@ -62,8 +62,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/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 9b9bd916314..22474e47110 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 WalRcvForceReply(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/buf_internals.h b/src/include/storage/buf_internals.h index 8d1e16b5d51..d7f8a8c1e63 100644 --- a/src/include/storage/buf_internals.h +++ b/src/include/storage/buf_internals.h @@ -570,12 +570,8 @@ extern bool StrategyRejectBuffer(BufferAccessStrategy strategy, extern int StrategySyncStart(uint32 *complete_passes, uint32 *num_buf_alloc); extern void StrategyNotifyBgWriter(int bgwprocno); -extern Size StrategyShmemSize(void); -extern void StrategyInitialize(bool init); - /* buf_table.c */ -extern Size BufTableShmemSize(int size); -extern void InitBufTable(int size); +extern void BufTableShmemRequest(int size); extern uint32 BufTableHashCode(BufferTag *tagPtr); extern int BufTableLookup(BufferTag *tagPtr, uint32 hashcode); extern int BufTableInsert(BufferTag *tagPtr, uint32 hashcode, int buf_id); diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h index 4017896f951..26441886035 100644 --- a/src/include/storage/bufmgr.h +++ b/src/include/storage/bufmgr.h @@ -369,10 +369,6 @@ extern void MarkDirtyAllUnpinnedBuffers(int32 *buffers_dirtied, int32 *buffers_already_dirty, int32 *buffers_skipped); -/* in buf_init.c */ -extern void BufferManagerShmemInit(void); -extern Size BufferManagerShmemSize(void); - /* in localbuf.c */ extern void AtProcExit_LocalBuffers(void); diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h index 9505701a805..7053e234383 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 e8e06be30c2..206d6b586ad 100644 --- a/src/include/storage/subsystemlist.h +++ b/src/include/storage/subsystemlist.h @@ -25,10 +25,18 @@ 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) PG_SHMEM_SUBSYSTEM(MultiXactShmemCallbacks) +PG_SHMEM_SUBSYSTEM(BufferManagerShmemCallbacks) +PG_SHMEM_SUBSYSTEM(StrategyCtlShmemCallbacks) + +/* lock manager */ +PG_SHMEM_SUBSYSTEM(LockManagerShmemCallbacks) /* predicate lock manager */ PG_SHMEM_SUBSYSTEM(PredicateLockShmemCallbacks) @@ -36,6 +44,9 @@ 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) @@ -43,11 +54,26 @@ 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) /* 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/test/modules/injection_points/injection_points.c b/src/test/modules/injection_points/injection_points.c index d59c5ad0582..d9b2bd4bd66 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,25 @@ 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); + static ShmemStructDesc InjectionPointsShmemDesc = { + .name = "injection_points", + .size = sizeof(InjectionPointSharedState), + .ptr = (void **) &inj_state, + }; + ShmemRequestStruct(&InjectionPointsShmemDesc); } 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 +586,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); } -- 2.47.3