Convert all remaining subsystems to use the new shmem allocation API

This removes all remaining uses of ShmemInitStruct() and
ShmemInitHash() from built-in code.

Reviewed-by: Ashutosh Bapat <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
This commit is contained in:
Heikki Linnakangas 2026-04-06 02:13:10 +03:00
parent a4b6139dcc
commit 9b5acad3f4
54 changed files with 939 additions and 1220 deletions

View 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);
ss_lru_item_t *item = &scan_locations->items[i];
scan_locations->head = &scan_locations->items[0];
scan_locations->tail = &scan_locations->items[SYNC_SCAN_NELEM - 1];
/*
* 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;
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;
}
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);
}
/*

View 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;
/*
* 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 = (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);
btvacinfo->num_vacuums = 0;
btvacinfo->max_vacuums = MaxBackends;
}
else
Assert(found);
btvacinfo->num_vacuums = 0;
btvacinfo->max_vacuums = MaxBackends;
}
bytea *

View file

@ -102,6 +102,7 @@
#include "storage/predicate.h"
#include "storage/proc.h"
#include "storage/procarray.h"
#include "storage/subsystems.h"
#include "utils/builtins.h"
#include "utils/injection_point.h"
#include "utils/memutils.h"
@ -189,6 +190,14 @@ typedef struct TwoPhaseStateData
static TwoPhaseStateData *TwoPhaseState;
static void TwoPhaseShmemRequest(void *arg);
static void TwoPhaseShmemInit(void *arg);
const ShmemCallbacks TwoPhaseShmemCallbacks = {
.request_fn = TwoPhaseShmemRequest,
.init_fn = TwoPhaseShmemInit,
};
/*
* Global transaction entry currently locked by us, if any. Note that any
* access to the entry pointed to by this variable must be protected by
@ -234,10 +243,10 @@ static void RemoveTwoPhaseFile(FullTransactionId fxid, bool giveWarning);
static void RecreateTwoPhaseFile(FullTransactionId fxid, void *content, int len);
/*
* Initialization of shared memory
* Register shared memory for two-phase state.
*/
Size
TwoPhaseShmemSize(void)
static void
TwoPhaseShmemRequest(void *arg)
{
Size size;
@ -248,46 +257,40 @@ TwoPhaseShmemSize(void)
size = MAXALIGN(size);
size = add_size(size, mul_size(max_prepared_xacts,
sizeof(GlobalTransactionData)));
return size;
ShmemRequestStruct(.name = "Prepared Transaction Table",
.size = size,
.ptr = (void **) &TwoPhaseState,
);
}
void
TwoPhaseShmemInit(void)
/*
* Initialize shared memory for two-phase state.
*/
static void
TwoPhaseShmemInit(void *arg)
{
bool found;
GlobalTransaction gxacts;
int i;
TwoPhaseState = ShmemInitStruct("Prepared Transaction Table",
TwoPhaseShmemSize(),
&found);
if (!IsUnderPostmaster)
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++)
{
GlobalTransaction gxacts;
int i;
/* insert into linked list */
gxacts[i].next = TwoPhaseState->freeGXacts;
TwoPhaseState->freeGXacts = &gxacts[i];
Assert(!found);
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];
/* 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);
}
/*

View 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.

View 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)
{
return sizeof(XLogPrefetchStats);
ShmemRequestStruct(.name = "XLogPrefetchStats",
.size = sizeof(XLogPrefetchStats),
.ptr = (void **) &SharedStats,
);
}
static void
XLogPrefetchShmemInit(void *arg)
{
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.

View 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);

View 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));
}
/*

View 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;
WorkerInfo worker;
AutoVacuumShmem = (AutoVacuumShmemStruct *)
ShmemInitStruct("AutoVacuum Data",
AutoVacuumShmemSize(),
&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);
if (!IsUnderPostmaster)
worker = (WorkerInfo) ((char *) AutoVacuumShmem +
MAXALIGN(sizeof(AutoVacuumShmemStruct)));
/* initialize the WorkerInfo free list */
for (int i = 0; i < autovacuum_worker_slots; i++)
{
WorkerInfo worker;
int i;
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);
}
pg_atomic_init_u32(&AutoVacuumShmem->av_nworkersForBalance, 0);
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);
}
/*

View 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;
dlist_iter iter;
int slotno = 0;
BackgroundWorkerData = ShmemInitStruct("Background Worker Data",
BackgroundWorkerShmemSize(),
&found);
if (!IsUnderPostmaster)
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)
{
dlist_iter iter;
int slotno = 0;
BackgroundWorkerSlot *slot = &BackgroundWorkerData->slot[slotno];
RegisteredBgWorker *rw;
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;
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];
slot->in_use = false;
++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];
slot->in_use = false;
++slotno;
}
else
Assert(found);
}
/*

View 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);
}
/*

View file

@ -211,6 +211,7 @@
#include "storage/lwlock.h"
#include "storage/procarray.h"
#include "storage/smgr.h"
#include "storage/subsystems.h"
#include "tcop/tcopprot.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
@ -346,6 +347,7 @@ static volatile sig_atomic_t launcher_running = false;
static DataChecksumsWorkerOperation operation;
/* Prototypes */
static void DataChecksumsShmemRequest(void *arg);
static bool DatabaseExists(Oid dboid);
static List *BuildDatabaseList(void);
static List *BuildRelationList(bool temp_relations, bool include_shared);
@ -356,6 +358,10 @@ static bool ProcessSingleRelationFork(Relation reln, ForkNumber forkNum, BufferA
static void launcher_cancel_handler(SIGNAL_ARGS);
static void WaitForAllTransactionsToFinish(void);
const ShmemCallbacks DataChecksumsShmemCallbacks = {
.request_fn = DataChecksumsShmemRequest,
};
/*****************************************************************************
* Functionality for manipulating the data checksum state in the cluster
*/
@ -1236,35 +1242,16 @@ ProcessAllDatabases(void)
}
/*
* DataChecksumStateSize
* Compute required space for datachecksumsworker-related shared memory
* DataChecksumShmemRequest
* Request datachecksumsworker-related shared memory
*/
Size
DataChecksumsShmemSize(void)
static void
DataChecksumsShmemRequest(void *arg)
{
Size size;
size = sizeof(DataChecksumsStateStruct);
size = MAXALIGN(size);
return size;
}
/*
* DataChecksumStateInit
* Allocate and initialize datachecksumsworker-related shared memory
*/
void
DataChecksumsShmemInit(void)
{
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,
);
}
/*

View 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)
static void PgArchShmemRequest(void *arg);
static void PgArchShmemInit(void *arg);
const ShmemCallbacks PgArchShmemCallbacks = {
.request_fn = PgArchShmemRequest,
.init_fn = PgArchShmemInit,
};
/* Register shared memory space needed by the archiver */
static void
PgArchShmemRequest(void *arg)
{
Size size = 0;
size = add_size(size, sizeof(PgArchData));
return size;
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);
}
/*

View 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);
}
/*

View 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;
LogicalRepWorker *worker = &LogicalRepCtx->workers[slot];
memset(LogicalRepCtx, 0, ApplyLauncherShmemSize());
LogicalRepCtx->last_start_dsa = DSA_HANDLE_INVALID;
LogicalRepCtx->last_start_dsh = DSHASH_HANDLE_INVALID;
/* 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);
}
}

View 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)
static void
LogicalDecodingCtlShmemRequest(void *arg)
{
return sizeof(LogicalDecodingCtlData);
}
void
LogicalDecodingCtlShmemInit(void)
{
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,
);
}
/*

View 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,52 +550,50 @@ 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)
replication_states_ctl->tranche_id = LWTRANCHE_REPLICATION_ORIGIN_STATE;
for (int i = 0; i < max_active_replication_origins; i++)
{
int i;
MemSet(replication_states_ctl, 0, ReplicationOriginShmemSize());
replication_states_ctl->tranche_id = LWTRANCHE_REPLICATION_ORIGIN_STATE;
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);
}
LWLockInitialize(&replication_states[i].lock,
replication_states_ctl->tranche_id);
ConditionVariableInit(&replication_states[i].origin_cv);
}
}
static void
ReplicationOriginShmemAttach(void *arg)
{
if (max_active_replication_origins == 0)
return;
replication_states = replication_states_ctl->states;
}
/* ---------------------------------------------------------------------------
* Perform a checkpoint of each replication origin's progress with respect to
* the replayed remote_lsn. Make sure that all transactions we refer to in the

View 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);
}
/*

View 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;
if (max_replication_slots == 0)
return size;
size = offsetof(ReplicationSlotCtlData, replication_slots);
size = add_size(size,
mul_size(max_replication_slots, sizeof(ReplicationSlot)));
return size;
}
/*
* Allocate and initialize shared memory for replication slots.
*/
void
ReplicationSlotsShmemInit(void)
{
bool found;
Size size;
if (max_replication_slots == 0)
return;
ReplicationSlotCtl = (ReplicationSlotCtlData *)
ShmemInitStruct("ReplicationSlot Ctl", ReplicationSlotsShmemSize(),
&found);
size = offsetof(ReplicationSlotCtlData, replication_slots);
size = add_size(size,
mul_size(max_replication_slots, sizeof(ReplicationSlot)));
ShmemRequestStruct(.name = "ReplicationSlot Ctl",
.size = size,
.ptr = (void **) &ReplicationSlotCtl,
);
}
if (!found)
/*
* Initialize shared memory for replication slots.
*/
static void
ReplicationSlotsShmemInit(void *arg)
{
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);
}
}

