#include "miscadmin.h"
#include "storage/lwlock.h"
#include "storage/shmem.h"
+#include "storage/subsystems.h"
#include "utils/rel.h"
#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;
/*
- * 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);
}
/*
#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"
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,
}
/*
- * 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 *
#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"
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
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;
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);
}
/*
#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"
/*
* 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!
LocalProcessControlFile(bool reset)
{
Assert(reset || ControlFile == NULL);
- ControlFile = palloc_object(ControlFileData);
+ LocalControlFile = palloc_object(ControlFileData);
+ ControlFile = LocalControlFile;
ReadControlFile();
SetLocalDataChecksumState(ControlFile->data_checksum_version);
}
}
/*
- * Initialization of shared memory for XLOG
+ * Register shared memory for XLOG.
*/
-Size
-XLOGShmemSize(void)
+static void
+XLOGShmemRequest(void *arg)
{
Size size;
/* 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
}
#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;
}
/*
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.
#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"
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,
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);
}
/*
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.
#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"
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
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);
#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"
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.
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));
}
/*
#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"
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
}
/*
- * 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;
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);
}
/*
#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"
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.
/*
- * Calculate shared memory needed.
+ * Register shared memory needed for background workers.
*/
-Size
-BackgroundWorkerShmemSize(void)
+static void
+BackgroundWorkerShmemRequest(void *arg)
{
Size size;
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);
}
/*
#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"
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
*/
/*
- * 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;
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);
}
/*
#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"
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);
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
*/
}
/*
- * 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,
+ );
}
/*
#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"
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);
}
/*
#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"
/* 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
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);
}
/*
#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"
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
{
}
/*
- * 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;
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,
+ );
}
/*
/*
* 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);
}
}
#include "storage/proc.h"
#include "storage/procarray.h"
#include "storage/procsignal.h"
+#include "storage/subsystems.h"
#include "utils/injection_point.h"
/*
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
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,
+ );
}
/*
#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"
*/
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).
*/
* ---------------------------------------------------------------------------
*/
-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;
}
/* ---------------------------------------------------------------------------
#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"
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;
}
/*
- * 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);
}
/*
#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"
/* 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;
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);
}
}
#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)? */
#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;
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);
}
/*
*/
#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;
static Size total_addin_request = 0;
-static void CreateOrAttachShmemStructs(void);
-
/*
* RequestAddinShmemSpace
* Request that extra shmem space be allocated for use by
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);
/* Establish pointers to all shared memory areas in this backend */
ShmemAttachRequested();
- CreateOrAttachShmemStructs();
/*
* Now give loadable modules a chance to set up their shmem allocations
/* Initialize all shmem areas */
ShmemInitRequested();
- /* Initialize legacy subsystems */
- CreateOrAttachShmemStructs();
-
/* Initialize dynamic shared memory facilities. */
dsm_postmaster_startup(shim);
#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
*
#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"
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
/*
- * 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
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);
}
/*
}
-/*
- * 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.
#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"
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++)
#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++)
#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
#include "pgstat.h"
#include "storage/shmem.h"
+#include "storage/subsystems.h"
#include "utils/memutils.h"
#include "utils/pgstat_internal.h"
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 = {
/*
* Compute shared memory space needed for cumulative statistics
*/
-Size
+static Size
StatsShmemSize(void)
{
Size sz;
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
#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"
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);
}
/*
*/
#include "postgres.h"
+#include "storage/subsystems.h"
#include "utils/injection_point.h"
#ifdef USE_INJECTION_POINTS
static HTAB *InjectionPointCache = NULL;
+#ifdef USE_INJECTION_POINTS
+static void InjectionPointShmemRequest(void *arg);
+static void InjectionPointShmemInit(void *arg);
+#endif
+
/*
* injection_point_cache_add
*
}
#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.
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,
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
/* 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);
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);
extern void XLogPrefetchReconfigure(void);
-extern size_t XLogPrefetchShmemSize(void);
-extern void XLogPrefetchShmemInit(void);
-
extern void XLogPrefetchResetStats(void);
extern XLogPrefetcher *XLogPrefetcherAllocate(XLogReaderState *reader);
/* 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);
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);
* 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);
extern bool AutoVacuumRequestWork(AutoVacuumWorkItemType type,
Oid relationId, BlockNumber blkno);
-/* shared memory stuff */
-extern Size AutoVacuumShmemSize(void);
-extern void AutoVacuumShmemInit(void);
-
#endif /* AUTOVACUUM_H */
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);
extern void AbsorbSyncRequests(void);
-extern Size CheckpointerShmemSize(void);
-extern void CheckpointerShmemInit(void);
-
extern bool FirstCallSinceLastCheckpoint(void);
#endif /* _BGWRITER_H */
#include "storage/procsignal.h"
-/* Shared memory */
-extern Size DataChecksumsShmemSize(void);
-extern void DataChecksumsShmemInit(void);
-
/* Possible operations the Datachecksumsworker can perform */
typedef enum DataChecksumsWorkerOperation
{
#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);
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,
#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);
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);
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 */
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,
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 */
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);
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);
/*
* 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);
/* xlog, clog, and buffers */
PG_SHMEM_SUBSYSTEM(VarsupShmemCallbacks)
+PG_SHMEM_SUBSYSTEM(XLOGShmemCallbacks)
+PG_SHMEM_SUBSYSTEM(XLogPrefetchShmemCallbacks)
+PG_SHMEM_SUBSYSTEM(XLogRecoveryShmemCallbacks)
PG_SHMEM_SUBSYSTEM(CLOGShmemCallbacks)
PG_SHMEM_SUBSYSTEM(CommitTsShmemCallbacks)
PG_SHMEM_SUBSYSTEM(SUBTRANSShmemCallbacks)
PG_SHMEM_SUBSYSTEM(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)
/* 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)
extern PGDLLIMPORT PgBackendStatus *MyBEEntry;
-/* ----------
- * Functions called from postmaster
- * ----------
- */
-extern Size BackendStatusShmemSize(void);
-extern void BackendStatusShmemInit(void);
-
-
/* ----------
* Functions called from backends
* ----------
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,
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);
/* ----------
/* 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
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);
}
/*
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);
}
#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"
PG_MODULE_MAGIC;
+/* In shared memory */
typedef struct InjIoErrorState
{
ConditionVariable cv;
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;
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
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);
}