]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Convert all remaining subsystems to use the new shmem allocation API
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Sun, 5 Apr 2026 23:13:10 +0000 (02:13 +0300)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Sun, 5 Apr 2026 23:13:10 +0000 (02:13 +0300)
This removes all remaining uses of ShmemInitStruct() and
ShmemInitHash() from built-in code.

Reviewed-by: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Reviewed-by: Matthias van de Meent <boekewurm+postgres@gmail.com>
Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Discussion: https://www.postgresql.org/message-id/CAExHW5vM1bneLYfg0wGeAa=52UiJ3z4vKd3AJ72X8Fw6k3KKrg@mail.gmail.com

54 files changed:
src/backend/access/common/syncscan.c
src/backend/access/nbtree/nbtutils.c
src/backend/access/transam/twophase.c
src/backend/access/transam/xlog.c
src/backend/access/transam/xlogprefetcher.c
src/backend/access/transam/xlogrecovery.c
src/backend/access/transam/xlogwait.c
src/backend/postmaster/autovacuum.c
src/backend/postmaster/bgworker.c
src/backend/postmaster/checkpointer.c
src/backend/postmaster/datachecksum_state.c
src/backend/postmaster/pgarch.c
src/backend/postmaster/walsummarizer.c
src/backend/replication/logical/launcher.c
src/backend/replication/logical/logicalctl.c
src/backend/replication/logical/origin.c
src/backend/replication/logical/slotsync.c
src/backend/replication/slot.c
src/backend/replication/walreceiverfuncs.c
src/backend/replication/walsender.c
src/backend/storage/ipc/ipci.c
src/backend/storage/lmgr/lock.c
src/backend/utils/activity/backend_status.c
src/backend/utils/activity/pgstat_shmem.c
src/backend/utils/activity/wait_event.c
src/backend/utils/misc/injection_point.c
src/include/access/nbtree.h
src/include/access/syncscan.h
src/include/access/twophase.h
src/include/access/xlog.h
src/include/access/xlogprefetcher.h
src/include/access/xlogrecovery.h
src/include/access/xlogwait.h
src/include/pgstat.h
src/include/postmaster/autovacuum.h
src/include/postmaster/bgworker_internals.h
src/include/postmaster/bgwriter.h
src/include/postmaster/datachecksum_state.h
src/include/postmaster/pgarch.h
src/include/postmaster/walsummarizer.h
src/include/replication/logicalctl.h
src/include/replication/logicallauncher.h
src/include/replication/origin.h
src/include/replication/slot.h
src/include/replication/slotsync.h
src/include/replication/walreceiver.h
src/include/replication/walsender.h
src/include/storage/lock.h
src/include/storage/subsystemlist.h
src/include/utils/backend_status.h
src/include/utils/injection_point.h
src/include/utils/wait_event.h
src/test/modules/injection_points/injection_points.c
src/test/modules/test_aio/test_aio.c

index 6fcfcb0e5603ec39fce95aa1e824a397a1c247db..0f9eb167bed502fceca8da948b86425177f06b69 100644 (file)
@@ -50,6 +50,7 @@
 #include "miscadmin.h"
 #include "storage/lwlock.h"
 #include "storage/shmem.h"
+#include "storage/subsystems.h"
 #include "utils/rel.h"
 
 
@@ -111,6 +112,14 @@ typedef struct ss_scan_locations_t
 #define SizeOfScanLocations(N) \
        (offsetof(ss_scan_locations_t, items) + (N) * sizeof(ss_lru_item_t))
 
+static void SyncScanShmemRequest(void *arg);
+static void SyncScanShmemInit(void *arg);
+
+const ShmemCallbacks SyncScanShmemCallbacks = {
+       .request_fn = SyncScanShmemRequest,
+       .init_fn = SyncScanShmemInit,
+};
+
 /* Pointer to struct in shared memory */
 static ss_scan_locations_t *scan_locations;
 