View file

@ -29,47 +29,46 @@
#include "storage/pmsignal.h"
#include "storage/proc.h"
#include "storage/shmem.h"
#include "storage/subsystems.h"
#include "utils/timestamp.h"
#include "utils/wait_event.h"
WalRcvData *WalRcv = NULL;
static void WalRcvShmemRequest(void *arg);
static void WalRcvShmemInit(void *arg);
const ShmemCallbacks WalRcvShmemCallbacks = {
.request_fn = WalRcvShmemRequest,
.init_fn = WalRcvShmemInit,
};
/*
* How long to wait for walreceiver to start up after requesting
* postmaster to launch it. In seconds.
*/
#define WALRCV_STARTUP_TIMEOUT 10
/* Report shared memory space needed by WalRcvShmemInit */
Size
WalRcvShmemSize(void)
/* Register shared memory space needed by walreceiver */
static void
WalRcvShmemRequest(void *arg)
{
Size size = 0;
size = add_size(size, sizeof(WalRcvData));
return size;
ShmemRequestStruct(.name = "Wal Receiver Ctl",
.size = sizeof(WalRcvData),
.ptr = (void **) &WalRcv,
);
}
/* Allocate and initialize walreceiver-related shared memory */
void
WalRcvShmemInit(void)
/* Initialize walreceiver-related shared memory */
static void
WalRcvShmemInit(void *arg)
{
bool found;
WalRcv = (WalRcvData *)
ShmemInitStruct("Wal Receiver Ctl", WalRcvShmemSize(), &found);
if (!found)
{
/* First time through, so initialize */
MemSet(WalRcv, 0, WalRcvShmemSize());
WalRcv->walRcvState = WALRCV_STOPPED;
ConditionVariableInit(&WalRcv->walRcvStoppedCV);
SpinLockInit(&WalRcv->mutex);
pg_atomic_init_u64(&WalRcv->writtenUpto, 0);
WalRcv->procno = INVALID_PROC_NUMBER;
}
MemSet(WalRcv, 0, sizeof(WalRcvData));
WalRcv->walRcvState = WALRCV_STOPPED;
ConditionVariableInit(&WalRcv->walRcvStoppedCV);
SpinLockInit(&WalRcv->mutex);
pg_atomic_init_u64(&WalRcv->writtenUpto, 0);
WalRcv->procno = INVALID_PROC_NUMBER;
}
/* Is walreceiver running (or starting up)? */