@@ -120,58 +129,47 @@ static BlockNumber ss_search(RelFileLocator relfilelocator,
 
 
 /*
- * SyncScanShmemSize --- report amount of shared memory space needed
+ * SyncScanShmemRequest --- register this module's shared memory
  */
-Size
-SyncScanShmemSize(void)
+static void
+SyncScanShmemRequest(void *arg)
 {
-       return SizeOfScanLocations(SYNC_SCAN_NELEM);
+       ShmemRequestStruct(.name = "Sync Scan Locations List",
+                                          .size = SizeOfScanLocations(SYNC_SCAN_NELEM),
+                                          .ptr = (void **) &scan_locations,
+               );
 }
 
 /*
  * SyncScanShmemInit --- initialize this module's shared memory
  */
-void
-SyncScanShmemInit(void)
+static void
+SyncScanShmemInit(void *arg)
 {
        int                     i;
-       bool            found;
 
-       scan_locations = (ss_scan_locations_t *)
-               ShmemInitStruct("Sync Scan Locations List",
-                                               SizeOfScanLocations(SYNC_SCAN_NELEM),
-                                               &found);
+       scan_locations->head = &scan_locations->items[0];
+       scan_locations->tail = &scan_locations->items[SYNC_SCAN_NELEM - 1];
 
-       if (!IsUnderPostmaster)
+       for (i = 0; i < SYNC_SCAN_NELEM; i++)
        {
-               /* Initialize shared memory area */
-               Assert(!found);
-
-               scan_locations->head = &scan_locations->items[0];
-               scan_locations->tail = &scan_locations->items[SYNC_SCAN_NELEM - 1];
-
-               for (i = 0; i < SYNC_SCAN_NELEM; i++)
-               {
-                       ss_lru_item_t *item = &scan_locations->items[i];
-
-                       /*
-                        * Initialize all slots with invalid values. As scans are started,
-                        * these invalid entries will fall off the LRU list and get
-                        * replaced with real entries.
-                        */
-                       item->location.relfilelocator.spcOid = InvalidOid;
-                       item->location.relfilelocator.dbOid = InvalidOid;
-                       item->location.relfilelocator.relNumber = InvalidRelFileNumber;
-                       item->location.location = InvalidBlockNumber;
-
-                       item->prev = (i > 0) ?
-                               (&scan_locations->items[i - 1]) : NULL;
-                       item->next = (i < SYNC_SCAN_NELEM - 1) ?
-                               (&scan_locations->items[i + 1]) : NULL;
-               }
+               ss_lru_item_t *item = &scan_locations->items[i];
+
+               /*
+                * Initialize all slots with invalid values. As scans are started,
+                * these invalid entries will fall off the LRU list and get replaced
+                * with real entries.
+                */
+               item->location.relfilelocator.spcOid = InvalidOid;
+               item->location.relfilelocator.dbOid = InvalidOid;
+               item->location.relfilelocator.relNumber = InvalidRelFileNumber;
+               item->location.location = InvalidBlockNumber;
+
+               item->prev = (i > 0) ?
+                       (&scan_locations->items[i - 1]) : NULL;
+               item->next = (i < SYNC_SCAN_NELEM - 1) ?
+                       (&scan_locations->items[i + 1]) : NULL;
        }
-       else
-               Assert(found);
 }
 
 /*
index 732bc750c9e0e97a44d39cf380dc8edfe5945c6e..014faa1622fb5be9acbb409a4db825abe90ba5cd 100644 (file)
@@ -25,6 +25,7 @@
 #include "lib/qunique.h"
 #include "miscadmin.h"
 #include "storage/lwlock.h"
+#include "storage/subsystems.h"
 #include "utils/datum.h"
 #include "utils/lsyscache.h"
 #include "utils/rel.h"
@@ -417,6 +418,13 @@ typedef struct BTVacInfo
 
 static BTVacInfo *btvacinfo;
 
+static void BTreeShmemRequest(void *arg);
+static void BTreeShmemInit(void *arg);
+
+const ShmemCallbacks BTreeShmemCallbacks = {
+       .request_fn = BTreeShmemRequest,
+       .init_fn = BTreeShmemInit,
+};
 
 /*
  * _bt_vacuum_cycleid --- get the active vacuum cycle ID for an index,
@@ -553,47 +561,37 @@ _bt_end_vacuum_callback(int code, Datum arg)
 }
 
 /*
- * BTreeShmemSize --- report amount of shared memory space needed
+ * BTreeShmemRequest --- register this module's shared memory
  */
-Size
-BTreeShmemSize(void)
+static void
+BTreeShmemRequest(void *arg)
 {
        Size            size;
 
        size = offsetof(BTVacInfo, vacuums);
        size = add_size(size, mul_size(MaxBackends, sizeof(BTOneVacInfo)));
-       return size;
+
+       ShmemRequestStruct(.name = "BTree Vacuum State",
+                                          .size = size,
+                                          .ptr = (void **) &btvacinfo,
+               );
 }
 
 /*
  * BTreeShmemInit --- initialize this module's shared memory
  */
-void
-BTreeShmemInit(void)
+static void
+BTreeShmemInit(void *arg)
 {
-       bool            found;
-
-       btvacinfo = (BTVacInfo *) ShmemInitStruct("BTree Vacuum State",
-                                                                                         BTreeShmemSize(),
-                                                                                         &found);
-
-       if (!IsUnderPostmaster)
-       {
-               /* Initialize shared memory area */
-               Assert(!found);
-
-               /*
-                * It doesn't really matter what the cycle counter starts at, but
-                * having it always start the same doesn't seem good.  Seed with
-                * low-order bits of time() instead.
-                */
-               btvacinfo->cycle_ctr = (BTCycleId) time(NULL);
+       /*
+        * It doesn't really matter what the cycle counter starts at, but having
+        * it always start the same doesn't seem good.  Seed with low-order bits
+        * of time() instead.
+        */
+       btvacinfo->cycle_ctr = (BTCycleId) time(NULL);
 
-               btvacinfo->num_vacuums = 0;
-               btvacinfo->max_vacuums = MaxBackends;
-       }
-       else
-               Assert(found);
+       btvacinfo->num_vacuums = 0;
+       btvacinfo->max_vacuums = MaxBackends;
 }
 
 bytea *
index ab1cbd67bac9d53762537d12c8db08eb7cad24cb..1035e8b3fc795ff8d709a064776b6f51026b3e1b 100644 (file)
 #include "storage/predicate.h"
 #include "storage/proc.h"
 #include "storage/procarray.h"
+#include "storage/subsystems.h"
 #include "utils/builtins.h"
 #include "utils/injection_point.h"
 #include "utils/memutils.h"
@@ -189,6 +190,14 @@ typedef struct TwoPhaseStateData
 
 static TwoPhaseStateData *TwoPhaseState;
 
+static void TwoPhaseShmemRequest(void *arg);
+static void TwoPhaseShmemInit(void *arg);
+
+const ShmemCallbacks TwoPhaseShmemCallbacks = {
+       .request_fn = TwoPhaseShmemRequest,
+       .init_fn = TwoPhaseShmemInit,
+};
+
 /*
  * Global transaction entry currently locked by us, if any.  Note that any
  * access to the entry pointed to by this variable must be protected by
@@ -234,10 +243,10 @@ static void RemoveTwoPhaseFile(FullTransactionId fxid, bool giveWarning);
 static void RecreateTwoPhaseFile(FullTransactionId fxid, void *content, int len);
 
 /*
- * Initialization of shared memory
+ * Register shared memory for two-phase state.
  */
-Size
-TwoPhaseShmemSize(void)
+static void
+TwoPhaseShmemRequest(void *arg)
 {
        Size            size;
 
@@ -248,46 +257,40 @@ TwoPhaseShmemSize(void)
        size = MAXALIGN(size);
        size = add_size(size, mul_size(max_prepared_xacts,
                                                                   sizeof(GlobalTransactionData)));
-
-       return size;
+       ShmemRequestStruct(.name = "Prepared Transaction Table",
+                                          .size = size,
+                                          .ptr = (void **) &TwoPhaseState,
+               );
 }
 
-void
-TwoPhaseShmemInit(void)
+/*
+ * Initialize shared memory for two-phase state.
+ */
+static void
+TwoPhaseShmemInit(void *arg)
 {
-       bool            found;
-
-       TwoPhaseState = ShmemInitStruct("Prepared Transaction Table",
-                                                                       TwoPhaseShmemSize(),
-                                                                       &found);
-       if (!IsUnderPostmaster)
-       {
-               GlobalTransaction gxacts;
-               int                     i;
+       GlobalTransaction gxacts;
+       int                     i;
 
-               Assert(!found);
-               TwoPhaseState->freeGXacts = NULL;
-               TwoPhaseState->numPrepXacts = 0;
+       TwoPhaseState->freeGXacts = NULL;
+       TwoPhaseState->numPrepXacts = 0;
 
-               /*
-                * Initialize the linked list of free GlobalTransactionData structs
-                */
-               gxacts = (GlobalTransaction)
-                       ((char *) TwoPhaseState +
-                        MAXALIGN(offsetof(TwoPhaseStateData, prepXacts) +
-                                         sizeof(GlobalTransaction) * max_prepared_xacts));
-               for (i = 0; i < max_prepared_xacts; i++)
-               {
-                       /* insert into linked list */
-                       gxacts[i].next = TwoPhaseState->freeGXacts;
-                       TwoPhaseState->freeGXacts = &gxacts[i];
+       /*
+        * Initialize the linked list of free GlobalTransactionData structs
+        */
+       gxacts = (GlobalTransaction)
+               ((char *) TwoPhaseState +
+                MAXALIGN(offsetof(TwoPhaseStateData, prepXacts) +
+                                 sizeof(GlobalTransaction) * max_prepared_xacts));
+       for (i = 0; i < max_prepared_xacts; i++)
+       {
+               /* insert into linked list */
+               gxacts[i].next = TwoPhaseState->freeGXacts;
+               TwoPhaseState->freeGXacts = &gxacts[i];
 
-                       /* associate it with a PGPROC assigned by ProcGlobalShmemInit */
-                       gxacts[i].pgprocno = GetNumberFromPGProc(&PreparedXactProcs[i]);
-               }
+               /* associate it with a PGPROC assigned by ProcGlobalShmemInit */
+               gxacts[i].pgprocno = GetNumberFromPGProc(&PreparedXactProcs[i]);
        }
-       else
-               Assert(found);
 }
 
 /*
index 9e8999bbb616f1afeda39004489bbdd0a1f82940..b82af9a85c0a0651b102deb9aa6e30c2b87d9740 100644 (file)
@@ -96,6 +96,7 @@
 #include "storage/procsignal.h"
 #include "storage/reinit.h"
 #include "storage/spin.h"
+#include "storage/subsystems.h"
 #include "storage/sync.h"
 #include "utils/guc_hooks.h"
 #include "utils/guc_tables.h"
@@ -579,8 +580,19 @@ static WALInsertLockPadded *WALInsertLocks = NULL;
 /*
  * We maintain an image of pg_control in shared memory.
  */
+static ControlFileData *LocalControlFile = NULL;
 static ControlFileData *ControlFile = NULL;
 
+static void XLOGShmemRequest(void *arg);
+static void XLOGShmemInit(void *arg);
+static void XLOGShmemAttach(void *arg);
+
+const ShmemCallbacks XLOGShmemCallbacks = {
+       .request_fn = XLOGShmemRequest,
+       .init_fn = XLOGShmemInit,
+       .attach_fn = XLOGShmemAttach,
+};
+
 /*
  * Calculate the amount of space left on the page after 'endptr'. Beware
  * multiple evaluation!
@@ -5257,7 +5269,8 @@ void
 LocalProcessControlFile(bool reset)
 {
        Assert(reset || ControlFile == NULL);
-       ControlFile = palloc_object(ControlFileData);
+       LocalControlFile = palloc_object(ControlFileData);
+       ControlFile = LocalControlFile;
        ReadControlFile();
        SetLocalDataChecksumState(ControlFile->data_checksum_version);
 }
@@ -5274,10 +5287,10 @@ GetActiveWalLevelOnStandby(void)
 }
 
 /*
- * Initialization of shared memory for XLOG
+ * Register shared memory for XLOG.
  */
-Size
-XLOGShmemSize(void)
+static void
+XLOGShmemRequest(void *arg)
 {
        Size            size;
 
@@ -5317,23 +5330,24 @@ XLOGShmemSize(void)
        /* and the buffers themselves */
        size = add_size(size, mul_size(XLOG_BLCKSZ, XLOGbuffers));
 
-       /*
-        * Note: we don't count ControlFileData, it comes out of the "slop factor"
-        * added by CreateSharedMemoryAndSemaphores.  This lets us use this
-        * routine again below to compute the actual allocation size.
-        */
-
-       return size;
+       ShmemRequestStruct(.name = "XLOG Ctl",
+                                          .size = size,
+                                          .ptr = (void **) &XLogCtl,
+               );
+       ShmemRequestStruct(.name = "Control File",
+                                          .size = sizeof(ControlFileData),
+                                          .ptr = (void **) &ControlFile,
+               );
 }
 
-void
-XLOGShmemInit(void)
+/*
+ * XLOGShmemInit - initialize the XLogCtl shared memory area.
+ */
+static void
+XLOGShmemInit(void *arg)
 {
-       bool            foundCFile,
-                               foundXLog;
        char       *allocptr;
        int                     i;
-       ControlFileData *localControlFile;
 
 #ifdef WAL_DEBUG
 
@@ -5351,36 +5365,17 @@ XLOGShmemInit(void)
        }
 #endif
 
-
-       XLogCtl = (XLogCtlData *)
-               ShmemInitStruct("XLOG Ctl", XLOGShmemSize(), &foundXLog);
-
-       localControlFile = ControlFile;
-       ControlFile = (ControlFileData *)
-               ShmemInitStruct("Control File", sizeof(ControlFileData), &foundCFile);
-
-       if (foundCFile || foundXLog)
-       {
-               /* both should be present or neither */
-               Assert(foundCFile && foundXLog);
-
-               /* Initialize local copy of WALInsertLocks */
-               WALInsertLocks = XLogCtl->Insert.WALInsertLocks;
-
-               if (localControlFile)
-                       pfree(localControlFile);
-               return;
-       }
        memset(XLogCtl, 0, sizeof(XLogCtlData));
 
        /*
         * Already have read control file locally, unless in bootstrap mode. Move
         * contents into shared memory.
         */
-       if (localControlFile)
+       if (LocalControlFile)
        {
-               memcpy(ControlFile, localControlFile, sizeof(ControlFileData));
-               pfree(localControlFile);
+               memcpy(ControlFile, LocalControlFile, sizeof(ControlFileData));
+               pfree(LocalControlFile);
+               LocalControlFile = NULL;
        }
 
        /*
@@ -5442,6 +5437,15 @@ XLOGShmemInit(void)
        pg_atomic_init_u64(&XLogCtl->unloggedLSN, InvalidXLogRecPtr);
 }
 
+/*
+ * XLOGShmemAttach - re-establish WALInsertLocks pointer after attaching.
+ */
+static void
+XLOGShmemAttach(void *arg)
+{
+       WALInsertLocks = XLogCtl->Insert.WALInsertLocks;
+}
+
 /*
  * This func must be called ONCE on system install.  It creates pg_control
  * and the initial XLOG segment.
index c235eca7c516d5b07f4de163ce1e200f7df17a39..83a3f97a57c8ccaadcef96dc00116adc1f1be296 100644 (file)
@@ -39,6 +39,7 @@
 #include "storage/fd.h"
 #include "storage/shmem.h"
 #include "storage/smgr.h"
+#include "storage/subsystems.h"
 #include "utils/fmgrprotos.h"
 #include "utils/guc_hooks.h"
 #include "utils/hsearch.h"
@@ -200,6 +201,14 @@ static LsnReadQueueNextStatus XLogPrefetcherNextBlock(uintptr_t pgsr_private,
 
 static XLogPrefetchStats *SharedStats;
 
+static void XLogPrefetchShmemRequest(void *arg);
+static void XLogPrefetchShmemInit(void *arg);
+
+const ShmemCallbacks XLogPrefetchShmemCallbacks = {
+       .request_fn = XLogPrefetchShmemRequest,
+       .init_fn = XLogPrefetchShmemInit,
+};
+
 static inline LsnReadQueue *
 lrq_alloc(uint32 max_distance,
                  uint32 max_inflight,
@@ -292,10 +301,25 @@ lrq_complete_lsn(LsnReadQueue *lrq, XLogRecPtr lsn)
                lrq_prefetch(lrq);
 }
 
-size_t
-XLogPrefetchShmemSize(void)
+static void
+XLogPrefetchShmemRequest(void *arg)
+{
+       ShmemRequestStruct(.name = "XLogPrefetchStats",
+                                          .size = sizeof(XLogPrefetchStats),
+                                          .ptr = (void **) &SharedStats,
+               );
+}
+
+static void
+XLogPrefetchShmemInit(void *arg)
 {
-       return sizeof(XLogPrefetchStats);
+       pg_atomic_init_u64(&SharedStats->reset_time, GetCurrentTimestamp());
+       pg_atomic_init_u64(&SharedStats->prefetch, 0);
+       pg_atomic_init_u64(&SharedStats->hit, 0);
+       pg_atomic_init_u64(&SharedStats->skip_init, 0);
+       pg_atomic_init_u64(&SharedStats->skip_new, 0);
+       pg_atomic_init_u64(&SharedStats->skip_fpw, 0);
+       pg_atomic_init_u64(&SharedStats->skip_rep, 0);
 }
 
 /*
@@ -313,27 +337,6 @@ XLogPrefetchResetStats(void)
        pg_atomic_write_u64(&SharedStats->skip_rep, 0);
 }
 
-void
-XLogPrefetchShmemInit(void)
-{
-       bool            found;
-
-       SharedStats = (XLogPrefetchStats *)
-               ShmemInitStruct("XLogPrefetchStats",
-                                               sizeof(XLogPrefetchStats),
-                                               &found);
-
-       if (!found)
-       {
-               pg_atomic_init_u64(&SharedStats->reset_time, GetCurrentTimestamp());
-               pg_atomic_init_u64(&SharedStats->prefetch, 0);
-               pg_atomic_init_u64(&SharedStats->hit, 0);
-               pg_atomic_init_u64(&SharedStats->skip_init, 0);
-               pg_atomic_init_u64(&SharedStats->skip_new, 0);
-               pg_atomic_init_u64(&SharedStats->skip_fpw, 0);
-               pg_atomic_init_u64(&SharedStats->skip_rep, 0);
-       }
-}
 
 /*
  * Called when any GUC is changed that affects prefetching.
index fd1c36d061d0eef2d468e09a61db7830e2a73f3a..c236e2b796928a76a0823ea4a2f65ce5de4e2303 100644 (file)
@@ -58,6 +58,7 @@
 #include "storage/pmsignal.h"
 #include "storage/procarray.h"
 #include "storage/spin.h"
+#include "storage/subsystems.h"
 #include "utils/datetime.h"
 #include "utils/fmgrprotos.h"
 #include "utils/guc_hooks.h"
@@ -307,6 +308,14 @@ static char *primary_image_masked = NULL;
 
 XLogRecoveryCtlData *XLogRecoveryCtl = NULL;
 
+static void XLogRecoveryShmemRequest(void *arg);
+static void XLogRecoveryShmemInit(void *arg);
+
+const ShmemCallbacks XLogRecoveryShmemCallbacks = {
+       .request_fn = XLogRecoveryShmemRequest,
+       .init_fn = XLogRecoveryShmemInit,
+};
+
 /*
  * abortedRecPtr is the start pointer of a broken record at end of WAL when
  * recovery completes; missingContrecPtr is the location of the first
@@ -385,28 +394,20 @@ static void SetCurrentChunkStartTime(TimestampTz xtime);
 static void SetLatestXTime(TimestampTz xtime);
 
 /*
- * Initialization of shared memory for WAL recovery
+ * Register shared memory for WAL recovery
  */
-Size
-XLogRecoveryShmemSize(void)
+static void
+XLogRecoveryShmemRequest(void *arg)
 {
-       Size            size;
-
-       /* XLogRecoveryCtl */
-       size = sizeof(XLogRecoveryCtlData);
-
-       return size;
+       ShmemRequestStruct(.name = "XLOG Recovery Ctl",
+                                          .size = sizeof(XLogRecoveryCtlData),
+                                          .ptr = (void **) &XLogRecoveryCtl,
+               );
 }
 
-void
-XLogRecoveryShmemInit(void)
+static void
+XLogRecoveryShmemInit(void *arg)
 {
-       bool            found;
-
-       XLogRecoveryCtl = (XLogRecoveryCtlData *)
-               ShmemInitStruct("XLOG Recovery Ctl", XLogRecoveryShmemSize(), &found);
-       if (found)
-               return;
        memset(XLogRecoveryCtl, 0, sizeof(XLogRecoveryCtlData));
 
        SpinLockInit(&XLogRecoveryCtl->info_lck);
index bf4630677b4274768023bc14c652233da629c61e..2e31c0d67d7626934ab86aed2755bd3a4c8accb8 100644 (file)
@@ -57,6 +57,7 @@
 #include "storage/latch.h"
 #include "storage/proc.h"
 #include "storage/shmem.h"
+#include "storage/subsystems.h"
 #include "utils/fmgrprotos.h"
 #include "utils/pg_lsn.h"
 #include "utils/snapmgr.h"
@@ -68,6 +69,14 @@ static int   waitlsn_cmp(const pairingheap_node *a, const pairingheap_node *b,
 
 struct WaitLSNState *waitLSNState = NULL;
 
+static void WaitLSNShmemRequest(void *arg);
+static void WaitLSNShmemInit(void *arg);
+
+const ShmemCallbacks WaitLSNShmemCallbacks = {
+       .request_fn = WaitLSNShmemRequest,
+       .init_fn = WaitLSNShmemInit,
+};
+
 /*
  * Wait event for each WaitLSNType, used with WaitLatch() to report
  * the wait in pg_stat_activity.
@@ -109,41 +118,34 @@ GetCurrentLSNForWaitType(WaitLSNType lsnType)
        pg_unreachable();
 }
 
-/* Report the amount of shared memory space needed for WaitLSNState. */
-Size
-WaitLSNShmemSize(void)
+/* Register the shared memory space needed for WaitLSNState. */
+static void
+WaitLSNShmemRequest(void *arg)
 {
        Size            size;
 
        size = offsetof(WaitLSNState, procInfos);
        size = add_size(size, mul_size(MaxBackends + NUM_AUXILIARY_PROCS, sizeof(WaitLSNProcInfo)));
-       return size;
+       ShmemRequestStruct(.name = "WaitLSNState",
+                                          .size = size,
+                                          .ptr = (void **) &waitLSNState,
+               );
 }
 
 /* Initialize the WaitLSNState in the shared memory. */
-void
-WaitLSNShmemInit(void)
+static void
+WaitLSNShmemInit(void *arg)
 {
-       bool            found;
-
-       waitLSNState = (WaitLSNState *) ShmemInitStruct("WaitLSNState",
-                                                                                                       WaitLSNShmemSize(),
-                                                                                                       &found);
-       if (!found)
+       /* Initialize heaps and tracking */
+       for (int i = 0; i < WAIT_LSN_TYPE_COUNT; i++)
        {
-               int                     i;
-
-               /* Initialize heaps and tracking */
-               for (i = 0; i < WAIT_LSN_TYPE_COUNT; i++)
-               {
-                       pg_atomic_init_u64(&waitLSNState->minWaitedLSN[i], PG_UINT64_MAX);
-                       pairingheap_initialize(&waitLSNState->waitersHeap[i], waitlsn_cmp, NULL);
-               }
-
-               /* Initialize process info array */
-               memset(&waitLSNState->procInfos, 0,
-                          (MaxBackends + NUM_AUXILIARY_PROCS) * sizeof(WaitLSNProcInfo));
+               pg_atomic_init_u64(&waitLSNState->minWaitedLSN[i], PG_UINT64_MAX);
+               pairingheap_initialize(&waitLSNState->waitersHeap[i], waitlsn_cmp, NULL);
        }
+
+       /* Initialize process info array */
+       memset(&waitLSNState->procInfos, 0,
+                  (MaxBackends + NUM_AUXILIARY_PROCS) * sizeof(WaitLSNProcInfo));
 }
 
 /*
index 8400e6722cc4cfcea9b2145fd4ac3be26642b683..250c43b85e5bf122f7342a13e864ae4cf1a48d18 100644 (file)
@@ -98,6 +98,7 @@
 #include "storage/proc.h"
 #include "storage/procsignal.h"
 #include "storage/smgr.h"
+#include "storage/subsystems.h"
 #include "tcop/tcopprot.h"
 #include "utils/fmgroids.h"
 #include "utils/fmgrprotos.h"
@@ -309,6 +310,14 @@ typedef struct
 
 static AutoVacuumShmemStruct *AutoVacuumShmem;
 
+static void AutoVacuumShmemRequest(void *arg);
+static void AutoVacuumShmemInit(void *arg);
+
+const ShmemCallbacks AutoVacuumShmemCallbacks = {
+       .request_fn = AutoVacuumShmemRequest,
+       .init_fn = AutoVacuumShmemInit,
+};
+
 /*
  * the database list (of avl_dbase elements) in the launcher, and the context
  * that contains it
@@ -3545,11 +3554,11 @@ autovac_init(void)
 }
 
 /*
- * AutoVacuumShmemSize
- *             Compute space needed for autovacuum-related shared memory
+ * AutoVacuumShmemRequest
+ *             Register shared memory space needed for autovacuum
  */
-Size
-AutoVacuumShmemSize(void)
+static void
+AutoVacuumShmemRequest(void *arg)
 {
        Size            size;
 
@@ -3560,53 +3569,41 @@ AutoVacuumShmemSize(void)
        size = MAXALIGN(size);
        size = add_size(size, mul_size(autovacuum_worker_slots,
                                                                   sizeof(WorkerInfoData)));
-       return size;
+
+       ShmemRequestStruct(.name = "AutoVacuum Data",
+                                          .size = size,
+                                          .ptr = (void **) &AutoVacuumShmem,
+               );
 }
 
 /*
  * AutoVacuumShmemInit
- *             Allocate and initialize autovacuum-related shared memory
+ *             Initialize autovacuum-related shared memory
  */
-void
-AutoVacuumShmemInit(void)
+static void
+AutoVacuumShmemInit(void *arg)
 {
-       bool            found;
-
-       AutoVacuumShmem = (AutoVacuumShmemStruct *)
-               ShmemInitStruct("AutoVacuum Data",
-                                               AutoVacuumShmemSize(),
-                                               &found);
-
-       if (!IsUnderPostmaster)
-       {
-               WorkerInfo      worker;
-               int                     i;
+       WorkerInfo      worker;
 
-               Assert(!found);
-
-               AutoVacuumShmem->av_launcherpid = 0;
-               dclist_init(&AutoVacuumShmem->av_freeWorkers);
-               dlist_init(&AutoVacuumShmem->av_runningWorkers);
-               AutoVacuumShmem->av_startingWorker = NULL;
-               memset(AutoVacuumShmem->av_workItems, 0,
-                          sizeof(AutoVacuumWorkItem) * NUM_WORKITEMS);
-
-               worker = (WorkerInfo) ((char *) AutoVacuumShmem +
-                                                          MAXALIGN(sizeof(AutoVacuumShmemStruct)));
-
-               /* initialize the WorkerInfo free list */
-               for (i = 0; i < autovacuum_worker_slots; i++)
-               {
-                       dclist_push_head(&AutoVacuumShmem->av_freeWorkers,
-                                                        &worker[i].wi_links);
-                       pg_atomic_init_flag(&worker[i].wi_dobalance);
-               }
+       AutoVacuumShmem->av_launcherpid = 0;
+       dclist_init(&AutoVacuumShmem->av_freeWorkers);
+       dlist_init(&AutoVacuumShmem->av_runningWorkers);
+       AutoVacuumShmem->av_startingWorker = NULL;
+       memset(AutoVacuumShmem->av_workItems, 0,
+                  sizeof(AutoVacuumWorkItem) * NUM_WORKITEMS);
 
-               pg_atomic_init_u32(&AutoVacuumShmem->av_nworkersForBalance, 0);
+       worker = (WorkerInfo) ((char *) AutoVacuumShmem +
+                                                  MAXALIGN(sizeof(AutoVacuumShmemStruct)));
 
+       /* initialize the WorkerInfo free list */
+       for (int i = 0; i < autovacuum_worker_slots; i++)
+       {
+               dclist_push_head(&AutoVacuumShmem->av_freeWorkers,
+                                                &worker[i].wi_links);
+               pg_atomic_init_flag(&worker[i].wi_dobalance);
        }
-       else
-               Assert(found);
+
+       pg_atomic_init_u32(&AutoVacuumShmem->av_nworkersForBalance, 0);
 }
 
 /*
index 536aff7ca0593142075d32ac615b56bd7c8ba40d..0992b9b63536bd881e215c803ecc259bbff68fc4 100644 (file)
@@ -30,6 +30,7 @@
 #include "storage/procarray.h"
 #include "storage/procsignal.h"
 #include "storage/shmem.h"
+#include "storage/subsystems.h"
 #include "tcop/tcopprot.h"
 #include "utils/ascii.h"
 #include "utils/memutils.h"
@@ -110,6 +111,14 @@ struct BackgroundWorkerHandle
 
 static BackgroundWorkerArray *BackgroundWorkerData;
 
+static void BackgroundWorkerShmemRequest(void *arg);
+static void BackgroundWorkerShmemInit(void *arg);
+
+const ShmemCallbacks BackgroundWorkerShmemCallbacks = {
+       .request_fn = BackgroundWorkerShmemRequest,
+       .init_fn = BackgroundWorkerShmemInit,
+};
+
 /*
  * List of internal background worker entry points.  We need this for
  * reasons explained in LookupBackgroundWorkerFunction(), below.
@@ -160,10 +169,10 @@ static bgworker_main_type LookupBackgroundWorkerFunction(const char *libraryname
 
 
 /*
- * Calculate shared memory needed.
+ * Register shared memory needed for background workers.
  */
-Size
-BackgroundWorkerShmemSize(void)
+static void
+BackgroundWorkerShmemRequest(void *arg)
 {
        Size            size;
 
@@ -171,66 +180,58 @@ BackgroundWorkerShmemSize(void)
        size = offsetof(BackgroundWorkerArray, slot);
        size = add_size(size, mul_size(max_worker_processes,
                                                                   sizeof(BackgroundWorkerSlot)));
-
-       return size;
+       ShmemRequestStruct(.name = "Background Worker Data",
+                                          .size = size,
+                                          .ptr = (void **) &BackgroundWorkerData,
+               );
 }
 
 /*
- * Initialize shared memory.
+ * Initialize shared memory for background workers.
  */
-void
-BackgroundWorkerShmemInit(void)
+static void
+BackgroundWorkerShmemInit(void *arg)
 {
-       bool            found;
-
-       BackgroundWorkerData = ShmemInitStruct("Background Worker Data",
-                                                                                  BackgroundWorkerShmemSize(),
-                                                                                  &found);
-       if (!IsUnderPostmaster)
-       {
-               dlist_iter      iter;
-               int                     slotno = 0;
+       dlist_iter      iter;
+       int                     slotno = 0;
 
-               BackgroundWorkerData->total_slots = max_worker_processes;
-               BackgroundWorkerData->parallel_register_count = 0;
-               BackgroundWorkerData->parallel_terminate_count = 0;
+       BackgroundWorkerData->total_slots = max_worker_processes;
+       BackgroundWorkerData->parallel_register_count = 0;
+       BackgroundWorkerData->parallel_terminate_count = 0;
 
-               /*
-                * Copy contents of worker list into shared memory.  Record the shared
-                * memory slot assigned to each worker.  This ensures a 1-to-1
-                * correspondence between the postmaster's private list and the array
-                * in shared memory.
-                */
-               dlist_foreach(iter, &BackgroundWorkerList)
-               {
-                       BackgroundWorkerSlot *slot = &BackgroundWorkerData->slot[slotno];
-                       RegisteredBgWorker *rw;
+       /*
+        * Copy contents of worker list into shared memory.  Record the shared
+        * memory slot assigned to each worker.  This ensures a 1-to-1
+        * correspondence between the postmaster's private list and the array in
+        * shared memory.
+        */
+       dlist_foreach(iter, &BackgroundWorkerList)
+       {
+               BackgroundWorkerSlot *slot = &BackgroundWorkerData->slot[slotno];
+               RegisteredBgWorker *rw;
 
-                       rw = dlist_container(RegisteredBgWorker, rw_lnode, iter.cur);
-                       Assert(slotno < max_worker_processes);
-                       slot->in_use = true;
-                       slot->terminate = false;
-                       slot->pid = InvalidPid;
-                       slot->generation = 0;
-                       rw->rw_shmem_slot = slotno;
-                       rw->rw_worker.bgw_notify_pid = 0;       /* might be reinit after crash */
-                       memcpy(&slot->worker, &rw->rw_worker, sizeof(BackgroundWorker));
-                       ++slotno;
-               }
+               rw = dlist_container(RegisteredBgWorker, rw_lnode, iter.cur);
+               Assert(slotno < max_worker_processes);
+               slot->in_use = true;
+               slot->terminate = false;
+               slot->pid = InvalidPid;
+               slot->generation = 0;
+               rw->rw_shmem_slot = slotno;
+               rw->rw_worker.bgw_notify_pid = 0;       /* might be reinit after crash */
+               memcpy(&slot->worker, &rw->rw_worker, sizeof(BackgroundWorker));
+               ++slotno;
+       }
 
-               /*
-                * Mark any remaining slots as not in use.
-                */
-               while (slotno < max_worker_processes)
-               {
-                       BackgroundWorkerSlot *slot = &BackgroundWorkerData->slot[slotno];
+       /*
+        * Mark any remaining slots as not in use.
+        */
+       while (slotno < max_worker_processes)
+       {
+               BackgroundWorkerSlot *slot = &BackgroundWorkerData->slot[slotno];
 
-                       slot->in_use = false;
-                       ++slotno;
-               }
+               slot->in_use = false;
+               ++slotno;
        }
-       else
-               Assert(found);
 }
 
 /*
index 3c982c6ffaca8cb5809b553e427f041049562179..6b424ee610fe456ab2460f11677a9513501b3375 100644 (file)
@@ -63,6 +63,7 @@
 #include "storage/shmem.h"
 #include "storage/smgr.h"
 #include "storage/spin.h"
+#include "storage/subsystems.h"
 #include "utils/acl.h"
 #include "utils/guc.h"
 #include "utils/memutils.h"
@@ -143,6 +144,14 @@ typedef struct
 
 static CheckpointerShmemStruct *CheckpointerShmem;
 
+static void CheckpointerShmemRequest(void *arg);
+static void CheckpointerShmemInit(void *arg);
+
+const ShmemCallbacks CheckpointerShmemCallbacks = {
+       .request_fn = CheckpointerShmemRequest,
+       .init_fn = CheckpointerShmemInit,
+};
+
 /* interval for calling AbsorbSyncRequests in CheckpointWriteDelay */
 #define WRITES_PER_ABSORB              1000
 
@@ -950,11 +959,11 @@ ReqShutdownXLOG(SIGNAL_ARGS)
  */
 
 /*
- * CheckpointerShmemSize
- *             Compute space needed for checkpointer-related shared memory
+ * CheckpointerShmemRequest
+ *             Register shared memory space needed for checkpointer
  */
-Size
-CheckpointerShmemSize(void)
+static void
+CheckpointerShmemRequest(void *arg)
 {
        Size            size;
 
@@ -967,39 +976,24 @@ CheckpointerShmemSize(void)
        size = add_size(size, mul_size(Min(NBuffers,
                                                                           MAX_CHECKPOINT_REQUESTS),
                                                                   sizeof(CheckpointerRequest)));
-
-       return size;
+       ShmemRequestStruct(.name = "Checkpointer Data",
+                                          .size = size,
+                                          .ptr = (void **) &CheckpointerShmem,
+               );
 }
 
 /*
  * CheckpointerShmemInit
- *             Allocate and initialize checkpointer-related shared memory
+ *             Initialize checkpointer-related shared memory
  */
-void
-CheckpointerShmemInit(void)
+static void
+CheckpointerShmemInit(void *arg)
 {
-       Size            size = CheckpointerShmemSize();
-       bool            found;
-
-       CheckpointerShmem = (CheckpointerShmemStruct *)
-               ShmemInitStruct("Checkpointer Data",
-                                               size,
-                                               &found);
-
-       if (!found)
-       {
-               /*
-                * First time through, so initialize.  Note that we zero the whole
-                * requests array; this is so that CompactCheckpointerRequestQueue can
-                * assume that any pad bytes in the request structs are zeroes.
-                */
-               MemSet(CheckpointerShmem, 0, size);
-               SpinLockInit(&CheckpointerShmem->ckpt_lck);
-               CheckpointerShmem->max_requests = Min(NBuffers, MAX_CHECKPOINT_REQUESTS);
-               CheckpointerShmem->head = CheckpointerShmem->tail = 0;
-               ConditionVariableInit(&CheckpointerShmem->start_cv);
-               ConditionVariableInit(&CheckpointerShmem->done_cv);
-       }
+       SpinLockInit(&CheckpointerShmem->ckpt_lck);
+       CheckpointerShmem->max_requests = Min(NBuffers, MAX_CHECKPOINT_REQUESTS);
+       CheckpointerShmem->head = CheckpointerShmem->tail = 0;
+       ConditionVariableInit(&CheckpointerShmem->start_cv);
+       ConditionVariableInit(&CheckpointerShmem->done_cv);
 }
 
 /*
index 76004bcedc6acf2296d607e3c752fdfd558b3121..eb7b01d0993677643c3b857f6701a4f2902c3d84 100644 (file)
 #include "storage/lwlock.h"
 #include "storage/procarray.h"
 #include "storage/smgr.h"
+#include "storage/subsystems.h"
 #include "tcop/tcopprot.h"
 #include "utils/builtins.h"
 #include "utils/fmgroids.h"
@@ -346,6 +347,7 @@ static volatile sig_atomic_t launcher_running = false;
 static DataChecksumsWorkerOperation operation;
 
 /* Prototypes */
+static void DataChecksumsShmemRequest(void *arg);
 static bool DatabaseExists(Oid dboid);
 static List *BuildDatabaseList(void);
 static List *BuildRelationList(bool temp_relations, bool include_shared);
@@ -356,6 +358,10 @@ static bool ProcessSingleRelationFork(Relation reln, ForkNumber forkNum, BufferA
 static void launcher_cancel_handler(SIGNAL_ARGS);
 static void WaitForAllTransactionsToFinish(void);
 
+const ShmemCallbacks DataChecksumsShmemCallbacks = {
+       .request_fn = DataChecksumsShmemRequest,
+};
+
 /*****************************************************************************
  * Functionality for manipulating the data checksum state in the cluster
  */
@@ -1236,35 +1242,16 @@ ProcessAllDatabases(void)
 }
 
 /*
- * DataChecksumStateSize
- *             Compute required space for datachecksumsworker-related shared memory
- */
-Size
-DataChecksumsShmemSize(void)
-{
-       Size            size;
-
-       size = sizeof(DataChecksumsStateStruct);
-       size = MAXALIGN(size);
-
-       return size;
-}
-
-/*
- * DataChecksumStateInit
- *             Allocate and initialize datachecksumsworker-related shared memory
+ * DataChecksumShmemRequest
+ *             Request datachecksumsworker-related shared memory
  */
-void
-DataChecksumsShmemInit(void)
+static void
+DataChecksumsShmemRequest(void *arg)
 {
-       bool            found;
-
-       DataChecksumState = (DataChecksumsStateStruct *)
-               ShmemInitStruct("DataChecksumsWorker Data",
-                                               DataChecksumsShmemSize(),
-                                               &found);
-       if (!found)
-               MemSet(DataChecksumState, 0, DataChecksumsShmemSize());
+       ShmemRequestStruct(.name = "DataChecksumsWorker Data",
+                                          .size = sizeof(DataChecksumsStateStruct),
+                                          .ptr = (void **) &DataChecksumState,
+               );
 }
 
 /*
index fa4bdfe9ab9ff40fe1adac473d3aaa3a343ea866..0a1a1149d78cdf264d50585a68f69682d56bcb39 100644 (file)
@@ -48,6 +48,7 @@
 #include "storage/proc.h"
 #include "storage/procsignal.h"
 #include "storage/shmem.h"
+#include "storage/subsystems.h"
 #include "utils/guc.h"
 #include "utils/memutils.h"
 #include "utils/ps_status.h"
@@ -154,33 +155,31 @@ static int        ready_file_comparator(Datum a, Datum b, void *arg);
 static void LoadArchiveLibrary(void);
 static void pgarch_call_module_shutdown_cb(int code, Datum arg);
 
-/* Report shared memory space needed by PgArchShmemInit */
-Size
-PgArchShmemSize(void)
-{
-       Size            size = 0;
+static void PgArchShmemRequest(void *arg);
+static void PgArchShmemInit(void *arg);
 
-       size = add_size(size, sizeof(PgArchData));
+const ShmemCallbacks PgArchShmemCallbacks = {
+       .request_fn = PgArchShmemRequest,
+       .init_fn = PgArchShmemInit,
+};
 
-       return size;
+/* Register shared memory space needed by the archiver */
+static void
+PgArchShmemRequest(void *arg)
+{
+       ShmemRequestStruct(.name = "Archiver Data",
+                                          .size = sizeof(PgArchData),
+                                          .ptr = (void **) &PgArch,
+               );
 }
 
-/* Allocate and initialize archiver-related shared memory */
-void
-PgArchShmemInit(void)
+/* Initialize archiver-related shared memory */
+static void
+PgArchShmemInit(void *arg)
 {
-       bool            found;
-
-       PgArch = (PgArchData *)
-               ShmemInitStruct("Archiver Data", PgArchShmemSize(), &found);
-
-       if (!found)
-       {
-               /* First time through, so initialize */
-               MemSet(PgArch, 0, PgArchShmemSize());
-               PgArch->pgprocno = INVALID_PROC_NUMBER;
-               pg_atomic_init_u32(&PgArch->force_dir_scan, 0);
-       }
+       MemSet(PgArch, 0, sizeof(PgArchData));
+       PgArch->pgprocno = INVALID_PROC_NUMBER;
+       pg_atomic_init_u32(&PgArch->force_dir_scan, 0);
 }
 
 /*
index a37b3018abf5cb23e8e7da6c7007857213a33929..20960f5b633f48836ec44efaba94effacd116ac9 100644 (file)
@@ -47,6 +47,7 @@
 #include "storage/proc.h"
 #include "storage/procsignal.h"
 #include "storage/shmem.h"
+#include "storage/subsystems.h"
 #include "utils/guc.h"
 #include "utils/memutils.h"
 #include "utils/wait_event.h"
@@ -109,6 +110,14 @@ typedef struct
 /* Pointer to shared memory state. */
 static WalSummarizerData *WalSummarizerCtl;
 
+static void WalSummarizerShmemRequest(void *arg);
+static void WalSummarizerShmemInit(void *arg);
+
+const ShmemCallbacks WalSummarizerShmemCallbacks = {
+       .request_fn = WalSummarizerShmemRequest,
+       .init_fn = WalSummarizerShmemInit,
+};
+
 /*
  * When we reach end of WAL and need to read more, we sleep for a number of
  * milliseconds that is an integer multiple of MS_PER_SLEEP_QUANTUM. This is
@@ -168,43 +177,34 @@ static void summarizer_wait_for_wal(void);
 static void MaybeRemoveOldWalSummaries(void);
 
 /*
- * Amount of shared memory required for this module.
+ * Register shared memory space needed by this module.
  */
-Size
-WalSummarizerShmemSize(void)
+static void
+WalSummarizerShmemRequest(void *arg)
 {
-       return sizeof(WalSummarizerData);
+       ShmemRequestStruct(.name = "Wal Summarizer Ctl",
+                                          .size = sizeof(WalSummarizerData),
+                                          .ptr = (void **) &WalSummarizerCtl,
+               );
 }
 
 /*
- * Create or attach to shared memory segment for this module.
+ * Initialize shared memory for this module.
  */
-void
-WalSummarizerShmemInit(void)
+static void
+WalSummarizerShmemInit(void *arg)
 {
-       bool            found;
-
-       WalSummarizerCtl = (WalSummarizerData *)
-               ShmemInitStruct("Wal Summarizer Ctl", WalSummarizerShmemSize(),
-                                               &found);
-
-       if (!found)
-       {
-               /*
-                * First time through, so initialize.
-                *
-                * We're just filling in dummy values here -- the real initialization
-                * will happen when GetOldestUnsummarizedLSN() is called for the first
-                * time.
-                */
-               WalSummarizerCtl->initialized = false;
-               WalSummarizerCtl->summarized_tli = 0;
-               WalSummarizerCtl->summarized_lsn = InvalidXLogRecPtr;
-               WalSummarizerCtl->lsn_is_exact = false;
-               WalSummarizerCtl->summarizer_pgprocno = INVALID_PROC_NUMBER;
-               WalSummarizerCtl->pending_lsn = InvalidXLogRecPtr;
-               ConditionVariableInit(&WalSummarizerCtl->summary_file_cv);
-       }
+       /*
+        * We're just filling in dummy values here -- the real initialization will
+        * happen when GetOldestUnsummarizedLSN() is called for the first time.
+        */
+       WalSummarizerCtl->initialized = false;
+       WalSummarizerCtl->summarized_tli = 0;
+       WalSummarizerCtl->summarized_lsn = InvalidXLogRecPtr;
+       WalSummarizerCtl->lsn_is_exact = false;
+       WalSummarizerCtl->summarizer_pgprocno = INVALID_PROC_NUMBER;
+       WalSummarizerCtl->pending_lsn = InvalidXLogRecPtr;
+       ConditionVariableInit(&WalSummarizerCtl->summary_file_cv);
 }
 
 /*
index 099641985503b22b774a755dd1c392a3d75b7fcd..9e75a3e04ee1416319d77c5d67a400a4938d7844 100644 (file)
@@ -38,6 +38,7 @@
 #include "storage/ipc.h"
 #include "storage/proc.h"
 #include "storage/procarray.h"
+#include "storage/subsystems.h"
 #include "tcop/tcopprot.h"
 #include "utils/builtins.h"
 #include "utils/memutils.h"
@@ -71,6 +72,14 @@ typedef struct LogicalRepCtxStruct
 
 static LogicalRepCtxStruct *LogicalRepCtx;
 
+static void ApplyLauncherShmemRequest(void *arg);
+static void ApplyLauncherShmemInit(void *arg);
+
+const ShmemCallbacks ApplyLauncherShmemCallbacks = {
+       .request_fn = ApplyLauncherShmemRequest,
+       .init_fn = ApplyLauncherShmemInit,
+};
+
 /* an entry in the last-start-times shared hash table */
 typedef struct LauncherLastStartTimesEntry
 {
@@ -972,11 +981,11 @@ logicalrep_pa_worker_count(Oid subid)
 }
 
 /*
- * ApplyLauncherShmemSize
- *             Compute space needed for replication launcher shared memory
+ * ApplyLauncherShmemRequest
+ *             Register shared memory space needed for replication launcher
  */
-Size
-ApplyLauncherShmemSize(void)
+static void
+ApplyLauncherShmemRequest(void *arg)
 {
        Size            size;
 
@@ -987,7 +996,10 @@ ApplyLauncherShmemSize(void)
        size = MAXALIGN(size);
        size = add_size(size, mul_size(max_logical_replication_workers,
                                                                   sizeof(LogicalRepWorker)));
-       return size;
+       ShmemRequestStruct(.name = "Logical Replication Launcher Data",
+                                          .size = size,
+                                          .ptr = (void **) &LogicalRepCtx,
+               );
 }
 
 /*
@@ -1028,35 +1040,23 @@ ApplyLauncherRegister(void)
 
 /*
  * ApplyLauncherShmemInit
- *             Allocate and initialize replication launcher shared memory
+ *             Initialize replication launcher shared memory
  */
-void
-ApplyLauncherShmemInit(void)
+static void
+ApplyLauncherShmemInit(void *arg)
 {
-       bool            found;
+       int                     slot;
 
-       LogicalRepCtx = (LogicalRepCtxStruct *)
-               ShmemInitStruct("Logical Replication Launcher Data",
-                                               ApplyLauncherShmemSize(),
-                                               &found);
+       LogicalRepCtx->last_start_dsa = DSA_HANDLE_INVALID;
+       LogicalRepCtx->last_start_dsh = DSHASH_HANDLE_INVALID;
 
-       if (!found)
+       /* Initialize memory and spin locks for each worker slot. */
+       for (slot = 0; slot < max_logical_replication_workers; slot++)
        {
-               int                     slot;
-
-               memset(LogicalRepCtx, 0, ApplyLauncherShmemSize());
-
-               LogicalRepCtx->last_start_dsa = DSA_HANDLE_INVALID;
-               LogicalRepCtx->last_start_dsh = DSHASH_HANDLE_INVALID;
+               LogicalRepWorker *worker = &LogicalRepCtx->workers[slot];
 
-               /* Initialize memory and spin locks for each worker slot. */
-               for (slot = 0; slot < max_logical_replication_workers; slot++)
-               {
-                       LogicalRepWorker *worker = &LogicalRepCtx->workers[slot];
-
-                       memset(worker, 0, sizeof(LogicalRepWorker));
-                       SpinLockInit(&worker->relmutex);
-               }
+               memset(worker, 0, sizeof(LogicalRepWorker));
+               SpinLockInit(&worker->relmutex);
        }
 }
 
index 4e2929512010a3376ef089cfa7707d2634d939ec..72f68ec58ef7e332e76d5baad4dca858d9bfa55a 100644 (file)
@@ -72,6 +72,7 @@
 #include "storage/proc.h"
 #include "storage/procarray.h"
 #include "storage/procsignal.h"
+#include "storage/subsystems.h"
 #include "utils/injection_point.h"
 
 /*
@@ -98,6 +99,12 @@ typedef struct LogicalDecodingCtlData
 
 static LogicalDecodingCtlData *LogicalDecodingCtl = NULL;
 
+static void LogicalDecodingCtlShmemRequest(void *arg);
+
+const ShmemCallbacks LogicalDecodingCtlShmemCallbacks = {
+       .request_fn = LogicalDecodingCtlShmemRequest,
+};
+
 /*
  * A process-local cache of LogicalDecodingCtl->xlog_logical_info. This is
  * initialized at process startup, and updated when processing the process
@@ -120,23 +127,13 @@ static void update_xlog_logical_info(void);
 static void abort_logical_decoding_activation(int code, Datum arg);
 static void write_logical_decoding_status_update_record(bool status);
 
-Size
-LogicalDecodingCtlShmemSize(void)
-{
-       return sizeof(LogicalDecodingCtlData);
-}
-
-void
-LogicalDecodingCtlShmemInit(void)
+static void
+LogicalDecodingCtlShmemRequest(void *arg)
 {
-       bool            found;
-
-       LogicalDecodingCtl = ShmemInitStruct("Logical decoding control",
-                                                                                LogicalDecodingCtlShmemSize(),
-                                                                                &found);
-
-       if (!found)
-               MemSet(LogicalDecodingCtl, 0, LogicalDecodingCtlShmemSize());
+       ShmemRequestStruct(.name = "Logical decoding control",
+                                          .size = sizeof(LogicalDecodingCtlData),
+                                          .ptr = (void **) &LogicalDecodingCtl,
+               );
 }
 
 /*
index 661d68ad653526ac634edceb8e7e7733ec02e19e..372d77c475ed5065621b848a6705c4c6db2eb682 100644 (file)
@@ -88,6 +88,7 @@
 #include "storage/fd.h"
 #include "storage/ipc.h"
 #include "storage/lmgr.h"
+#include "storage/subsystems.h"
 #include "utils/builtins.h"
 #include "utils/fmgroids.h"
 #include "utils/guc.h"
@@ -176,6 +177,16 @@ ReplOriginXactState replorigin_xact_state = {
  */
 static ReplicationState *replication_states;
 
+static void ReplicationOriginShmemRequest(void *arg);
+static void ReplicationOriginShmemInit(void *arg);
+static void ReplicationOriginShmemAttach(void *arg);
+
+const ShmemCallbacks ReplicationOriginShmemCallbacks = {
+       .request_fn = ReplicationOriginShmemRequest,
+       .init_fn = ReplicationOriginShmemInit,
+       .attach_fn = ReplicationOriginShmemAttach,
+};
+
 /*
  * Actual shared memory block (replication_states[] is now part of this).
  */
@@ -539,50 +550,48 @@ replorigin_by_oid(ReplOriginId roident, bool missing_ok, char **roname)
  * ---------------------------------------------------------------------------
  */
 
-Size
-ReplicationOriginShmemSize(void)
+static void
+ReplicationOriginShmemRequest(void *arg)
 {
        Size            size = 0;
 
        if (max_active_replication_origins == 0)
-               return size;
+               return;
 
        size = add_size(size, offsetof(ReplicationStateCtl, states));
-
        size = add_size(size,
                                        mul_size(max_active_replication_origins, sizeof(ReplicationState)));
-       return size;
+       ShmemRequestStruct(.name = "ReplicationOriginState",
+                                          .size = size,
+                                          .ptr = (void **) &replication_states_ctl,
+               );
 }
 
-void
-ReplicationOriginShmemInit(void)
+static void
+ReplicationOriginShmemInit(void *arg)
 {
-       bool            found;
-
        if (max_active_replication_origins == 0)
                return;
 
-       replication_states_ctl = (ReplicationStateCtl *)
-               ShmemInitStruct("ReplicationOriginState",
-                                               ReplicationOriginShmemSize(),
-                                               &found);
        replication_states = replication_states_ctl->states;
 
-       if (!found)
-       {
-               int                     i;
+       replication_states_ctl->tranche_id = LWTRANCHE_REPLICATION_ORIGIN_STATE;
 
-               MemSet(replication_states_ctl, 0, ReplicationOriginShmemSize());
+       for (int i = 0; i < max_active_replication_origins; i++)
+       {
+               LWLockInitialize(&replication_states[i].lock,
+                                                replication_states_ctl->tranche_id);
+               ConditionVariableInit(&replication_states[i].origin_cv);
+       }
+}
 
-               replication_states_ctl->tranche_id = LWTRANCHE_REPLICATION_ORIGIN_STATE;
+static void
+ReplicationOriginShmemAttach(void *arg)
+{
+       if (max_active_replication_origins == 0)
+               return;
 
-               for (i = 0; i < max_active_replication_origins; i++)
-               {
-                       LWLockInitialize(&replication_states[i].lock,
-                                                        replication_states_ctl->tranche_id);
-                       ConditionVariableInit(&replication_states[i].origin_cv);
-               }
-       }
+       replication_states = replication_states_ctl->states;
 }
 
 /* ---------------------------------------------------------------------------
index e75db69e3f647bb186d2c9eb3411de9e363ecaeb..d615ff8a81c89a814879504afe76e0d83e607071 100644 (file)
@@ -73,6 +73,7 @@
 #include "storage/lmgr.h"
 #include "storage/proc.h"
 #include "storage/procarray.h"
+#include "storage/subsystems.h"
 #include "tcop/tcopprot.h"
 #include "utils/builtins.h"
 #include "utils/memutils.h"
@@ -118,6 +119,14 @@ typedef struct SlotSyncCtxStruct
 
 static SlotSyncCtxStruct *SlotSyncCtx = NULL;
 
+static void SlotSyncShmemRequest(void *arg);
+static void SlotSyncShmemInit(void *arg);
+
+const ShmemCallbacks SlotSyncShmemCallbacks = {
+       .request_fn = SlotSyncShmemRequest,
+       .init_fn = SlotSyncShmemInit,
+};
+
 /* GUC variable */
 bool           sync_replication_slots = false;
 
@@ -1828,32 +1837,26 @@ IsSyncingReplicationSlots(void)
 }
 
 /*
- * Amount of shared memory required for slot synchronization.
+ * Register shared memory space needed for slot synchronization.
  */
-Size
-SlotSyncShmemSize(void)
+static void
+SlotSyncShmemRequest(void *arg)
 {
-       return sizeof(SlotSyncCtxStruct);
+       ShmemRequestStruct(.name = "Slot Sync Data",
+                                          .size = sizeof(SlotSyncCtxStruct),
+                                          .ptr = (void **) &SlotSyncCtx,
+               );
 }
 
 /*
- * Allocate and initialize the shared memory of slot synchronization.
+ * Initialize shared memory for slot synchronization.
  */
-void
-SlotSyncShmemInit(void)
+static void
+SlotSyncShmemInit(void *arg)
 {
-       Size            size = SlotSyncShmemSize();
-       bool            found;
-
-       SlotSyncCtx = (SlotSyncCtxStruct *)
-               ShmemInitStruct("Slot Sync Data", size, &found);
-
-       if (!found)
-       {
-               memset(SlotSyncCtx, 0, size);
-               SlotSyncCtx->pid = InvalidPid;
-               SpinLockInit(&SlotSyncCtx->mutex);
-       }
+       memset(SlotSyncCtx, 0, sizeof(SlotSyncCtxStruct));
+       SlotSyncCtx->pid = InvalidPid;
+       SpinLockInit(&SlotSyncCtx->mutex);
 }
 
 /*
index a9092fc2382ee61861c8084cadb5c1c2ab6df672..21a213a0ebf1457eaa8d878f0f183b151e72f7be 100644 (file)
@@ -55,6 +55,7 @@
 #include "storage/ipc.h"
 #include "storage/proc.h"
 #include "storage/procarray.h"
+#include "storage/subsystems.h"
 #include "utils/builtins.h"
 #include "utils/guc_hooks.h"
 #include "utils/injection_point.h"
@@ -145,6 +146,14 @@ StaticAssertDecl(lengthof(SlotInvalidationCauses) == (RS_INVAL_MAX_CAUSES + 1),
 /* Control array for replication slot management */
 ReplicationSlotCtlData *ReplicationSlotCtl = NULL;
 
+static void ReplicationSlotsShmemRequest(void *arg);
+static void ReplicationSlotsShmemInit(void *arg);
+
+const ShmemCallbacks ReplicationSlotsShmemCallbacks = {
+       .request_fn = ReplicationSlotsShmemRequest,
+       .init_fn = ReplicationSlotsShmemInit,
+};
+
 /* My backend's replication slot in the shared memory array */
 ReplicationSlot *MyReplicationSlot = NULL;
 
@@ -183,56 +192,41 @@ static void CreateSlotOnDisk(ReplicationSlot *slot);
 static void SaveSlotToPath(ReplicationSlot *slot, const char *dir, int elevel);
 
 /*
- * Report shared-memory space needed by ReplicationSlotsShmemInit.
+ * Register shared memory space needed for replication slots.
  */
-Size
-ReplicationSlotsShmemSize(void)
+static void
+ReplicationSlotsShmemRequest(void *arg)
 {
-       Size            size = 0;
+       Size            size;
 
        if (max_replication_slots == 0)
-               return size;
+               return;
 
        size = offsetof(ReplicationSlotCtlData, replication_slots);
        size = add_size(size,
                                        mul_size(max_replication_slots, sizeof(ReplicationSlot)));
-
-       return size;
+       ShmemRequestStruct(.name = "ReplicationSlot Ctl",
+                                          .size = size,
+                                          .ptr = (void **) &ReplicationSlotCtl,
+               );
 }
 
 /*
- * Allocate and initialize shared memory for replication slots.
+ * Initialize shared memory for replication slots.
  */
-void
-ReplicationSlotsShmemInit(void)
+static void
+ReplicationSlotsShmemInit(void *arg)
 {
-       bool            found;
-
-       if (max_replication_slots == 0)
-               return;
-
-       ReplicationSlotCtl = (ReplicationSlotCtlData *)
-               ShmemInitStruct("ReplicationSlot Ctl", ReplicationSlotsShmemSize(),
-                                               &found);
-
-       if (!found)
+       for (int i = 0; i < max_replication_slots; i++)
        {
-               int                     i;
+               ReplicationSlot *slot = &ReplicationSlotCtl->replication_slots[i];
 
-               /* First time through, so initialize */
-               MemSet(ReplicationSlotCtl, 0, ReplicationSlotsShmemSize());
-
-               for (i = 0; i < max_replication_slots; i++)
-               {
-                       ReplicationSlot *slot = &ReplicationSlotCtl->replication_slots[i];
-
-                       /* everything else is zeroed by the memset above */
-                       slot->active_proc = INVALID_PROC_NUMBER;
-                       SpinLockInit(&slot->mutex);
-                       LWLockInitialize(&slot->io_in_progress_lock,
-                                                        LWTRANCHE_REPLICATION_SLOT_IO);
-                       ConditionVariableInit(&slot->active_cv);
-               }
+               /* everything else is zeroed by the memset above */
+               slot->active_proc = INVALID_PROC_NUMBER;
+               SpinLockInit(&slot->mutex);
+               LWLockInitialize(&slot->io_in_progress_lock,
+                                                LWTRANCHE_REPLICATION_SLOT_IO);
+               ConditionVariableInit(&slot->active_cv);
        }
 }
 
index 45b9d4f09f280288a3268332eb97a0f20dfc6eb5..4e03e721872c708af5ca7005892bd1d98a9c44a5 100644 (file)
 #include "storage/pmsignal.h"
 #include "storage/proc.h"
 #include "storage/shmem.h"
+#include "storage/subsystems.h"
 #include "utils/timestamp.h"
 #include "utils/wait_event.h"
 
 WalRcvData *WalRcv = NULL;
 
+static void WalRcvShmemRequest(void *arg);
+static void WalRcvShmemInit(void *arg);
+
+const ShmemCallbacks WalRcvShmemCallbacks = {
+       .request_fn = WalRcvShmemRequest,
+       .init_fn = WalRcvShmemInit,
+};
+
 /*
  * How long to wait for walreceiver to start up after requesting
  * postmaster to launch it. In seconds.
  */
 #define WALRCV_STARTUP_TIMEOUT 10
 
-/* Report shared memory space needed by WalRcvShmemInit */
-Size
-WalRcvShmemSize(void)
+/* Register shared memory space needed by walreceiver */
+static void
+WalRcvShmemRequest(void *arg)
 {
-       Size            size = 0;
-
-       size = add_size(size, sizeof(WalRcvData));
-
-       return size;
+       ShmemRequestStruct(.name = "Wal Receiver Ctl",
+                                          .size = sizeof(WalRcvData),
+                                          .ptr = (void **) &WalRcv,
+               );
 }
 
-/* Allocate and initialize walreceiver-related shared memory */
-void
-WalRcvShmemInit(void)
+/* Initialize walreceiver-related shared memory */
+static void
+WalRcvShmemInit(void *arg)
 {
-       bool            found;
-
-       WalRcv = (WalRcvData *)
-               ShmemInitStruct("Wal Receiver Ctl", WalRcvShmemSize(), &found);
-
-       if (!found)
-       {
-               /* First time through, so initialize */
-               MemSet(WalRcv, 0, WalRcvShmemSize());
-               WalRcv->walRcvState = WALRCV_STOPPED;
-               ConditionVariableInit(&WalRcv->walRcvStoppedCV);
-               SpinLockInit(&WalRcv->mutex);
-               pg_atomic_init_u64(&WalRcv->writtenUpto, 0);
-               WalRcv->procno = INVALID_PROC_NUMBER;
-       }
+       MemSet(WalRcv, 0, sizeof(WalRcvData));
+       WalRcv->walRcvState = WALRCV_STOPPED;
+       ConditionVariableInit(&WalRcv->walRcvStoppedCV);
+       SpinLockInit(&WalRcv->mutex);
+       pg_atomic_init_u64(&WalRcv->writtenUpto, 0);
+       WalRcv->procno = INVALID_PROC_NUMBER;
 }
 
 /* Is walreceiver running (or starting up)? */
index 2bb3f34dc6d1113ba46cdc2d442a868a4c99ee3a..ec39942bfc10cb8ca8a4a148ab4b31e6bb2dbc7d 100644 (file)
@@ -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"
 /* Array of WalSnds in shared memory */
 WalSndCtlData *WalSndCtl = NULL;
 
+static void WalSndShmemRequest(void *arg);
+static void WalSndShmemInit(void *arg);
+
+const ShmemCallbacks WalSndShmemCallbacks = {
+       .request_fn = WalSndShmemRequest,
+       .init_fn = WalSndShmemInit,
+};
+
 /* My slot in the shared memory array */
 WalSnd    *MyWalSnd = NULL;
 
@@ -3765,47 +3774,37 @@ WalSndSignals(void)
        pqsignal(SIGCHLD, SIG_DFL);
 }
 
-/* Report shared-memory space needed by WalSndShmemInit */
-Size
-WalSndShmemSize(void)
+/* Register shared-memory space needed by walsender */
+static void
+WalSndShmemRequest(void *arg)
 {
-       Size            size = 0;
+       Size            size;
 
        size = offsetof(WalSndCtlData, walsnds);
        size = add_size(size, mul_size(max_wal_senders, sizeof(WalSnd)));
-
-       return size;
+       ShmemRequestStruct(.name = "Wal Sender Ctl",
+                                          .size = size,
+                                          .ptr = (void **) &WalSndCtl,
+               );
 }
 
-/* Allocate and initialize walsender-related shared memory */
-void
-WalSndShmemInit(void)
+/* Initialize walsender-related shared memory */
+static void
+WalSndShmemInit(void *arg)
 {
-       bool            found;
-       int                     i;
+       for (int i = 0; i < NUM_SYNC_REP_WAIT_MODE; i++)
+               dlist_init(&(WalSndCtl->SyncRepQueue[i]));
 
-       WalSndCtl = (WalSndCtlData *)
-               ShmemInitStruct("Wal Sender Ctl", WalSndShmemSize(), &found);
-
-       if (!found)
+       for (int i = 0; i < max_wal_senders; i++)
        {
-               /* First time through, so initialize */
-               MemSet(WalSndCtl, 0, WalSndShmemSize());
-
-               for (i = 0; i < NUM_SYNC_REP_WAIT_MODE; i++)
-                       dlist_init(&(WalSndCtl->SyncRepQueue[i]));
-
-               for (i = 0; i < max_wal_senders; i++)
-               {
-                       WalSnd     *walsnd = &WalSndCtl->walsnds[i];
-
-                       SpinLockInit(&walsnd->mutex);
-               }
+               WalSnd     *walsnd = &WalSndCtl->walsnds[i];
 
-               ConditionVariableInit(&WalSndCtl->wal_flush_cv);
-               ConditionVariableInit(&WalSndCtl->wal_replay_cv);
-               ConditionVariableInit(&WalSndCtl->wal_confirm_rcv_cv);
+               SpinLockInit(&walsnd->mutex);
        }
+
+       ConditionVariableInit(&WalSndCtl->wal_flush_cv);
+       ConditionVariableInit(&WalSndCtl->wal_replay_cv);
+       ConditionVariableInit(&WalSndCtl->wal_confirm_rcv_cv);
 }
 
 /*
index f64c1d59fa3fe7d1bb475133cc711c3d600da8d9..bf6b81e621b0d2fe2746cbd5025967ec07c0008c 100644 (file)
  */
 #include "postgres.h"
 
-#include "access/clog.h"
-#include "access/commit_ts.h"
-#include "access/multixact.h"
-#include "access/nbtree.h"
-#include "access/subtrans.h"
-#include "access/syncscan.h"
-#include "access/twophase.h"
-#include "access/xlogprefetcher.h"
-#include "access/xlogrecovery.h"
-#include "access/xlogwait.h"
-#include "commands/async.h"
 #include "miscadmin.h"
 #include "pgstat.h"
-#include "postmaster/autovacuum.h"
-#include "postmaster/bgworker_internals.h"
-#include "postmaster/bgwriter.h"
-#include "postmaster/datachecksum_state.h"
-#include "postmaster/walsummarizer.h"
-#include "replication/logicallauncher.h"
-#include "replication/origin.h"
-#include "replication/slot.h"
-#include "replication/slotsync.h"
-#include "replication/walreceiver.h"
-#include "replication/walsender.h"
-#include "storage/aio_subsys.h"
 #include "storage/dsm.h"
 #include "storage/ipc.h"
+#include "storage/lock.h"
 #include "storage/pg_shmem.h"
-#include "storage/predicate.h"
 #include "storage/proc.h"
 #include "storage/shmem_internal.h"
 #include "storage/subsystems.h"
 #include "utils/guc.h"
-#include "utils/injection_point.h"
-#include "utils/wait_event.h"
 
 /* GUCs */
 int                    shared_memory_type = DEFAULT_SHARED_MEMORY_TYPE;
@@ -57,8 +32,6 @@ shmem_startup_hook_type shmem_startup_hook = NULL;
 
 static Size total_addin_request = 0;
 
-static void CreateOrAttachShmemStructs(void);
-
 /*
  * RequestAddinShmemSpace
  *             Request that extra shmem space be allocated for use by
@@ -97,33 +70,6 @@ CalculateShmemSize(void)
        size = 100000;
        size = add_size(size, ShmemGetRequestedSize());
 
-       /* legacy subsystems */
-       size = add_size(size, LockManagerShmemSize());
-       size = add_size(size, XLogPrefetchShmemSize());
-       size = add_size(size, XLOGShmemSize());
-       size = add_size(size, XLogRecoveryShmemSize());
-       size = add_size(size, TwoPhaseShmemSize());
-       size = add_size(size, BackgroundWorkerShmemSize());
-       size = add_size(size, BackendStatusShmemSize());
-       size = add_size(size, CheckpointerShmemSize());
-       size = add_size(size, AutoVacuumShmemSize());
-       size = add_size(size, ReplicationSlotsShmemSize());
-       size = add_size(size, ReplicationOriginShmemSize());
-       size = add_size(size, WalSndShmemSize());
-       size = add_size(size, WalRcvShmemSize());
-       size = add_size(size, WalSummarizerShmemSize());
-       size = add_size(size, PgArchShmemSize());
-       size = add_size(size, ApplyLauncherShmemSize());
-       size = add_size(size, BTreeShmemSize());
-       size = add_size(size, SyncScanShmemSize());
-       size = add_size(size, StatsShmemSize());
-       size = add_size(size, WaitEventCustomShmemSize());
-       size = add_size(size, InjectionPointShmemSize());
-       size = add_size(size, SlotSyncShmemSize());
-       size = add_size(size, WaitLSNShmemSize());
-       size = add_size(size, LogicalDecodingCtlShmemSize());
-       size = add_size(size, DataChecksumsShmemSize());
-
        /* include additional requested shmem from preload libraries */
        size = add_size(size, total_addin_request);
 
@@ -157,7 +103,6 @@ AttachSharedMemoryStructs(void)
 
        /* Establish pointers to all shared memory areas in this backend */
        ShmemAttachRequested();
-       CreateOrAttachShmemStructs();
 
        /*
         * Now give loadable modules a chance to set up their shmem allocations
@@ -204,9 +149,6 @@ CreateSharedMemoryAndSemaphores(void)
        /* Initialize all shmem areas */
        ShmemInitRequested();
 
-       /* Initialize legacy subsystems */
-       CreateOrAttachShmemStructs();
-
        /* Initialize dynamic shared memory facilities. */
        dsm_postmaster_startup(shim);
 
@@ -237,70 +179,6 @@ RegisterBuiltinShmemCallbacks(void)
 #undef PG_SHMEM_SUBSYSTEM
 }
 
-/*
- * Initialize various subsystems, setting up their data structures in
- * shared memory.
- *
- * This is called by the postmaster or by a standalone backend.
- * It is also called by a backend forked from the postmaster in the
- * EXEC_BACKEND case.  In the latter case, the shared memory segment
- * already exists and has been physically attached to, but we have to
- * initialize pointers in local memory that reference the shared structures,
- * because we didn't inherit the correct pointer values from the postmaster
- * as we do in the fork() scenario.  The easiest way to do that is to run
- * through the same code as before.  (Note that the called routines mostly
- * check IsUnderPostmaster, rather than EXEC_BACKEND, to detect this case.
- * This is a bit code-wasteful and could be cleaned up.)
- */
-static void
-CreateOrAttachShmemStructs(void)
-{
-       /*
-        * Set up xlog, clog, and buffers
-        */
-       XLOGShmemInit();
-       XLogPrefetchShmemInit();
-       XLogRecoveryShmemInit();
-
-       /*
-        * Set up lock manager
-        */
-       LockManagerShmemInit();
-
-       /*
-        * Set up process table
-        */
-       BackendStatusShmemInit();
-       TwoPhaseShmemInit();
-       BackgroundWorkerShmemInit();
-
-       /*
-        * Set up interprocess signaling mechanisms
-        */
-       CheckpointerShmemInit();
-       AutoVacuumShmemInit();
-       ReplicationSlotsShmemInit();
-       ReplicationOriginShmemInit();
-       WalSndShmemInit();
-       WalRcvShmemInit();
-       WalSummarizerShmemInit();
-       PgArchShmemInit();
-       ApplyLauncherShmemInit();
-       SlotSyncShmemInit();
-       DataChecksumsShmemInit();
-
-       /*
-        * Set up other modules that need some shared memory space
-        */
-       BTreeShmemInit();
-       SyncScanShmemInit();
-       StatsShmemInit();
-       WaitEventCustomShmemInit();
-       InjectionPointShmemInit();
-       WaitLSNShmemInit();
-       LogicalDecodingCtlShmemInit();
-}
-
 /*
  * InitializeShmemGUCs
  *
index 798c453ab38d70bb699bde36f0342189dc7adc70..c221fe9688981454765785e494e153d8b29e79e1 100644 (file)
 #include "storage/lmgr.h"
 #include "storage/proc.h"
 #include "storage/procarray.h"
+#include "storage/shmem.h"
 #include "storage/spin.h"
 #include "storage/standby.h"
+#include "storage/subsystems.h"
 #include "utils/memutils.h"
 #include "utils/ps_status.h"
 #include "utils/resowner.h"
@@ -312,6 +314,14 @@ typedef struct
 
 static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
 
+static void LockManagerShmemRequest(void *arg);
+static void LockManagerShmemInit(void *arg);
+
+const ShmemCallbacks LockManagerShmemCallbacks = {
+       .request_fn = LockManagerShmemRequest,
+       .init_fn = LockManagerShmemInit,
+};
+
 
 /*
  * Pointers to hash tables containing lock state
@@ -432,21 +442,15 @@ static void GetSingleProcBlockerStatusData(PGPROC *blocked_proc,
 
 
 /*
- * Initialize the lock manager's shmem data structures.
+ * Register the lock manager's shmem data structures.
  *
- * This is called from CreateSharedMemoryAndSemaphores(), which see for more
- * comments.  In the normal postmaster case, the shared hash tables are
- * created here, and backends inherit pointers to them via fork().  In the
- * EXEC_BACKEND case, each backend re-executes this code to obtain pointers to
- * the already existing shared hash tables.  In either case, each backend must
- * also call InitLockManagerAccess() to create the locallock hash table.
+ * In addition to this, each backend must also call InitLockManagerAccess() to
+ * create the locallock hash table.
  */
-void
-LockManagerShmemInit(void)
+static void
+LockManagerShmemRequest(void *arg)
 {
-       HASHCTL         info;
        int64           max_table_size;
-       bool            found;
 
        /*
         * Compute sizes for lock hashtables.  Note that these calculations must
@@ -455,45 +459,41 @@ LockManagerShmemInit(void)
        max_table_size = NLOCKENTS();
 
        /*
-        * Allocate hash table for LOCK structs.  This stores per-locked-object
+        * Hash table for LOCK structs.  This stores per-locked-object
         * information.
         */
-       info.keysize = sizeof(LOCKTAG);
-       info.entrysize = sizeof(LOCK);
-       info.num_partitions = NUM_LOCK_PARTITIONS;
-
-       LockMethodLockHash = ShmemInitHash("LOCK hash",
-                                                                          max_table_size,
-                                                                          &info,
-                                                                          HASH_ELEM | HASH_BLOBS |
-                                                                          HASH_PARTITION | HASH_FIXED_SIZE);
+       ShmemRequestHash(.name = "LOCK hash",
+                                        .nelems = max_table_size,
+                                        .ptr = &LockMethodLockHash,
+                                        .hash_info.keysize = sizeof(LOCKTAG),
+                                        .hash_info.entrysize = sizeof(LOCK),
+                                        .hash_info.num_partitions = NUM_LOCK_PARTITIONS,
+                                        .hash_flags = HASH_ELEM | HASH_BLOBS | HASH_PARTITION,
+               );
 
        /* Assume an average of 2 holders per lock */
        max_table_size *= 2;
 
-       /*
-        * Allocate hash table for PROCLOCK structs.  This stores
-        * per-lock-per-holder information.
-        */
-       info.keysize = sizeof(PROCLOCKTAG);
-       info.entrysize = sizeof(PROCLOCK);
-       info.hash = proclock_hash;
-       info.num_partitions = NUM_LOCK_PARTITIONS;
-
-       LockMethodProcLockHash = ShmemInitHash("PROCLOCK hash",
-                                                                                  max_table_size,
-                                                                                  &info,
-                                                                                  HASH_ELEM | HASH_FUNCTION |
-                                                                                  HASH_FIXED_SIZE | HASH_PARTITION);
+       ShmemRequestHash(.name = "PROCLOCK hash",
+                                        .nelems = max_table_size,
+                                        .ptr = &LockMethodProcLockHash,
+                                        .hash_info.keysize = sizeof(PROCLOCKTAG),
+                                        .hash_info.entrysize = sizeof(PROCLOCK),
+                                        .hash_info.hash = proclock_hash,
+                                        .hash_info.num_partitions = NUM_LOCK_PARTITIONS,
+                                        .hash_flags = HASH_ELEM | HASH_FUNCTION | HASH_PARTITION,
+               );
+
+       ShmemRequestStruct(.name = "Fast Path Strong Relation Lock Data",
+                                          .size = sizeof(FastPathStrongRelationLockData),
+                                          .ptr = (void **) (void *) &FastPathStrongRelationLocks,
+               );
+}
 
-       /*
-        * Allocate fast-path structures.
-        */
-       FastPathStrongRelationLocks =
-               ShmemInitStruct("Fast Path Strong Relation Lock Data",
-                                               sizeof(FastPathStrongRelationLockData), &found);
-       if (!found)
-               SpinLockInit(&FastPathStrongRelationLocks->mutex);
+static void
+LockManagerShmemInit(void *arg)
+{
+       SpinLockInit(&FastPathStrongRelationLocks->mutex);
 }
 
 /*
@@ -3758,29 +3758,6 @@ PostPrepare_Locks(FullTransactionId fxid)
 }
 
 
-/*
- * Estimate shared-memory space used for lock tables
- */
-Size
-LockManagerShmemSize(void)
-{
-       Size            size = 0;
-       long            max_table_size;
-
-       /* lock hash table */
-       max_table_size = NLOCKENTS();
-       size = add_size(size, hash_estimate_size(max_table_size, sizeof(LOCK)));
-
-       /* proclock hash table */
-       max_table_size *= 2;
-       size = add_size(size, hash_estimate_size(max_table_size, sizeof(PROCLOCK)));
-
-       /* fast-path structures */
-       size = add_size(size, sizeof(FastPathStrongRelationLockData));
-
-       return size;
-}
-
 /*
  * GetLockStatusData - Return a summary of the lock manager's internal
  * status, for use in a user-level reporting function.
index cd08712946911c88db5c70bf909c005f0696205f..d685fc5cd87c02bc9456a3e601d291308c930097 100644 (file)
@@ -19,6 +19,8 @@
 #include "storage/ipc.h"
 #include "storage/proc.h"              /* for MyProc */
 #include "storage/procarray.h"
+#include "storage/shmem.h"
+#include "storage/subsystems.h"
 #include "utils/ascii.h"
 #include "utils/guc.h"                 /* for application_name */
 #include "utils/memutils.h"
@@ -73,133 +75,97 @@ static void pgstat_beshutdown_hook(int code, Datum arg);
 static void pgstat_read_current_status(void);
 static void pgstat_setup_backend_status_context(void);
 
+static void BackendStatusShmemRequest(void *arg);
+static void BackendStatusShmemInit(void *arg);
+static void BackendStatusShmemAttach(void *arg);
+
+const ShmemCallbacks BackendStatusShmemCallbacks = {
+       .request_fn = BackendStatusShmemRequest,
+       .init_fn = BackendStatusShmemInit,
+       .attach_fn = BackendStatusShmemAttach,
+};
 
 /*
- * Report shared-memory space needed by BackendStatusShmemInit.
+ * Register shared memory needs for backend status reporting.
  */
-Size
-BackendStatusShmemSize(void)
+static void
+BackendStatusShmemRequest(void *arg)
 {
-       Size            size;
-
-       /* BackendStatusArray: */
-       size = mul_size(sizeof(PgBackendStatus), NumBackendStatSlots);
-       /* BackendAppnameBuffer: */
-       size = add_size(size,
-                                       mul_size(NAMEDATALEN, NumBackendStatSlots));
-       /* BackendClientHostnameBuffer: */
-       size = add_size(size,
-                                       mul_size(NAMEDATALEN, NumBackendStatSlots));
-       /* BackendActivityBuffer: */
-       size = add_size(size,
-                                       mul_size(pgstat_track_activity_query_size, NumBackendStatSlots));
+       ShmemRequestStruct(.name = "Backend Status Array",
+                                          .size = mul_size(sizeof(PgBackendStatus), NumBackendStatSlots),
+                                          .ptr = (void **) &BackendStatusArray,
+               );
+
+       ShmemRequestStruct(.name = "Backend Application Name Buffer",
+                                          .size = mul_size(NAMEDATALEN, NumBackendStatSlots),
+                                          .ptr = (void **) &BackendAppnameBuffer,
+               );
+
+       ShmemRequestStruct(.name = "Backend Client Host Name Buffer",
+                                          .size = mul_size(NAMEDATALEN, NumBackendStatSlots),
+                                          .ptr = (void **) &BackendClientHostnameBuffer,
+               );
+
+       BackendActivityBufferSize = mul_size(pgstat_track_activity_query_size,
+                                                                                NumBackendStatSlots);
+       ShmemRequestStruct(.name = "Backend Activity Buffer",
+                                          .size = BackendActivityBufferSize,
+                                          .ptr = (void **) &BackendActivityBuffer
+               );
+
 #ifdef USE_SSL
-       /* BackendSslStatusBuffer: */
-       size = add_size(size,
-                                       mul_size(sizeof(PgBackendSSLStatus), NumBackendStatSlots));
+       ShmemRequestStruct(.name = "Backend SSL Status Buffer",
+                                          .size = mul_size(sizeof(PgBackendSSLStatus), NumBackendStatSlots),
+                                          .ptr = (void **) &BackendSslStatusBuffer,
+               );
 #endif
+
 #ifdef ENABLE_GSS
-       /* BackendGssStatusBuffer: */
-       size = add_size(size,
-                                       mul_size(sizeof(PgBackendGSSStatus), NumBackendStatSlots));
+       ShmemRequestStruct(.name = "Backend GSS Status Buffer",
+                                          .size = mul_size(sizeof(PgBackendGSSStatus), NumBackendStatSlots),
+                                          .ptr = (void **) &BackendGssStatusBuffer,
+               );
 #endif
-       return size;
 }
 
 /*
  * Initialize the shared status array and several string buffers
  * during postmaster startup.
  */
-void
-BackendStatusShmemInit(void)
+static void
+BackendStatusShmemInit(void *arg)
 {
-       Size            size;
-       bool            found;
        int                     i;
        char       *buffer;
 
-       /* Create or attach to the shared array */
-       size = mul_size(sizeof(PgBackendStatus), NumBackendStatSlots);
-       BackendStatusArray = (PgBackendStatus *)
-               ShmemInitStruct("Backend Status Array", size, &found);
-
-       if (!found)
+       /* Initialize st_appname pointers. */
+       buffer = BackendAppnameBuffer;
+       for (i = 0; i < NumBackendStatSlots; i++)
        {
-               /*
-                * We're the first - initialize.
-                */
-               MemSet(BackendStatusArray, 0, size);
-       }
-
-       /* Create or attach to the shared appname buffer */
-       size = mul_size(NAMEDATALEN, NumBackendStatSlots);
-       BackendAppnameBuffer = (char *)
-               ShmemInitStruct("Backend Application Name Buffer", size, &found);
-
-       if (!found)
-       {
-               MemSet(BackendAppnameBuffer, 0, size);
-
-               /* Initialize st_appname pointers. */
-               buffer = BackendAppnameBuffer;
-               for (i = 0; i < NumBackendStatSlots; i++)
-               {
-                       BackendStatusArray[i].st_appname = buffer;
-                       buffer += NAMEDATALEN;
-               }
+               BackendStatusArray[i].st_appname = buffer;
+               buffer += NAMEDATALEN;
        }
 
-       /* Create or attach to the shared client hostname buffer */
-       size = mul_size(NAMEDATALEN, NumBackendStatSlots);
-       BackendClientHostnameBuffer = (char *)
-               ShmemInitStruct("Backend Client Host Name Buffer", size, &found);
-
-       if (!found)
+       /* Initialize st_clienthostname pointers. */
+       buffer = BackendClientHostnameBuffer;
+       for (i = 0; i < NumBackendStatSlots; i++)
        {
-               MemSet(BackendClientHostnameBuffer, 0, size);
-
-               /* Initialize st_clienthostname pointers. */
-               buffer = BackendClientHostnameBuffer;
-               for (i = 0; i < NumBackendStatSlots; i++)
-               {
-                       BackendStatusArray[i].st_clienthostname = buffer;
-                       buffer += NAMEDATALEN;
-               }
+               BackendStatusArray[i].st_clienthostname = buffer;
+               buffer += NAMEDATALEN;
        }
 
-       /* Create or attach to the shared activity buffer */
-       BackendActivityBufferSize = mul_size(pgstat_track_activity_query_size,
-                                                                                NumBackendStatSlots);
-       BackendActivityBuffer = (char *)
-               ShmemInitStruct("Backend Activity Buffer",
-                                               BackendActivityBufferSize,
-                                               &found);
-
-       if (!found)
+       /* Initialize st_activity pointers. */
+       buffer = BackendActivityBuffer;
+       for (i = 0; i < NumBackendStatSlots; i++)
        {
-               MemSet(BackendActivityBuffer, 0, BackendActivityBufferSize);
-
-               /* Initialize st_activity pointers. */
-               buffer = BackendActivityBuffer;
-               for (i = 0; i < NumBackendStatSlots; i++)
-               {
-                       BackendStatusArray[i].st_activity_raw = buffer;
-                       buffer += pgstat_track_activity_query_size;
-               }
+               BackendStatusArray[i].st_activity_raw = buffer;
+               buffer += pgstat_track_activity_query_size;
        }
 
 #ifdef USE_SSL
-       /* Create or attach to the shared SSL status buffer */
-       size = mul_size(sizeof(PgBackendSSLStatus), NumBackendStatSlots);
-       BackendSslStatusBuffer = (PgBackendSSLStatus *)
-               ShmemInitStruct("Backend SSL Status Buffer", size, &found);
-
-       if (!found)
        {
                PgBackendSSLStatus *ptr;
 
-               MemSet(BackendSslStatusBuffer, 0, size);
-
                /* Initialize st_sslstatus pointers. */
                ptr = BackendSslStatusBuffer;
                for (i = 0; i < NumBackendStatSlots; i++)
@@ -211,17 +177,9 @@ BackendStatusShmemInit(void)
 #endif
 
 #ifdef ENABLE_GSS
-       /* Create or attach to the shared GSSAPI status buffer */
-       size = mul_size(sizeof(PgBackendGSSStatus), NumBackendStatSlots);
-       BackendGssStatusBuffer = (PgBackendGSSStatus *)
-               ShmemInitStruct("Backend GSS Status Buffer", size, &found);
-
-       if (!found)
        {
                PgBackendGSSStatus *ptr;
 
-               MemSet(BackendGssStatusBuffer, 0, size);
-
                /* Initialize st_gssstatus pointers. */
                ptr = BackendGssStatusBuffer;
                for (i = 0; i < NumBackendStatSlots; i++)
@@ -233,6 +191,13 @@ BackendStatusShmemInit(void)
 #endif
 }
 
+static void
+BackendStatusShmemAttach(void *arg)
+{
+       BackendActivityBufferSize = mul_size(pgstat_track_activity_query_size,
+                                                                                NumBackendStatSlots);
+}
+
 /*
  * Initialize pgstats backend activity state, and set up our on-proc-exit
  * hook.  Called from InitPostgres and AuxiliaryProcessMain.  MyProcNumber must
index 33fbdca960974e65e44b8bc2335e729885639240..955faf5ebc7d2dd9a98a74fecd70652f71fc8470 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "pgstat.h"
 #include "storage/shmem.h"
+#include "storage/subsystems.h"
 #include "utils/memutils.h"
 #include "utils/pgstat_internal.h"
 
@@ -57,6 +58,13 @@ static void pgstat_release_matching_entry_refs(bool discard_pending, ReleaseMatc
 
 static void pgstat_setup_memcxt(void);
 
+static void StatsShmemRequest(void *arg);
+static void StatsShmemInit(void *arg);
+
+const ShmemCallbacks StatsShmemCallbacks = {
+       .request_fn = StatsShmemRequest,
+       .init_fn = StatsShmemInit,
+};
 
 /* parameter for the shared hash */
 static const dshash_parameters dsh_params = {
@@ -123,7 +131,7 @@ pgstat_dsa_init_size(void)
 /*
  * Compute shared memory space needed for cumulative statistics
  */
-Size
+static Size
 StatsShmemSize(void)
 {
        Size            sz;
@@ -149,102 +157,98 @@ StatsShmemSize(void)
        return sz;
 }
 
+/*
+ * Register shared memory area for cumulative statistics
+ */
+static void
+StatsShmemRequest(void *arg)
+{
+       ShmemRequestStruct(.name = "Shared Memory Stats",
+                                          .size = StatsShmemSize(),
+                                          .ptr = (void **) &pgStatLocal.shmem,
+               );
+}
+
 /*
  * Initialize cumulative statistics system during startup
  */
-void
-StatsShmemInit(void)
+static void
+StatsShmemInit(void *arg)
 {
-       bool            found;
-       Size            sz;
+       dsa_area   *dsa;
+       dshash_table *dsh;
+       PgStat_ShmemControl *ctl = pgStatLocal.shmem;
+       char       *p = (char *) ctl;
 
-       sz = StatsShmemSize();
-       pgStatLocal.shmem = (PgStat_ShmemControl *)
-               ShmemInitStruct("Shared Memory Stats", sz, &found);
+       /* the allocation of pgStatLocal.shmem itself */
+       p += MAXALIGN(sizeof(PgStat_ShmemControl));
 
-       if (!IsUnderPostmaster)
-       {
-               dsa_area   *dsa;
-               dshash_table *dsh;
-               PgStat_ShmemControl *ctl = pgStatLocal.shmem;
-               char       *p = (char *) ctl;
+       /*
+        * Create a small dsa allocation in plain shared memory. This is required
+        * because postmaster cannot use dsm segments. It also provides a small
+        * efficiency win.
+        */
+       ctl->raw_dsa_area = p;
+       dsa = dsa_create_in_place(ctl->raw_dsa_area,
+                                                         pgstat_dsa_init_size(),
+                                                         LWTRANCHE_PGSTATS_DSA, NULL);
+       dsa_pin(dsa);
 
-               Assert(!found);
+       /*
+        * To ensure dshash is created in "plain" shared memory, temporarily limit
+        * size of dsa to the initial size of the dsa.
+        */
+       dsa_set_size_limit(dsa, pgstat_dsa_init_size());
 
-               /* the allocation of pgStatLocal.shmem itself */
-               p += MAXALIGN(sizeof(PgStat_ShmemControl));
+       /*
+        * With the limit in place, create the dshash table. XXX: It'd be nice if
+        * there were dshash_create_in_place().
+        */
+       dsh = dshash_create(dsa, &dsh_params, NULL);
+       ctl->hash_handle = dshash_get_hash_table_handle(dsh);
 
-               /*
-                * Create a small dsa allocation in plain shared memory. This is
-                * required because postmaster cannot use dsm segments. It also
-                * provides a small efficiency win.
-                */
-               ctl->raw_dsa_area = p;
-               dsa = dsa_create_in_place(ctl->raw_dsa_area,
-                                                                 pgstat_dsa_init_size(),
-                                                                 LWTRANCHE_PGSTATS_DSA, NULL);
-               dsa_pin(dsa);
+       /* lift limit set above */
+       dsa_set_size_limit(dsa, -1);
 
-               /*
-                * To ensure dshash is created in "plain" shared memory, temporarily
-                * limit size of dsa to the initial size of the dsa.
-                */
-               dsa_set_size_limit(dsa, pgstat_dsa_init_size());
+       /*
+        * Postmaster will never access these again, thus free the local
+        * dsa/dshash references.
+        */
+       dshash_detach(dsh);
+       dsa_detach(dsa);
 
-               /*
-                * With the limit in place, create the dshash table. XXX: It'd be nice
-                * if there were dshash_create_in_place().
-                */
-               dsh = dshash_create(dsa, &dsh_params, NULL);
-               ctl->hash_handle = dshash_get_hash_table_handle(dsh);
+       pg_atomic_init_u64(&ctl->gc_request_count, 1);
 
-               /* lift limit set above */
-               dsa_set_size_limit(dsa, -1);
+       /* Do the per-kind initialization */
+       for (PgStat_Kind kind = PGSTAT_KIND_MIN; kind <= PGSTAT_KIND_MAX; kind++)
+       {
+               const PgStat_KindInfo *kind_info = pgstat_get_kind_info(kind);
+               char       *ptr;
 
-               /*
-                * Postmaster will never access these again, thus free the local
-                * dsa/dshash references.
-                */
-               dshash_detach(dsh);
-               dsa_detach(dsa);
+               if (!kind_info)
+                       continue;
 
-               pg_atomic_init_u64(&ctl->gc_request_count, 1);
+               /* initialize entry count tracking */
+               if (kind_info->track_entry_count)
+                       pg_atomic_init_u64(&ctl->entry_counts[kind - 1], 0);
 
-               /* Do the per-kind initialization */
-               for (PgStat_Kind kind = PGSTAT_KIND_MIN; kind <= PGSTAT_KIND_MAX; kind++)
+               /* initialize fixed-numbered stats */
+               if (kind_info->fixed_amount)
                {
-                       const PgStat_KindInfo *kind_info = pgstat_get_kind_info(kind);
-                       char       *ptr;
-
-                       if (!kind_info)
-                               continue;
-
-                       /* initialize entry count tracking */
-                       if (kind_info->track_entry_count)
-                               pg_atomic_init_u64(&ctl->entry_counts[kind - 1], 0);
-
-                       /* initialize fixed-numbered stats */
-                       if (kind_info->fixed_amount)
+                       if (pgstat_is_kind_builtin(kind))
+                               ptr = ((char *) ctl) + kind_info->shared_ctl_off;
+                       else
                        {
-                               if (pgstat_is_kind_builtin(kind))
-                                       ptr = ((char *) ctl) + kind_info->shared_ctl_off;
-                               else
-                               {
-                                       int                     idx = kind - PGSTAT_KIND_CUSTOM_MIN;
-
-                                       Assert(kind_info->shared_size != 0);
-                                       ctl->custom_data[idx] = ShmemAlloc(kind_info->shared_size);
-                                       ptr = ctl->custom_data[idx];
-                               }
-
-                               kind_info->init_shmem_cb(ptr);
+                               int                     idx = kind - PGSTAT_KIND_CUSTOM_MIN;
+
+                               Assert(kind_info->shared_size != 0);
+                               ctl->custom_data[idx] = ShmemAlloc(kind_info->shared_size);
+                               ptr = ctl->custom_data[idx];
                        }
+
+                       kind_info->init_shmem_cb(ptr);
                }
        }
-       else
-       {
-               Assert(found);
-       }
 }
 
 void
index 2b76967776c9084e108d67fabea20b14ec115d2e..95635c7f56ce726ca34d91025307b0558e1bd943 100644 (file)
@@ -25,6 +25,7 @@
 #include "storage/lmgr.h"
 #include "storage/lwlock.h"
 #include "storage/shmem.h"
+#include "storage/subsystems.h"
 #include "storage/spin.h"
 #include "utils/wait_event.h"
 
@@ -95,59 +96,47 @@ static WaitEventCustomCounterData *WaitEventCustomCounter;
 static uint32 WaitEventCustomNew(uint32 classId, const char *wait_event_name);
 static const char *GetWaitEventCustomIdentifier(uint32 wait_event_info);
 
+static void WaitEventCustomShmemRequest(void *arg);
+static void WaitEventCustomShmemInit(void *arg);
+
+const ShmemCallbacks WaitEventCustomShmemCallbacks = {
+       .request_fn = WaitEventCustomShmemRequest,
+       .init_fn = WaitEventCustomShmemInit,
+};
+
 /*
- *  Return the space for dynamic shared hash tables and dynamic allocation counter.
+ * Register shmem space for dynamic shared hash and dynamic allocation counter.
  */
-Size
-WaitEventCustomShmemSize(void)
+static void
+WaitEventCustomShmemRequest(void *arg)
 {
-       Size            sz;
-
-       sz = MAXALIGN(sizeof(WaitEventCustomCounterData));
-       sz = add_size(sz, hash_estimate_size(WAIT_EVENT_CUSTOM_HASH_SIZE,
-                                                                                sizeof(WaitEventCustomEntryByInfo)));
-       sz = add_size(sz, hash_estimate_size(WAIT_EVENT_CUSTOM_HASH_SIZE,
-                                                                                sizeof(WaitEventCustomEntryByName)));
-       return sz;
+       ShmemRequestStruct(.name = "WaitEventCustomCounterData",
+                                          .size = sizeof(WaitEventCustomCounterData),
+                                          .ptr = (void **) &WaitEventCustomCounter,
+               );
+       ShmemRequestHash(.name = "WaitEventCustom hash by wait event information",
+                                        .ptr = &WaitEventCustomHashByInfo,
+                                        .nelems = WAIT_EVENT_CUSTOM_HASH_SIZE,
+                                        .hash_info.keysize = sizeof(uint32),
+                                        .hash_info.entrysize = sizeof(WaitEventCustomEntryByInfo),
+                                        .hash_flags = HASH_ELEM | HASH_BLOBS,
+               );
+       ShmemRequestHash(.name = "WaitEventCustom hash by name",
+                                        .ptr = &WaitEventCustomHashByName,
+                                        .nelems = WAIT_EVENT_CUSTOM_HASH_SIZE,
+       /* key is a NULL-terminated string */
+                                        .hash_info.keysize = sizeof(char[NAMEDATALEN]),
+                                        .hash_info.entrysize = sizeof(WaitEventCustomEntryByName),
+                                        .hash_flags = HASH_ELEM | HASH_STRINGS,
+               );
 }
 
-/*
- * Allocate shmem space for dynamic shared hash and dynamic allocation counter.
- */
-void
-WaitEventCustomShmemInit(void)
+static void
+WaitEventCustomShmemInit(void *arg)
 {
-       bool            found;
-       HASHCTL         info;
-
-       WaitEventCustomCounter = (WaitEventCustomCounterData *)
-               ShmemInitStruct("WaitEventCustomCounterData",
-                                               sizeof(WaitEventCustomCounterData), &found);
-
-       if (!found)
-       {
-               /* initialize the allocation counter and its spinlock. */
-               WaitEventCustomCounter->nextId = WAIT_EVENT_CUSTOM_INITIAL_ID;
-               SpinLockInit(&WaitEventCustomCounter->mutex);
-       }
-
-       /* initialize or attach the hash tables to store custom wait events */
-       info.keysize = sizeof(uint32);
-       info.entrysize = sizeof(WaitEventCustomEntryByInfo);
-       WaitEventCustomHashByInfo =
-               ShmemInitHash("WaitEventCustom hash by wait event information",
-                                         WAIT_EVENT_CUSTOM_HASH_SIZE,
-                                         &info,
-                                         HASH_ELEM | HASH_BLOBS);
-
-       /* key is a NULL-terminated string */
-       info.keysize = sizeof(char[NAMEDATALEN]);
-       info.entrysize = sizeof(WaitEventCustomEntryByName);
-       WaitEventCustomHashByName =
-               ShmemInitHash("WaitEventCustom hash by name",
-                                         WAIT_EVENT_CUSTOM_HASH_SIZE,
-                                         &info,
-                                         HASH_ELEM | HASH_STRINGS);
+       /* initialize the allocation counter and its spinlock. */
+       WaitEventCustomCounter->nextId = WAIT_EVENT_CUSTOM_INITIAL_ID;
+       SpinLockInit(&WaitEventCustomCounter->mutex);
 }
 
 /*
index c06b0e9b800925367f6f5757b16badc06b693dc9..a7c99e097ea46e111ced146afb7f88b894bf70dc 100644 (file)
@@ -17,6 +17,7 @@
  */
 #include "postgres.h"
 
+#include "storage/subsystems.h"
 #include "utils/injection_point.h"
 
 #ifdef USE_INJECTION_POINTS
@@ -109,6 +110,11 @@ typedef struct InjectionPointCacheEntry
 
 static HTAB *InjectionPointCache = NULL;
 
+#ifdef USE_INJECTION_POINTS
+static void InjectionPointShmemRequest(void *arg);
+static void InjectionPointShmemInit(void *arg);
+#endif
+
 /*
  * injection_point_cache_add
  *
@@ -226,45 +232,34 @@ injection_point_cache_get(const char *name)
 }
 #endif                                                 /* USE_INJECTION_POINTS */
 
-/*
- * Return the space for dynamic shared hash table.
- */
-Size
-InjectionPointShmemSize(void)
-{
+const ShmemCallbacks InjectionPointShmemCallbacks = {
 #ifdef USE_INJECTION_POINTS
-       Size            sz = 0;
-
-       sz = add_size(sz, sizeof(InjectionPointsCtl));
-       return sz;
-#else
-       return 0;
+       .request_fn = InjectionPointShmemRequest,
+       .init_fn = InjectionPointShmemInit,
 #endif
-}
+};
 
 /*
- * Allocate shmem space for dynamic shared hash.
+ * Reserve space for the dynamic shared hash table
  */
-void
-InjectionPointShmemInit(void)
-{
 #ifdef USE_INJECTION_POINTS
-       bool            found;
+static void
+InjectionPointShmemRequest(void *arg)
+{
+       ShmemRequestStruct(.name = "InjectionPoint hash",
+                                          .size = sizeof(InjectionPointsCtl),
+                                          .ptr = (void **) &ActiveInjectionPoints,
+               );
+}
 
-       ActiveInjectionPoints = ShmemInitStruct("InjectionPoint hash",
-                                                                                       sizeof(InjectionPointsCtl),
-                                                                                       &found);
-       if (!IsUnderPostmaster)
-       {
-               Assert(!found);
-               pg_atomic_init_u32(&ActiveInjectionPoints->max_inuse, 0);
-               for (int i = 0; i < MAX_INJECTION_POINTS; i++)
-                       pg_atomic_init_u64(&ActiveInjectionPoints->entries[i].generation, 0);
-       }
-       else
-               Assert(found);
-#endif
+static void
+InjectionPointShmemInit(void *arg)
+{
+       pg_atomic_init_u32(&ActiveInjectionPoints->max_inuse, 0);
+       for (int i = 0; i < MAX_INJECTION_POINTS; i++)
+               pg_atomic_init_u64(&ActiveInjectionPoints->entries[i].generation, 0);
 }
+#endif
 
 /*
  * Attach a new injection point.
index da7503c57b6f65267f90365a586de22cd4cb283f..3097e9bb1af9ba7c990b5d5e5f9025f1e078cfb6 100644 (file)
@@ -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,
index 24cf33294e5f742c7eddc0a673a13acb607d5d93..32f8332aaeea921a6f578ce80d87da3b5695d516 100644 (file)
@@ -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
index 761d56a5f3df991af9a358c21a38a839a2dde0a1..1d2ff42c9b72f5ab6487353b4947e71c88cfef11 100644 (file)
@@ -33,9 +33,6 @@ typedef struct GlobalTransactionData *GlobalTransaction;
 /* GUC variable */
 extern PGDLLIMPORT int max_prepared_xacts;
 
-extern Size TwoPhaseShmemSize(void);
-extern void TwoPhaseShmemInit(void);
-
 extern void AtAbort_Twophase(void);
 extern void PostPrepare_Twophase(void);
 
index 4af38e74ce49ebdf4c362adb50cbdbb1e585b11e..437b4f32349ee71ab39ccd58d62f3896708df311 100644 (file)
@@ -259,8 +259,6 @@ extern void InitLocalDataChecksumState(void);
 extern void SetLocalDataChecksumState(uint32 data_checksum_version);
 extern bool GetDefaultCharSignedness(void);
 extern XLogRecPtr GetFakeLSNForUnloggedRel(void);
-extern Size XLOGShmemSize(void);
-extern void XLOGShmemInit(void);
 extern void BootStrapXLOG(uint32 data_checksum_version);
 extern void InitializeWalConsistencyChecking(void);
 extern void LocalProcessControlFile(bool reset);
index 7ec40c4b78b89e6efd902d1630823154683d1a1f..56a81676d92319a0880b0ce2638d903588f53b37 100644 (file)
@@ -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);
index 2842106b285804fff8860c1d64bc5612f7efadbf..ba7750dca0b453255dcec212a41e3dc6d1df799c 100644 (file)
@@ -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);
index d12531d32b809fed3a622e0a599024f57ee28227..07157f220eae02b4e975708f3a5e875b227e2070 100644 (file)
@@ -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);
index 8e3549c3752547c7a210789d219d07c093186d20..2786a7c5ffbbd47b40ecd2198faf72ecf9400082 100644 (file)
@@ -541,10 +541,6 @@ typedef struct PgStat_BackendPending
  * Functions in pgstat.c
  */
 
-/* functions called from postmaster */
-extern Size StatsShmemSize(void);
-extern void StatsShmemInit(void);
-
 /* Functions called during server startup / shutdown */
 extern void pgstat_restore_stats(void);
 extern void pgstat_discard_stats(void);
index b21d111d4d5593059ed8b65de3d7fef48c5e6023..8954f6b28eed4e054f5775bb5d422136d3d9470f 100644 (file)
@@ -66,8 +66,4 @@ pg_noreturn extern void AutoVacWorkerMain(const void *startup_data, size_t start
 extern bool AutoVacuumRequestWork(AutoVacuumWorkItemType type,
                                                                  Oid relationId, BlockNumber blkno);
 
-/* shared memory stuff */
-extern Size AutoVacuumShmemSize(void);
-extern void AutoVacuumShmemInit(void);
-
 #endif                                                 /* AUTOVACUUM_H */
index b789caf403403c1c919d7aebddce3a71f8676d33..b6261bc01df7fc4d8422c2e26bdf2a7a1199ef20 100644 (file)
@@ -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);
index 47470cba89376e36cc58fdace9b6ca22c146e8a6..36eea0b1ab0c6fc0f872d7bf426d674893a0d8dc 100644 (file)
@@ -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 */
index 343494edcc8ee2b8fc5c9c3ef9a4a6922a6f63a1..05625539604c3f9dfac8b19ad19db07413c395d0 100644 (file)
 
 #include "storage/procsignal.h"
 
-/* Shared memory */
-extern Size DataChecksumsShmemSize(void);
-extern void DataChecksumsShmemInit(void);
-
 /* Possible operations the Datachecksumsworker can perform */
 typedef enum DataChecksumsWorkerOperation
 {
index faa7609cd81012dfeb4d9164d9a21be5139f242e..9772bb573a1fcfc0190cc94dc370f76b2d00ad0f 100644 (file)
@@ -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);
index a4c055066b4472a9aa15cb896c2608dcfec3d5ab..b9a755fadbc0e3ec965298d294e41dff6fe4716b 100644 (file)
@@ -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,
index 495554c532ce1acc3e15b7fb7aef312f9427cad9..0bc1302f13083f9e307da2aa65cc644eb2d441d5 100644 (file)
@@ -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);
index 504b710536a9fd080d9cb6b292388aa79623942a..5f0c1b9c68274d16e9d2b5e8700c1c75f60643a5 100644 (file)
@@ -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);
index eb46b41b4b704e13fa5d0dbe4d46155de9f61fec..a69faf6eaaf68488d218cf470108a36c0662bf5c 100644 (file)
@@ -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 */
index 4b4709f6e2c86ff488e8ddc816e90c2c2f0d87ed..1a3557de6070ab847c37ae0997965e8021d46487 100644 (file)
@@ -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,
index e546d0d050dc606bb68e799e8e61783962bba9e2..d2121cd3ed77e918fa047ed898c54c7da1d89046 100644 (file)
@@ -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 */
index 85d24c87298682431efe514632bb05a5807e74f0..47c07574d4d82dd1dbb0d345572853e8d7e99338 100644 (file)
@@ -491,8 +491,6 @@ pg_noreturn extern void WalReceiverMain(const void *startup_data, size_t startup
 extern void WalRcvRequestApplyReply(void);
 
 /* prototypes for functions in walreceiverfuncs.c */
-extern Size WalRcvShmemSize(void);
-extern void WalRcvShmemInit(void);
 extern void ShutdownWalRcv(void);
 extern bool WalRcvStreaming(void);
 extern bool WalRcvRunning(void);
index a4df3b8e0aee7ae9e9fb2eaecb1c7d375060877f..8952c848d19ca53f92d3a8c25155f4e19cd9c38d 100644 (file)
@@ -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);
index fa68e6ecece4ffc7c7d85c083d584a7644cee66b..ee3cb1dc203caed3b6b28163265017b090ebb0e0 100644 (file)
@@ -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);
index d8e11756a618b8191c07777869fdf47067d37c69..5e092552c7257e655700512f9a7ceb9dfb45a388 100644 (file)
@@ -32,6 +32,9 @@ PG_SHMEM_SUBSYSTEM(DSMRegistryShmemCallbacks)
 
 /* xlog, clog, and buffers */
 PG_SHMEM_SUBSYSTEM(VarsupShmemCallbacks)
+PG_SHMEM_SUBSYSTEM(XLOGShmemCallbacks)
+PG_SHMEM_SUBSYSTEM(XLogPrefetchShmemCallbacks)
+PG_SHMEM_SUBSYSTEM(XLogRecoveryShmemCallbacks)
 PG_SHMEM_SUBSYSTEM(CLOGShmemCallbacks)
 PG_SHMEM_SUBSYSTEM(CommitTsShmemCallbacks)
 PG_SHMEM_SUBSYSTEM(SUBTRANSShmemCallbacks)
@@ -40,12 +43,18 @@ PG_SHMEM_SUBSYSTEM(BufferManagerShmemCallbacks)
 PG_SHMEM_SUBSYSTEM(StrategyCtlShmemCallbacks)
 PG_SHMEM_SUBSYSTEM(BufTableShmemCallbacks)
 
+/* lock manager */
+PG_SHMEM_SUBSYSTEM(LockManagerShmemCallbacks)
+
 /* predicate lock manager */
 PG_SHMEM_SUBSYSTEM(PredicateLockShmemCallbacks)
 
 /* process table */
 PG_SHMEM_SUBSYSTEM(ProcGlobalShmemCallbacks)
 PG_SHMEM_SUBSYSTEM(ProcArrayShmemCallbacks)
+PG_SHMEM_SUBSYSTEM(BackendStatusShmemCallbacks)
+PG_SHMEM_SUBSYSTEM(TwoPhaseShmemCallbacks)
+PG_SHMEM_SUBSYSTEM(BackgroundWorkerShmemCallbacks)
 
 /* shared-inval messaging */
 PG_SHMEM_SUBSYSTEM(SharedInvalShmemCallbacks)
@@ -53,9 +62,27 @@ PG_SHMEM_SUBSYSTEM(SharedInvalShmemCallbacks)
 /* interprocess signaling mechanisms */
 PG_SHMEM_SUBSYSTEM(PMSignalShmemCallbacks)
 PG_SHMEM_SUBSYSTEM(ProcSignalShmemCallbacks)
+PG_SHMEM_SUBSYSTEM(CheckpointerShmemCallbacks)
+PG_SHMEM_SUBSYSTEM(AutoVacuumShmemCallbacks)
+PG_SHMEM_SUBSYSTEM(ReplicationSlotsShmemCallbacks)
+PG_SHMEM_SUBSYSTEM(ReplicationOriginShmemCallbacks)
+PG_SHMEM_SUBSYSTEM(WalSndShmemCallbacks)
+PG_SHMEM_SUBSYSTEM(WalRcvShmemCallbacks)
+PG_SHMEM_SUBSYSTEM(WalSummarizerShmemCallbacks)
+PG_SHMEM_SUBSYSTEM(PgArchShmemCallbacks)
+PG_SHMEM_SUBSYSTEM(ApplyLauncherShmemCallbacks)
+PG_SHMEM_SUBSYSTEM(SlotSyncShmemCallbacks)
 
 /* other modules that need some shared memory space */
+PG_SHMEM_SUBSYSTEM(BTreeShmemCallbacks)
+PG_SHMEM_SUBSYSTEM(SyncScanShmemCallbacks)
 PG_SHMEM_SUBSYSTEM(AsyncShmemCallbacks)
+PG_SHMEM_SUBSYSTEM(StatsShmemCallbacks)
+PG_SHMEM_SUBSYSTEM(WaitEventCustomShmemCallbacks)
+PG_SHMEM_SUBSYSTEM(InjectionPointShmemCallbacks)
+PG_SHMEM_SUBSYSTEM(WaitLSNShmemCallbacks)
+PG_SHMEM_SUBSYSTEM(LogicalDecodingCtlShmemCallbacks)
+PG_SHMEM_SUBSYSTEM(DataChecksumsShmemCallbacks)
 
 /* AIO subsystem. This delegates to the method-specific callbacks */
 PG_SHMEM_SUBSYSTEM(AioShmemCallbacks)
index ddd06304e975ed70237ff86e04c7512ccc32c0ad..a334e096e4a6b38dfcb45809608fb52caa4a623f 100644 (file)
@@ -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
  * ----------
index 27a2526524fd34f721984677413509f0d60e496c..fabd1455c3ccf9f4e2e20a1f7966218f07183149 100644 (file)
@@ -46,9 +46,6 @@ typedef void (*InjectionPointCallback) (const char *name,
                                                                                const void *private_data,
                                                                                void *arg);
 
-extern Size InjectionPointShmemSize(void);
-extern void InjectionPointShmemInit(void);
-
 extern void InjectionPointAttach(const char *name,
                                                                 const char *library,
                                                                 const char *function,
index 34c27cc3dc3e1a5b0d7dfe4757b549e3bba9232e..86ee348220d7f75bf753cee1fe1fd4b44f28fad6 100644 (file)
@@ -42,8 +42,6 @@ extern PGDLLIMPORT uint32 *my_wait_event_info;
 extern uint32 WaitEventExtensionNew(const char *wait_event_name);
 extern uint32 WaitEventInjectionPointNew(const char *wait_event_name);
 
-extern void WaitEventCustomShmemInit(void);
-extern Size WaitEventCustomShmemSize(void);
 extern char **GetWaitEventCustomNames(uint32 classId, int *nwaitevents);
 
 /* ----------
index d59c5ad05823b19455d487b16fd171e855a6de87..0f1af51367357f31f35682d559d9f739725eb590 100644 (file)
@@ -107,9 +107,13 @@ extern PGDLLEXPORT void injection_wait(const char *name,
 /* track if injection points attached in this process are linked to it */
 static bool injection_point_local = false;
 
-/* Shared memory init callbacks */
-static shmem_request_hook_type prev_shmem_request_hook = NULL;
-static shmem_startup_hook_type prev_shmem_startup_hook = NULL;
+static void injection_shmem_request(void *arg);
+static void injection_shmem_init(void *arg);
+
+static const ShmemCallbacks injection_shmem_callbacks = {
+       .request_fn = injection_shmem_request,
+       .init_fn = injection_shmem_init,
+};
 
 /*
  * Routine for shared memory area initialization, used as a callback
@@ -126,44 +130,23 @@ injection_point_init_state(void *ptr, void *arg)
        ConditionVariableInit(&state->wait_point);
 }
 
-/* Shared memory initialization when loading module */
 static void
-injection_shmem_request(void)
+injection_shmem_request(void *arg)
 {
-       Size            size;
-
-       if (prev_shmem_request_hook)
-               prev_shmem_request_hook();
-
-       size = MAXALIGN(sizeof(InjectionPointSharedState));
-       RequestAddinShmemSpace(size);
+       ShmemRequestStruct(.name = "injection_points",
+                                          .size = sizeof(InjectionPointSharedState),
+                                          .ptr = (void **) &inj_state,
+               );
 }
 
 static void
-injection_shmem_startup(void)
+injection_shmem_init(void *arg)
 {
-       bool            found;
-
-       if (prev_shmem_startup_hook)
-               prev_shmem_startup_hook();
-
-       /* Create or attach to the shared memory state */
-       LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE);
-
-       inj_state = ShmemInitStruct("injection_points",
-                                                               sizeof(InjectionPointSharedState),
-                                                               &found);
-
-       if (!found)
-       {
-               /*
-                * First time through, so initialize.  This is shared with the dynamic
-                * initialization using a DSM.
-                */
-               injection_point_init_state(inj_state, NULL);
-       }
-
-       LWLockRelease(AddinShmemInitLock);
+       /*
+        * First time through, so initialize.  This is shared with the dynamic
+        * initialization using a DSM.
+        */
+       injection_point_init_state(inj_state, NULL);
 }
 
 /*
@@ -601,9 +584,5 @@ _PG_init(void)
        if (!process_shared_preload_libraries_in_progress)
                return;
 
-       /* Shared memory initialization */
-       prev_shmem_request_hook = shmem_request_hook;
-       shmem_request_hook = injection_shmem_request;
-       prev_shmem_startup_hook = shmem_startup_hook;
-       shmem_startup_hook = injection_shmem_startup;
+       RegisterShmemCallbacks(&injection_shmem_callbacks);
 }
index d7530681192f51974a7a274a0981dd7a8ad2192e..35efba1a5e3c9e2b1d2c99085134c81009a5915a 100644 (file)
@@ -28,7 +28,6 @@
 #include "storage/bufmgr.h"
 #include "storage/checksum.h"
 #include "storage/condition_variable.h"
-#include "storage/ipc.h"
 #include "storage/lwlock.h"
 #include "storage/proc.h"
 #include "storage/procnumber.h"
@@ -44,6 +43,7 @@
 PG_MODULE_MAGIC;
 
 
+/* In shared memory */
 typedef struct InjIoErrorState
 {
        ConditionVariable cv;
@@ -74,8 +74,15 @@ typedef struct BlocksReadStreamData
 static InjIoErrorState *inj_io_error_state;
 
 /* Shared memory init callbacks */
-static shmem_request_hook_type prev_shmem_request_hook = NULL;
-static shmem_startup_hook_type prev_shmem_startup_hook = NULL;
+static void test_aio_shmem_request(void *arg);
+static void test_aio_shmem_init(void *arg);
+static void test_aio_shmem_attach(void *arg);
+
+static const ShmemCallbacks inj_io_shmem_callbacks = {
+       .request_fn = test_aio_shmem_request,
+       .init_fn = test_aio_shmem_init,
+       .attach_fn = test_aio_shmem_attach,
+};
 
 
 static PgAioHandle *last_handle;
@@ -83,70 +90,55 @@ static PgAioHandle *last_handle;
 
 
 static void
-test_aio_shmem_request(void)
+test_aio_shmem_request(void *arg)
 {
-       if (prev_shmem_request_hook)
-               prev_shmem_request_hook();
-
-       RequestAddinShmemSpace(sizeof(InjIoErrorState));
+       ShmemRequestStruct(.name = "test_aio injection points",
+                                          .size = sizeof(InjIoErrorState),
+                                          .ptr = (void **) &inj_io_error_state,
+               );
 }
 
 static void
-test_aio_shmem_startup(void)
+test_aio_shmem_init(void *arg)
 {
-       bool            found;
-
-       if (prev_shmem_startup_hook)
-               prev_shmem_startup_hook();
-
-       /* Create or attach to the shared memory state */
-       LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE);
-
-       inj_io_error_state = ShmemInitStruct("injection_points",
-                                                                                sizeof(InjIoErrorState),
-                                                                                &found);
-
-       if (!found)
-       {
-               /* First time through, initialize */
-               inj_io_error_state->enabled_short_read = false;
-               inj_io_error_state->enabled_reopen = false;
-               inj_io_error_state->enabled_completion_wait = false;
+       /* First time through, initialize */
+       inj_io_error_state->enabled_short_read = false;
+       inj_io_error_state->enabled_reopen = false;
+       inj_io_error_state->enabled_completion_wait = false;
 
-               ConditionVariableInit(&inj_io_error_state->cv);
-               inj_io_error_state->completion_wait_event = WaitEventInjectionPointNew("completion_wait");
+       ConditionVariableInit(&inj_io_error_state->cv);
+       inj_io_error_state->completion_wait_event = WaitEventInjectionPointNew("completion_wait");
 
 #ifdef USE_INJECTION_POINTS
-               InjectionPointAttach("aio-process-completion-before-shared",
-                                                        "test_aio",
-                                                        "inj_io_completion_hook",
-                                                        NULL,
-                                                        0);
-               InjectionPointLoad("aio-process-completion-before-shared");
-
-               InjectionPointAttach("aio-worker-after-reopen",
-                                                        "test_aio",
-                                                        "inj_io_reopen",
-                                                        NULL,
-                                                        0);
-               InjectionPointLoad("aio-worker-after-reopen");
+       InjectionPointAttach("aio-process-completion-before-shared",
+                                                "test_aio",
+                                                "inj_io_completion_hook",
+                                                NULL,
+                                                0);
+       InjectionPointLoad("aio-process-completion-before-shared");
+
+       InjectionPointAttach("aio-worker-after-reopen",
+                                                "test_aio",
+                                                "inj_io_reopen",
+                                                NULL,
+                                                0);
+       InjectionPointLoad("aio-worker-after-reopen");
 
 #endif
-       }
-       else
-       {
-               /*
-                * Pre-load the injection points now, so we can call them in a
-                * critical section.
-                */
+}
+
+static void
+test_aio_shmem_attach(void *arg)
+{
+       /*
+        * Pre-load the injection points now, so we can call them in a critical
+        * section.
+        */
 #ifdef USE_INJECTION_POINTS
-               InjectionPointLoad("aio-process-completion-before-shared");
-               InjectionPointLoad("aio-worker-after-reopen");
-               elog(LOG, "injection point loaded");
+       InjectionPointLoad("aio-process-completion-before-shared");
+       InjectionPointLoad("aio-worker-after-reopen");
+       elog(LOG, "injection point loaded");
 #endif
-       }
-
-       LWLockRelease(AddinShmemInitLock);
 }
 
 void
@@ -155,10 +147,7 @@ _PG_init(void)
        if (!process_shared_preload_libraries_in_progress)
                return;
 
-       prev_shmem_request_hook = shmem_request_hook;
-       shmem_request_hook = test_aio_shmem_request;
-       prev_shmem_startup_hook = shmem_startup_hook;
-       shmem_startup_hook = test_aio_shmem_startup;
+       RegisterShmemCallbacks(&inj_io_shmem_callbacks);
 }