View 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"
@ -117,6 +118,14 @@
/* Array of WalSnds in shared memory */
WalSndCtlData *WalSndCtl = NULL;
static void WalSndShmemRequest(void *arg);
static void WalSndShmemInit(void *arg);
const ShmemCallbacks WalSndShmemCallbacks = {
.request_fn = WalSndShmemRequest,
.init_fn = WalSndShmemInit,
};
/* My slot in the shared memory array */
WalSnd *MyWalSnd = NULL;
@ -3765,47 +3774,37 @@ WalSndSignals(void)
pqsignal(SIGCHLD, SIG_DFL);
}
/* Report shared-memory space needed by WalSndShmemInit */
Size
WalSndShmemSize(void)
/* Register shared-memory space needed by walsender */
static void
WalSndShmemRequest(void *arg)
{
Size size = 0;
Size size;
size = offsetof(WalSndCtlData, walsnds);
size = add_size(size, mul_size(max_wal_senders, sizeof(WalSnd)));
return size;
ShmemRequestStruct(.name = "Wal Sender Ctl",
.size = size,
.ptr = (void **) &WalSndCtl,
);
}
/* Allocate and initialize walsender-related shared memory */
void
WalSndShmemInit(void)
/* Initialize walsender-related shared memory */
static void
WalSndShmemInit(void *arg)
{
bool found;
int i;
for (int i = 0; i < NUM_SYNC_REP_WAIT_MODE; i++)
dlist_init(&(WalSndCtl->SyncRepQueue[i]));
WalSndCtl = (WalSndCtlData *)
ShmemInitStruct("Wal Sender Ctl", WalSndShmemSize(), &found);
if (!found)
for (int i = 0; i < max_wal_senders; i++)
{
/* First time through, so initialize */
MemSet(WalSndCtl, 0, WalSndShmemSize());
WalSnd *walsnd = &WalSndCtl->walsnds[i];
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);
}
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);
}
/*

View file

@ -14,41 +14,16 @@
*/
#include "postgres.h"
#include "access/clog.h"
#include "access/commit_ts.h"
#include "access/multixact.h"
#include "access/nbtree.h"
#include "access/subtrans.h"
#include "access/syncscan.h"
#include "access/twophase.h"
#include "access/xlogprefetcher.h"
#include "access/xlogrecovery.h"
#include "access/xlogwait.h"
#include "commands/async.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "postmaster/autovacuum.h"
#include "postmaster/bgworker_internals.h"
#include "postmaster/bgwriter.h"
#include "postmaster/datachecksum_state.h"
#include "postmaster/walsummarizer.h"
#include "replication/logicallauncher.h"
#include "replication/origin.h"
#include "replication/slot.h"
#include "replication/slotsync.h"
#include "replication/walreceiver.h"
#include "replication/walsender.h"
#include "storage/aio_subsys.h"
#include "storage/dsm.h"
#include "storage/ipc.h"
#include "storage/lock.h"
#include "storage/pg_shmem.h"
#include "storage/predicate.h"
#include "storage/proc.h"
#include "storage/shmem_internal.h"
#include "storage/subsystems.h"
#include "utils/guc.h"
#include "utils/injection_point.h"
#include "utils/wait_event.h"
/* GUCs */
int shared_memory_type = DEFAULT_SHARED_MEMORY_TYPE;
@ -57,8 +32,6 @@ shmem_startup_hook_type shmem_startup_hook = NULL;
static Size total_addin_request = 0;
static void CreateOrAttachShmemStructs(void);
/*
* RequestAddinShmemSpace
* Request that extra shmem space be allocated for use by
@ -97,33 +70,6 @@ CalculateShmemSize(void)
size = 100000;
size = add_size(size, ShmemGetRequestedSize());
/* legacy subsystems */
size = add_size(size, LockManagerShmemSize());
size = add_size(size, XLogPrefetchShmemSize());
size = add_size(size, XLOGShmemSize());
size = add_size(size, XLogRecoveryShmemSize());
size = add_size(size, TwoPhaseShmemSize());
size = add_size(size, BackgroundWorkerShmemSize());
size = add_size(size, BackendStatusShmemSize());
size = add_size(size, CheckpointerShmemSize());
size = add_size(size, AutoVacuumShmemSize());
size = add_size(size, ReplicationSlotsShmemSize());
size = add_size(size, ReplicationOriginShmemSize());
size = add_size(size, WalSndShmemSize());
size = add_size(size, WalRcvShmemSize());
size = add_size(size, WalSummarizerShmemSize());
size = add_size(size, PgArchShmemSize());
size = add_size(size, ApplyLauncherShmemSize());
size = add_size(size, BTreeShmemSize());
size = add_size(size, SyncScanShmemSize());
size = add_size(size, StatsShmemSize());
size = add_size(size, WaitEventCustomShmemSize());
size = add_size(size, InjectionPointShmemSize());
size = add_size(size, SlotSyncShmemSize());
size = add_size(size, WaitLSNShmemSize());
size = add_size(size, LogicalDecodingCtlShmemSize());
size = add_size(size, DataChecksumsShmemSize());
/* include additional requested shmem from preload libraries */
size = add_size(size, total_addin_request);
@ -157,7 +103,6 @@ AttachSharedMemoryStructs(void)
/* Establish pointers to all shared memory areas in this backend */
ShmemAttachRequested();
CreateOrAttachShmemStructs();
/*
* Now give loadable modules a chance to set up their shmem allocations
@ -204,9 +149,6 @@ CreateSharedMemoryAndSemaphores(void)
/* Initialize all shmem areas */
ShmemInitRequested();
/* Initialize legacy subsystems */
CreateOrAttachShmemStructs();
/* Initialize dynamic shared memory facilities. */
dsm_postmaster_startup(shim);
@ -237,70 +179,6 @@ RegisterBuiltinShmemCallbacks(void)
#undef PG_SHMEM_SUBSYSTEM
}
/*
* Initialize various subsystems, setting up their data structures in
* shared memory.
*
* This is called by the postmaster or by a standalone backend.
* It is also called by a backend forked from the postmaster in the
* EXEC_BACKEND case. In the latter case, the shared memory segment
* already exists and has been physically attached to, but we have to
* initialize pointers in local memory that reference the shared structures,
* because we didn't inherit the correct pointer values from the postmaster
* as we do in the fork() scenario. The easiest way to do that is to run
* through the same code as before. (Note that the called routines mostly
* check IsUnderPostmaster, rather than EXEC_BACKEND, to detect this case.
* This is a bit code-wasteful and could be cleaned up.)
*/
static void
CreateOrAttachShmemStructs(void)
{
/*
* Set up xlog, clog, and buffers
*/
XLOGShmemInit();
XLogPrefetchShmemInit();
XLogRecoveryShmemInit();
/*
* Set up lock manager
*/
LockManagerShmemInit();
/*
* Set up process table
*/
BackendStatusShmemInit();
TwoPhaseShmemInit();
BackgroundWorkerShmemInit();
/*
* Set up interprocess signaling mechanisms
*/
CheckpointerShmemInit();
AutoVacuumShmemInit();
ReplicationSlotsShmemInit();
ReplicationOriginShmemInit();
WalSndShmemInit();
WalRcvShmemInit();
WalSummarizerShmemInit();
PgArchShmemInit();
ApplyLauncherShmemInit();
SlotSyncShmemInit();
DataChecksumsShmemInit();
/*
* Set up other modules that need some shared memory space
*/
BTreeShmemInit();
SyncScanShmemInit();
StatsShmemInit();
WaitEventCustomShmemInit();
InjectionPointShmemInit();
WaitLSNShmemInit();
LogicalDecodingCtlShmemInit();
}
/*
* InitializeShmemGUCs
*

View file

@ -43,8 +43,10 @@
#include "storage/lmgr.h"
#include "storage/proc.h"
#include "storage/procarray.h"
#include "storage/shmem.h"
#include "storage/spin.h"
#include "storage/standby.h"
#include "storage/subsystems.h"
#include "utils/memutils.h"
#include "utils/ps_status.h"
#include "utils/resowner.h"
@ -312,6 +314,14 @@ typedef struct
static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
static void LockManagerShmemRequest(void *arg);
static void LockManagerShmemInit(void *arg);
const ShmemCallbacks LockManagerShmemCallbacks = {
.request_fn = LockManagerShmemRequest,
.init_fn = LockManagerShmemInit,
};
/*
* Pointers to hash tables containing lock state
@ -432,21 +442,15 @@ static void GetSingleProcBlockerStatusData(PGPROC *blocked_proc,
/*
* Initialize the lock manager's shmem data structures.
* Register the lock manager's shmem data structures.
*
* This is called from CreateSharedMemoryAndSemaphores(), which see for more
* comments. In the normal postmaster case, the shared hash tables are
* created here, and backends inherit pointers to them via fork(). In the
* EXEC_BACKEND case, each backend re-executes this code to obtain pointers to
* the already existing shared hash tables. In either case, each backend must
* also call InitLockManagerAccess() to create the locallock hash table.
* In addition to this, each backend must also call InitLockManagerAccess() to
* create the locallock hash table.
*/
void
LockManagerShmemInit(void)
static void
LockManagerShmemRequest(void *arg)
{
HASHCTL info;
int64 max_table_size;
bool found;
/*
* Compute sizes for lock hashtables. Note that these calculations must
@ -455,45 +459,41 @@ LockManagerShmemInit(void)
max_table_size = NLOCKENTS();
/*
* Allocate hash table for LOCK structs. This stores per-locked-object
* Hash table for LOCK structs. This stores per-locked-object
* information.
*/
info.keysize = sizeof(LOCKTAG);
info.entrysize = sizeof(LOCK);
info.num_partitions = NUM_LOCK_PARTITIONS;
LockMethodLockHash = ShmemInitHash("LOCK hash",
max_table_size,
&info,
HASH_ELEM | HASH_BLOBS |
HASH_PARTITION | HASH_FIXED_SIZE);
ShmemRequestHash(.name = "LOCK hash",
.nelems = max_table_size,
.ptr = &LockMethodLockHash,
.hash_info.keysize = sizeof(LOCKTAG),
.hash_info.entrysize = sizeof(LOCK),
.hash_info.num_partitions = NUM_LOCK_PARTITIONS,
.hash_flags = HASH_ELEM | HASH_BLOBS | HASH_PARTITION,
);
/* Assume an average of 2 holders per lock */
max_table_size *= 2;
/*
* Allocate hash table for PROCLOCK structs. This stores
* per-lock-per-holder information.
*/
info.keysize = sizeof(PROCLOCKTAG);
info.entrysize = sizeof(PROCLOCK);
info.hash = proclock_hash;
info.num_partitions = NUM_LOCK_PARTITIONS;
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,
);
LockMethodProcLockHash = ShmemInitHash("PROCLOCK hash",
max_table_size,
&info,
HASH_ELEM | HASH_FUNCTION |
HASH_FIXED_SIZE | 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.

View 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;
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
);
/* 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));
#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);
BackendStatusArray[i].st_appname = buffer;
buffer += NAMEDATALEN;
}
/* Create or attach to the shared appname buffer */
size = mul_size(NAMEDATALEN, NumBackendStatSlots);
BackendAppnameBuffer = (char *)
ShmemInitStruct("Backend Application Name Buffer", size, &found);
if (!found)
/* Initialize st_clienthostname pointers. */
buffer = BackendClientHostnameBuffer;
for (i = 0; i < NumBackendStatSlots; i++)
{
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_clienthostname = 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_activity pointers. */
buffer = BackendActivityBuffer;
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;
}
}
/* 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)
{
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

View 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)
/*
* 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);
/*
* 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());
/*
* 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);
/* lift limit set above */
dsa_set_size_limit(dsa, -1);
/*
* Postmaster will never access these again, thus free the local
* dsa/dshash references.
*/
dshash_detach(dsh);
dsa_detach(dsa);
pg_atomic_init_u64(&ctl->gc_request_count, 1);
/* Do the per-kind initialization */
for (PgStat_Kind kind = PGSTAT_KIND_MIN; kind <= PGSTAT_KIND_MAX; kind++)
{
dsa_area *dsa;
dshash_table *dsh;
PgStat_ShmemControl *ctl = pgStatLocal.shmem;
char *p = (char *) ctl;
const PgStat_KindInfo *kind_info = pgstat_get_kind_info(kind);
char *ptr;
Assert(!found);
if (!kind_info)
continue;
/* the allocation of pgStatLocal.shmem itself */
p += MAXALIGN(sizeof(PgStat_ShmemControl));
/* initialize entry count tracking */
if (kind_info->track_entry_count)
pg_atomic_init_u64(&ctl->entry_counts[kind - 1], 0);
/*
* 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);
/*
* 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());
/*
* 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);
/* lift limit set above */
dsa_set_size_limit(dsa, -1);
/*
* Postmaster will never access these again, thus free the local
* dsa/dshash references.
*/
dshash_detach(dsh);
dsa_detach(dsa);
pg_atomic_init_u64(&ctl->gc_request_count, 1);
/* 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;
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);
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

View 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);
/*
* Return the space for dynamic shared hash tables and dynamic allocation counter.
*/
Size
WaitEventCustomShmemSize(void)
{
Size sz;
static void WaitEventCustomShmemRequest(void *arg);
static void WaitEventCustomShmemInit(void *arg);
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;
const ShmemCallbacks WaitEventCustomShmemCallbacks = {
.request_fn = WaitEventCustomShmemRequest,
.init_fn = WaitEventCustomShmemInit,
};
/*
* Register shmem space for dynamic shared hash and dynamic allocation counter.
*/
static void
WaitEventCustomShmemRequest(void *arg)
{
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);
}
/*

View 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,46 +232,35 @@ 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;
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
InjectionPointShmemRequest(void *arg)
{
ShmemRequestStruct(.name = "InjectionPoint hash",
.size = sizeof(InjectionPointsCtl),
.ptr = (void **) &ActiveInjectionPoints,
);
}
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.
*/

View 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,

View 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

View 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);

View 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);

View 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);

View 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);

View 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);

View 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);

View 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 */

View 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);

View 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 */

View file

@ -17,10 +17,6 @@
#include "storage/procsignal.h"
/* Shared memory */
extern Size DataChecksumsShmemSize(void);
extern void DataChecksumsShmemInit(void);
/* Possible operations the Datachecksumsworker can perform */
typedef enum DataChecksumsWorkerOperation
{

View 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);

View 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,

View 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);

View 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);

View 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 */

View 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,

View 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 */

View 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);

View 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);

View 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);

View 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)

View 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
* ----------

View 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,

View 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);
/* ----------

View 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);
}

View 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;
/* 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;
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;
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-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-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);
}