Size size;
size = offsetof(BTVacInfo, vacuums);
- size = add_size(size, mul_size(GetMaxBackends(), sizeof(BTOneVacInfo)));
+ size = add_size(size, mul_size(MaxBackends, sizeof(BTOneVacInfo)));
return size;
}
btvacinfo->cycle_ctr = (BTCycleId) time(NULL);
btvacinfo->num_vacuums = 0;
- btvacinfo->max_vacuums = GetMaxBackends();
+ btvacinfo->max_vacuums = MaxBackends;
}
else
Assert(found);
} MultiXactStateData;
/*
- * Pointers to the state data in shared memory
- *
- * The index of the last element of the OldestMemberMXactId and
- * OldestVisibleMXactId arrays can be obtained with GetMaxOldestSlot().
+ * Last element of OldestMemberMXactId and OldestVisibleMXactId arrays.
+ * Valid elements are (1..MaxOldestSlot); element 0 is never used.
*/
+#define MaxOldestSlot (MaxBackends + max_prepared_xacts)
+
+/* Pointers to the state data in shared memory */
static MultiXactStateData *MultiXactState;
static MultiXactId *OldestMemberMXactId;
static MultiXactId *OldestVisibleMXactId;
static void RecordNewMultiXact(MultiXactId multi, MultiXactOffset offset,
int nmembers, MultiXactMember *members);
static MultiXactId GetNewMultiXactId(int nmembers, MultiXactOffset *offset);
-static inline int GetMaxOldestSlot(void);
/* MultiXact cache management */
static int mxactMemberComparator(const void *arg1, const void *arg2);
}
}
-/*
- * Retrieve the index of the last element of the OldestMemberMXactId and
- * OldestVisibleMXactId arrays. Valid elements are (1..MaxOldestSlot); element
- * 0 is never used.
- */
-static inline int
-GetMaxOldestSlot(void)
-{
- return GetMaxBackends() + max_prepared_xacts;
-}
-
/*
* MultiXactIdSetOldestVisible
* Save the oldest MultiXactId this transaction considers possibly live.
if (!MultiXactIdIsValid(OldestVisibleMXactId[MyBackendId]))
{
MultiXactId oldestMXact;
- int maxOldestSlot = GetMaxOldestSlot();
int i;
LWLockAcquire(MultiXactGenLock, LW_EXCLUSIVE);
if (oldestMXact < FirstMultiXactId)
oldestMXact = FirstMultiXactId;
- for (i = 1; i <= maxOldestSlot; i++)
+ for (i = 1; i <= MaxOldestSlot; i++)
{
MultiXactId thisoldest = OldestMemberMXactId[i];
/* We need 2*MaxOldestSlot + 1 perBackendXactIds[] entries */
#define SHARED_MULTIXACT_STATE_SIZE \
add_size(offsetof(MultiXactStateData, perBackendXactIds) + sizeof(MultiXactId), \
- mul_size(sizeof(MultiXactId) * 2, GetMaxOldestSlot()))
+ mul_size(sizeof(MultiXactId) * 2, MaxOldestSlot))
size = SHARED_MULTIXACT_STATE_SIZE;
size = add_size(size, SimpleLruShmemSize(NUM_MULTIXACTOFFSET_BUFFERS, 0));
* since we only use indexes 1..MaxOldestSlot in each array.
*/
OldestMemberMXactId = MultiXactState->perBackendXactIds;
- OldestVisibleMXactId = OldestMemberMXactId + GetMaxOldestSlot();
+ OldestVisibleMXactId = OldestMemberMXactId + MaxOldestSlot;
}
/*
{
MultiXactId oldestMXact;
MultiXactId nextMXact;
- int maxOldestSlot = GetMaxOldestSlot();
int i;
/*
nextMXact = FirstMultiXactId;
oldestMXact = nextMXact;
- for (i = 1; i <= maxOldestSlot; i++)
+ for (i = 1; i <= MaxOldestSlot; i++)
{
MultiXactId thisoldest;
{
GlobalTransaction gxacts;
int i;
- int max_backends = GetMaxBackends();
Assert(!found);
TwoPhaseState->freeGXacts = NULL;
* prepared transaction. Currently multixact.c uses that
* technique.
*/
- gxacts[i].dummyBackendId = max_backends + 1 + i;
+ gxacts[i].dummyBackendId = MaxBackends + 1 + i;
}
}
else
Size size;
/* This had better match AsyncShmemInit */
- size = mul_size(GetMaxBackends() + 1, sizeof(QueueBackendStatus));
+ size = mul_size(MaxBackends + 1, sizeof(QueueBackendStatus));
size = add_size(size, offsetof(AsyncQueueControl, backend));
size = add_size(size, SimpleLruShmemSize(NUM_NOTIFY_BUFFERS, 0));
{
bool found;
Size size;
- int max_backends = GetMaxBackends();
/*
* Create or attach to the AsyncQueueControl structure.
* The used entries in the backend[] array run from 1 to MaxBackends; the
* zero'th entry is unused but must be allocated.
*/
- size = mul_size(max_backends + 1, sizeof(QueueBackendStatus));
+ size = mul_size(MaxBackends + 1, sizeof(QueueBackendStatus));
size = add_size(size, offsetof(AsyncQueueControl, backend));
asyncQueueControl = (AsyncQueueControl *)
QUEUE_FIRST_LISTENER = InvalidBackendId;
asyncQueueControl->lastQueueFillWarn = 0;
/* zero'th entry won't be used, but let's initialize it anyway */
- for (int i = 0; i <= max_backends; i++)
+ for (int i = 0; i <= MaxBackends; i++)
{
QUEUE_BACKEND_PID(i) = InvalidPid;
QUEUE_BACKEND_DBOID(i) = InvalidOid;
int32 *pids;
BackendId *ids;
int count;
- int max_backends = GetMaxBackends();
/*
* Identify backends that we need to signal. We don't want to send
* XXX in principle these pallocs could fail, which would be bad. Maybe
* preallocate the arrays? They're not that large, though.
*/
- pids = (int32 *) palloc(max_backends * sizeof(int32));
- ids = (BackendId *) palloc(max_backends * sizeof(BackendId));
+ pids = (int32 *) palloc(MaxBackends * sizeof(int32));
+ ids = (BackendId *) palloc(MaxBackends * sizeof(BackendId));
count = 0;
LWLockAcquire(NotifyQueueLock, LW_EXCLUSIVE);
struct addrinfo hint;
int listen_index = 0;
int added = 0;
- int max_backends = GetMaxBackends();
#ifdef HAVE_UNIX_SOCKETS
char unixSocketPath[MAXPGPATH];
* intended to provide a clamp on the request on platforms where an
* overly large request provokes a kernel error (are there any?).
*/
- maxconn = max_backends * 2;
+ maxconn = MaxBackends * 2;
if (maxconn > PG_SOMAXCONN)
maxconn = PG_SOMAXCONN;
* This will need rethinking if we ever want more than one of a particular
* auxiliary process type.
*/
- ProcSignalInit(GetMaxBackends() + MyAuxProcType + 1);
+ ProcSignalInit(MaxBackends + MyAuxProcType + 1);
/*
* Auxiliary processes don't run transactions, but they may need a
LocalProcessControlFile(false);
/*
- * Register the apply launcher. It's probably a good idea to call this
- * before any modules had a chance to take the background worker slots.
+ * Register the apply launcher. Since it registers a background worker,
+ * it needs to be called before InitializeMaxBackends(), and it's probably
+ * a good idea to call it before any modules had chance to take the
+ * background worker slots.
*/
ApplyLauncherRegister();
#endif
/*
- * Now that loadable modules have had their chance to alter any GUCs,
- * calculate MaxBackends.
+ * Now that loadable modules have had their chance to register background
+ * workers, calculate MaxBackends.
*/
InitializeMaxBackends();
param->query_id_enabled = query_id_enabled;
param->max_safe_fds = max_safe_fds;
- param->MaxBackends = GetMaxBackends();
+ param->MaxBackends = MaxBackends;
#ifdef WIN32
param->PostmasterHandle = PostmasterHandle;
query_id_enabled = param->query_id_enabled;
max_safe_fds = param->max_safe_fds;
- SetMaxBackends(param->MaxBackends);
+ MaxBackends = param->MaxBackends;
#ifdef WIN32
PostmasterHandle = param->PostmasterHandle;
/* Determine size for new control segment. */
maxitems = PG_DYNSHMEM_FIXED_SLOTS
- + PG_DYNSHMEM_SLOTS_PER_BACKEND * GetMaxBackends();
+ + PG_DYNSHMEM_SLOTS_PER_BACKEND * MaxBackends;
elog(DEBUG2, "dynamic shared memory system will support %u segments",
maxitems);
segsize = dsm_control_bytes_needed(maxitems);
/* oldest catalog xmin of any replication slot */
TransactionId replication_slot_catalog_xmin;
- /* indexes into allProcs[], has ProcArrayMaxProcs entries */
+ /* indexes into allProcs[], has PROCARRAY_MAXPROCS entries */
int pgprocnos[FLEXIBLE_ARRAY_MEMBER];
} ProcArrayStruct;
static inline FullTransactionId FullXidRelativeTo(FullTransactionId rel,
TransactionId xid);
static void GlobalVisUpdateApply(ComputeXidHorizonsResult *horizons);
-static inline int GetProcArrayMaxProcs(void);
-
-
-/*
- * Retrieve the number of slots in the ProcArray structure.
- */
-static inline int
-GetProcArrayMaxProcs(void)
-{
- return GetMaxBackends() + max_prepared_xacts;
-}
/*
* Report shared-memory space needed by CreateSharedProcArray.
Size size;
/* Size of the ProcArray structure itself */
+#define PROCARRAY_MAXPROCS (MaxBackends + max_prepared_xacts)
+
size = offsetof(ProcArrayStruct, pgprocnos);
- size = add_size(size, mul_size(sizeof(int), GetProcArrayMaxProcs()));
+ size = add_size(size, mul_size(sizeof(int), PROCARRAY_MAXPROCS));
/*
* During Hot Standby processing we have a data structure called
* shared memory is being set up.
*/
#define TOTAL_MAX_CACHED_SUBXIDS \
- ((PGPROC_MAX_CACHED_SUBXIDS + 1) * GetProcArrayMaxProcs())
+ ((PGPROC_MAX_CACHED_SUBXIDS + 1) * PROCARRAY_MAXPROCS)
if (EnableHotStandby)
{
ShmemInitStruct("Proc Array",
add_size(offsetof(ProcArrayStruct, pgprocnos),
mul_size(sizeof(int),
- GetProcArrayMaxProcs())),
+ PROCARRAY_MAXPROCS)),
&found);
if (!found)
* We're the first - initialize.
*/
procArray->numProcs = 0;
- procArray->maxProcs = GetProcArrayMaxProcs();
+ procArray->maxProcs = PROCARRAY_MAXPROCS;
procArray->maxKnownAssignedXids = TOTAL_MAX_CACHED_SUBXIDS;
procArray->numKnownAssignedXids = 0;
procArray->tailKnownAssignedXids = 0;
*/
int nelements = head - tail;
- if (nelements < 4 * GetProcArrayMaxProcs() ||
+ if (nelements < 4 * PROCARRAY_MAXPROCS ||
nelements < 2 * pArray->numKnownAssignedXids)
return;
}
ProcSignalSlot psh_slot[FLEXIBLE_ARRAY_MEMBER];
} ProcSignalHeader;
+/*
+ * We reserve a slot for each possible BackendId, plus one for each
+ * possible auxiliary process type. (This scheme assumes there is not
+ * more than one of any auxiliary process type at a time.)
+ */
+#define NumProcSignalSlots (MaxBackends + NUM_AUXPROCTYPES)
+
/* Check whether the relevant type bit is set in the flags. */
#define BARRIER_SHOULD_CHECK(flags, type) \
(((flags) & (((uint32) 1) << (uint32) (type))) != 0)
static bool CheckProcSignal(ProcSignalReason reason);
static void CleanupProcSignalState(int status, Datum arg);
static void ResetProcSignalBarrierBits(uint32 flags);
-static inline int GetNumProcSignalSlots(void);
-
-/*
- * GetNumProcSignalSlots
- *
- * We reserve a slot for each possible BackendId, plus one for each possible
- * auxiliary process type. (This scheme assume there is not more than one of
- * any auxiliary process type at a time.)
- */
-static inline int
-GetNumProcSignalSlots(void)
-{
- return GetMaxBackends() + NUM_AUXPROCTYPES;
-}
/*
* ProcSignalShmemSize
{
Size size;
- size = mul_size(GetNumProcSignalSlots(), sizeof(ProcSignalSlot));
+ size = mul_size(NumProcSignalSlots, sizeof(ProcSignalSlot));
size = add_size(size, offsetof(ProcSignalHeader, psh_slot));
return size;
}
{
Size size = ProcSignalShmemSize();
bool found;
- int numProcSignalSlots = GetNumProcSignalSlots();
ProcSignal = (ProcSignalHeader *)
ShmemInitStruct("ProcSignal", size, &found);
pg_atomic_init_u64(&ProcSignal->psh_barrierGeneration, 0);
- for (i = 0; i < numProcSignalSlots; ++i)
+ for (i = 0; i < NumProcSignalSlots; ++i)
{
ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
ProcSignalSlot *slot;
uint64 barrier_generation;
- Assert(pss_idx >= 1 && pss_idx <= GetNumProcSignalSlots());
+ Assert(pss_idx >= 1 && pss_idx <= NumProcSignalSlots);
slot = &ProcSignal->psh_slot[pss_idx - 1];
*/
int i;
- for (i = GetNumProcSignalSlots() - 1; i >= 0; i--)
+ for (i = NumProcSignalSlots - 1; i >= 0; i--)
{
slot = &ProcSignal->psh_slot[i];
{
uint32 flagbit = 1 << (uint32) type;
uint64 generation;
- int numProcSignalSlots = GetNumProcSignalSlots();
/*
* Set all the flags.
* anything that we do afterwards. (This is also true of the later call to
* pg_atomic_add_fetch_u64.)
*/
- for (int i = 0; i < numProcSignalSlots; i++)
+ for (int i = 0; i < NumProcSignalSlots; i++)
{
volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
* backends that need to update state - but they won't actually need to
* change any state.
*/
- for (int i = numProcSignalSlots - 1; i >= 0; i--)
+ for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
pid_t pid = slot->pss_pid;
{
Assert(generation <= pg_atomic_read_u64(&ProcSignal->psh_barrierGeneration));
- for (int i = GetNumProcSignalSlots() - 1; i >= 0; i--)
+ for (int i = NumProcSignalSlots - 1; i >= 0; i--)
{
ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
uint64 oldval;
* free slot. This is because the autovacuum launcher and worker processes,
* which are included in MaxBackends, are not started in Hot Standby mode.
*/
- size = add_size(size, mul_size(sizeof(ProcState), GetMaxBackends()));
+ size = add_size(size, mul_size(sizeof(ProcState), MaxBackends));
return size;
}
shmInvalBuffer->maxMsgNum = 0;
shmInvalBuffer->nextThreshold = CLEANUP_MIN;
shmInvalBuffer->lastBackend = 0;
- shmInvalBuffer->maxBackends = GetMaxBackends();
+ shmInvalBuffer->maxBackends = MaxBackends;
SpinLockInit(&shmInvalBuffer->msgnumLock);
/* The buffer[] array is initially all unused, so we need not fill it */
InitDeadLockChecking(void)
{
MemoryContext oldcxt;
- int max_backends = GetMaxBackends();
/* Make sure allocations are permanent */
oldcxt = MemoryContextSwitchTo(TopMemoryContext);
* FindLockCycle needs at most MaxBackends entries in visitedProcs[] and
* deadlockDetails[].
*/
- visitedProcs = (PGPROC **) palloc(max_backends * sizeof(PGPROC *));
- deadlockDetails = (DEADLOCK_INFO *) palloc(max_backends * sizeof(DEADLOCK_INFO));
+ visitedProcs = (PGPROC **) palloc(MaxBackends * sizeof(PGPROC *));
+ deadlockDetails = (DEADLOCK_INFO *) palloc(MaxBackends * sizeof(DEADLOCK_INFO));
/*
* TopoSort needs to consider at most MaxBackends wait-queue entries, and
* it needn't run concurrently with FindLockCycle.
*/
topoProcs = visitedProcs; /* re-use this space */
- beforeConstraints = (int *) palloc(max_backends * sizeof(int));
- afterConstraints = (int *) palloc(max_backends * sizeof(int));
+ beforeConstraints = (int *) palloc(MaxBackends * sizeof(int));
+ afterConstraints = (int *) palloc(MaxBackends * sizeof(int));
/*
* We need to consider rearranging at most MaxBackends/2 wait queues
* MaxBackends total waiters.
*/
waitOrders = (WAIT_ORDER *)
- palloc((max_backends / 2) * sizeof(WAIT_ORDER));
- waitOrderProcs = (PGPROC **) palloc(max_backends * sizeof(PGPROC *));
+ palloc((MaxBackends / 2) * sizeof(WAIT_ORDER));
+ waitOrderProcs = (PGPROC **) palloc(MaxBackends * sizeof(PGPROC *));
/*
* Allow at most MaxBackends distinct constraints in a configuration. (Is
* limits the maximum recursion depth of DeadLockCheckRecurse. Making it
* really big might potentially allow a stack-overflow problem.
*/
- maxCurConstraints = max_backends;
+ maxCurConstraints = MaxBackends;
curConstraints = (EDGE *) palloc(maxCurConstraints * sizeof(EDGE));
/*
* last MaxBackends entries in possibleConstraints[] are reserved as
* output workspace for FindLockCycle.
*/
- maxPossibleConstraints = max_backends * 4;
+ maxPossibleConstraints = MaxBackends * 4;
possibleConstraints =
(EDGE *) palloc(maxPossibleConstraints * sizeof(EDGE));
if (nCurConstraints >= maxCurConstraints)
return true; /* out of room for active constraints? */
oldPossibleConstraints = nPossibleConstraints;
- if (nPossibleConstraints + nEdges + GetMaxBackends() <= maxPossibleConstraints)
+ if (nPossibleConstraints + nEdges + MaxBackends <= maxPossibleConstraints)
{
/* We can save the edge list in possibleConstraints[] */
nPossibleConstraints += nEdges;
/*
* Make sure we have room for FindLockCycle's output.
*/
- if (nPossibleConstraints + GetMaxBackends() > maxPossibleConstraints)
+ if (nPossibleConstraints + MaxBackends > maxPossibleConstraints)
return -1;
/*
* record total length of cycle --- outer levels will now fill
* deadlockDetails[]
*/
- Assert(depth <= GetMaxBackends());
+ Assert(depth <= MaxBackends);
nDeadlockDetails = depth;
return true;
}
}
/* Mark proc as seen */
- Assert(nVisitedProcs < GetMaxBackends());
+ Assert(nVisitedProcs < MaxBackends);
visitedProcs[nVisitedProcs++] = checkProc;
/*
/*
* Add this edge to the list of soft edges in the cycle
*/
- Assert(*nSoftEdges < GetMaxBackends());
+ Assert(*nSoftEdges < MaxBackends);
softEdges[*nSoftEdges].waiter = checkProcLeader;
softEdges[*nSoftEdges].blocker = leader;
softEdges[*nSoftEdges].lock = lock;
/*
* Add this edge to the list of soft edges in the cycle
*/
- Assert(*nSoftEdges < GetMaxBackends());
+ Assert(*nSoftEdges < MaxBackends);
softEdges[*nSoftEdges].waiter = checkProcLeader;
softEdges[*nSoftEdges].blocker = leader;
softEdges[*nSoftEdges].lock = lock;
waitOrders[nWaitOrders].procs = waitOrderProcs + nWaitOrderProcs;
waitOrders[nWaitOrders].nProcs = lock->waitProcs.size;
nWaitOrderProcs += lock->waitProcs.size;
- Assert(nWaitOrderProcs <= GetMaxBackends());
+ Assert(nWaitOrderProcs <= MaxBackends);
/*
* Do the topo sort. TopoSort need not examine constraints after this
int max_locks_per_xact; /* set by guc.c */
#define NLOCKENTS() \
- mul_size(max_locks_per_xact, add_size(GetMaxBackends(), max_prepared_xacts))
+ mul_size(max_locks_per_xact, add_size(MaxBackends, max_prepared_xacts))
/*
LWLock *partitionLock;
int count = 0;
int fast_count = 0;
- int max_backends = GetMaxBackends();
if (lockmethodid <= 0 || lockmethodid >= lengthof(LockMethods))
elog(ERROR, "unrecognized lock method: %d", lockmethodid);
vxids = (VirtualTransactionId *)
MemoryContextAlloc(TopMemoryContext,
sizeof(VirtualTransactionId) *
- (max_backends + max_prepared_xacts + 1));
+ (MaxBackends + max_prepared_xacts + 1));
}
else
vxids = (VirtualTransactionId *)
palloc0(sizeof(VirtualTransactionId) *
- (max_backends + max_prepared_xacts + 1));
+ (MaxBackends + max_prepared_xacts + 1));
/* Compute hash code and partition lock, and look up conflicting modes. */
hashcode = LockTagHashCode(locktag);
LWLockRelease(partitionLock);
- if (count > max_backends + max_prepared_xacts) /* should never happen */
+ if (count > MaxBackends + max_prepared_xacts) /* should never happen */
elog(PANIC, "too many conflicting locks found");
vxids[count].backendId = InvalidBackendId;
int els;
int el;
int i;
- int max_backends = GetMaxBackends();
data = (LockData *) palloc(sizeof(LockData));
/* Guess how much space we'll need. */
- els = max_backends;
+ els = MaxBackends;
el = 0;
data->locks = (LockInstanceData *) palloc(sizeof(LockInstanceData) * els);
if (el >= els)
{
- els += max_backends;
+ els += MaxBackends;
data->locks = (LockInstanceData *)
repalloc(data->locks, sizeof(LockInstanceData) * els);
}
if (el >= els)
{
- els += max_backends;
+ els += MaxBackends;
data->locks = (LockInstanceData *)
repalloc(data->locks, sizeof(LockInstanceData) * els);
}
* for the procs[] array; the other two could need enlargement, though.)
*/
data->nprocs = data->nlocks = data->npids = 0;
- data->maxprocs = data->maxlocks = data->maxpids = GetMaxBackends();
+ data->maxprocs = data->maxlocks = data->maxpids = MaxBackends;
data->procs = (BlockedProcData *) palloc(sizeof(BlockedProcData) * data->maxprocs);
data->locks = (LockInstanceData *) palloc(sizeof(LockInstanceData) * data->maxlocks);
data->waiter_pids = (int *) palloc(sizeof(int) * data->maxpids);
PGPROC *proc;
int queue_size;
int i;
- int max_backends = GetMaxBackends();
/* Nothing to do if this proc is not blocked */
if (theLock == NULL)
if (data->nlocks >= data->maxlocks)
{
- data->maxlocks += max_backends;
+ data->maxlocks += MaxBackends;
data->locks = (LockInstanceData *)
repalloc(data->locks, sizeof(LockInstanceData) * data->maxlocks);
}
if (queue_size > data->maxpids - data->npids)
{
- data->maxpids = Max(data->maxpids + max_backends,
+ data->maxpids = Max(data->maxpids + MaxBackends,
data->npids + queue_size);
data->waiter_pids = (int *) repalloc(data->waiter_pids,
sizeof(int) * data->maxpids);
(&MainLWLockArray[PREDICATELOCK_MANAGER_LWLOCK_OFFSET + (i)].lock)
#define NPREDICATELOCKTARGETENTS() \
- mul_size(max_predicate_locks_per_xact, add_size(GetMaxBackends(), max_prepared_xacts))
+ mul_size(max_predicate_locks_per_xact, add_size(MaxBackends, max_prepared_xacts))
#define SxactIsOnFinishedList(sxact) (!SHMQueueIsDetached(&((sxact)->finishedLink)))
* Compute size for serializable transaction hashtable. Note these
* calculations must agree with PredicateLockShmemSize!
*/
- max_table_size = (GetMaxBackends() + max_prepared_xacts);
+ max_table_size = (MaxBackends + max_prepared_xacts);
/*
* Allocate a list to hold information on transactions participating in
size = add_size(size, size / 10);
/* transaction list */
- max_table_size = GetMaxBackends() + max_prepared_xacts;
+ max_table_size = MaxBackends + max_prepared_xacts;
max_table_size *= 10;
size = add_size(size, PredXactListDataSize);
size = add_size(size, mul_size((Size) max_table_size,
{
++(PredXact->WritableSxactCount);
Assert(PredXact->WritableSxactCount <=
- (GetMaxBackends() + max_prepared_xacts));
+ (MaxBackends + max_prepared_xacts));
}
MySerializableXact = sxact;
{
++(PredXact->WritableSxactCount);
Assert(PredXact->WritableSxactCount <=
- (GetMaxBackends() + max_prepared_xacts));
+ (MaxBackends + max_prepared_xacts));
}
/*
{
Size size = 0;
Size TotalProcs =
- add_size(GetMaxBackends(), add_size(NUM_AUXILIARY_PROCS, max_prepared_xacts));
+ add_size(MaxBackends, add_size(NUM_AUXILIARY_PROCS, max_prepared_xacts));
/* ProcGlobal */
size = add_size(size, sizeof(PROC_HDR));
* We need a sema per backend (including autovacuum), plus one for each
* auxiliary process.
*/
- return GetMaxBackends() + NUM_AUXILIARY_PROCS;
+ return MaxBackends + NUM_AUXILIARY_PROCS;
}
/*
int i,
j;
bool found;
- int max_backends = GetMaxBackends();
- uint32 TotalProcs = max_backends + NUM_AUXILIARY_PROCS + max_prepared_xacts;
+ uint32 TotalProcs = MaxBackends + NUM_AUXILIARY_PROCS + max_prepared_xacts;
/* Create the ProcGlobal shared structure */
ProcGlobal = (PROC_HDR *)
MemSet(procs, 0, TotalProcs * sizeof(PGPROC));
ProcGlobal->allProcs = procs;
/* XXX allProcCount isn't really all of them; it excludes prepared xacts */
- ProcGlobal->allProcCount = max_backends + NUM_AUXILIARY_PROCS;
+ ProcGlobal->allProcCount = MaxBackends + NUM_AUXILIARY_PROCS;
/*
* Allocate arrays mirroring PGPROC fields in a dense manner. See
* dummy PGPROCs don't need these though - they're never associated
* with a real process
*/
- if (i < max_backends + NUM_AUXILIARY_PROCS)
+ if (i < MaxBackends + NUM_AUXILIARY_PROCS)
{
procs[i].sem = PGSemaphoreCreate();
InitSharedLatch(&(procs[i].procLatch));
ProcGlobal->bgworkerFreeProcs = &procs[i];
procs[i].procgloballist = &ProcGlobal->bgworkerFreeProcs;
}
- else if (i < max_backends)
+ else if (i < MaxBackends)
{
/* PGPROC for walsender, add to walsenderFreeProcs list */
procs[i].links.next = (SHM_QUEUE *) ProcGlobal->walsenderFreeProcs;
* Save pointers to the blocks of PGPROC structures reserved for auxiliary
* processes and prepared transactions.
*/
- AuxiliaryProcs = &procs[max_backends];
- PreparedXactProcs = &procs[max_backends + NUM_AUXILIARY_PROCS];
+ AuxiliaryProcs = &procs[MaxBackends];
+ PreparedXactProcs = &procs[MaxBackends + NUM_AUXILIARY_PROCS];
/* Create ProcStructLock spinlock, too */
ProcStructLock = (slock_t *) ShmemAlloc(sizeof(slock_t));
#include "utils/memutils.h"
+/* ----------
+ * Total number of backends including auxiliary
+ *
+ * We reserve a slot for each possible BackendId, plus one for each
+ * possible auxiliary process type. (This scheme assumes there is not
+ * more than one of any auxiliary process type at a time.) MaxBackends
+ * includes autovacuum workers and background workers as well.
+ * ----------
+ */
+#define NumBackendStatSlots (MaxBackends + NUM_AUXPROCTYPES)
+
+
/* ----------
* GUC parameters
* ----------
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 inline int GetNumBackendStatSlots(void);
-/*
- * Retrieve the total number of backends including auxiliary
- *
- * We reserve a slot for each possible BackendId, plus one for each possible
- * auxiliary process type. (This scheme assumes there is not more than one of
- * any auxiliary process type at a time.) MaxBackends includes autovacuum
- * workers and background workers as well.
- */
-static inline int
-GetNumBackendStatSlots(void)
-{
- return GetMaxBackends() + NUM_AUXPROCTYPES;
-}
-
/*
* Report shared-memory space needed by CreateSharedBackendStatus.
*/
BackendStatusShmemSize(void)
{
Size size;
- int numBackendStatSlots = GetNumBackendStatSlots();
/* BackendStatusArray: */
- size = mul_size(sizeof(PgBackendStatus), numBackendStatSlots);
+ size = mul_size(sizeof(PgBackendStatus), NumBackendStatSlots);
/* BackendAppnameBuffer: */
size = add_size(size,
- mul_size(NAMEDATALEN, numBackendStatSlots));
+ mul_size(NAMEDATALEN, NumBackendStatSlots));
/* BackendClientHostnameBuffer: */
size = add_size(size,
- mul_size(NAMEDATALEN, numBackendStatSlots));
+ mul_size(NAMEDATALEN, NumBackendStatSlots));
/* BackendActivityBuffer: */
size = add_size(size,
- mul_size(pgstat_track_activity_query_size, numBackendStatSlots));
+ mul_size(pgstat_track_activity_query_size, NumBackendStatSlots));
#ifdef USE_SSL
/* BackendSslStatusBuffer: */
size = add_size(size,
- mul_size(sizeof(PgBackendSSLStatus), numBackendStatSlots));
+ mul_size(sizeof(PgBackendSSLStatus), NumBackendStatSlots));
#endif
#ifdef ENABLE_GSS
/* BackendGssStatusBuffer: */
size = add_size(size,
- mul_size(sizeof(PgBackendGSSStatus), numBackendStatSlots));
+ mul_size(sizeof(PgBackendGSSStatus), NumBackendStatSlots));
#endif
return size;
}
bool found;
int i;
char *buffer;
- int numBackendStatSlots = GetNumBackendStatSlots();
/* Create or attach to the shared array */
- size = mul_size(sizeof(PgBackendStatus), numBackendStatSlots);
+ size = mul_size(sizeof(PgBackendStatus), NumBackendStatSlots);
BackendStatusArray = (PgBackendStatus *)
ShmemInitStruct("Backend Status Array", size, &found);
}
/* Create or attach to the shared appname buffer */
- size = mul_size(NAMEDATALEN, numBackendStatSlots);
+ size = mul_size(NAMEDATALEN, NumBackendStatSlots);
BackendAppnameBuffer = (char *)
ShmemInitStruct("Backend Application Name Buffer", size, &found);
/* Initialize st_appname pointers. */
buffer = BackendAppnameBuffer;
- for (i = 0; i < numBackendStatSlots; i++)
+ for (i = 0; i < NumBackendStatSlots; i++)
{
BackendStatusArray[i].st_appname = buffer;
buffer += NAMEDATALEN;
}
/* Create or attach to the shared client hostname buffer */
- size = mul_size(NAMEDATALEN, numBackendStatSlots);
+ size = mul_size(NAMEDATALEN, NumBackendStatSlots);
BackendClientHostnameBuffer = (char *)
ShmemInitStruct("Backend Client Host Name Buffer", size, &found);
/* Initialize st_clienthostname pointers. */
buffer = BackendClientHostnameBuffer;
- for (i = 0; i < numBackendStatSlots; i++)
+ 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);
+ NumBackendStatSlots);
BackendActivityBuffer = (char *)
ShmemInitStruct("Backend Activity Buffer",
BackendActivityBufferSize,
/* Initialize st_activity pointers. */
buffer = BackendActivityBuffer;
- for (i = 0; i < numBackendStatSlots; i++)
+ for (i = 0; i < NumBackendStatSlots; i++)
{
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);
+ size = mul_size(sizeof(PgBackendSSLStatus), NumBackendStatSlots);
BackendSslStatusBuffer = (PgBackendSSLStatus *)
ShmemInitStruct("Backend SSL Status Buffer", size, &found);
/* Initialize st_sslstatus pointers. */
ptr = BackendSslStatusBuffer;
- for (i = 0; i < numBackendStatSlots; i++)
+ for (i = 0; i < NumBackendStatSlots; i++)
{
BackendStatusArray[i].st_sslstatus = ptr;
ptr++;
#ifdef ENABLE_GSS
/* Create or attach to the shared GSSAPI status buffer */
- size = mul_size(sizeof(PgBackendGSSStatus), numBackendStatSlots);
+ size = mul_size(sizeof(PgBackendGSSStatus), NumBackendStatSlots);
BackendGssStatusBuffer = (PgBackendGSSStatus *)
ShmemInitStruct("Backend GSS Status Buffer", size, &found);
/* Initialize st_gssstatus pointers. */
ptr = BackendGssStatusBuffer;
- for (i = 0; i < numBackendStatSlots; i++)
+ for (i = 0; i < NumBackendStatSlots; i++)
{
BackendStatusArray[i].st_gssstatus = ptr;
ptr++;
/* Initialize MyBEEntry */
if (MyBackendId != InvalidBackendId)
{
- Assert(MyBackendId >= 1 && MyBackendId <= GetMaxBackends());
+ Assert(MyBackendId >= 1 && MyBackendId <= MaxBackends);
MyBEEntry = &BackendStatusArray[MyBackendId - 1];
}
else
* MaxBackends + AuxBackendType + 1 as the index of the slot for an
* auxiliary process.
*/
- MyBEEntry = &BackendStatusArray[GetMaxBackends() + MyAuxProcType];
+ MyBEEntry = &BackendStatusArray[MaxBackends + MyAuxProcType];
}
/* Set up a process-exit hook to clean up */
PgBackendGSSStatus *localgssstatus;
#endif
int i;
- int numBackendStatSlots = GetNumBackendStatSlots();
if (localBackendStatusTable)
return; /* already done */
*/
localtable = (LocalPgBackendStatus *)
MemoryContextAlloc(backendStatusSnapContext,
- sizeof(LocalPgBackendStatus) * numBackendStatSlots);
+ sizeof(LocalPgBackendStatus) * NumBackendStatSlots);
localappname = (char *)
MemoryContextAlloc(backendStatusSnapContext,
- NAMEDATALEN * numBackendStatSlots);
+ NAMEDATALEN * NumBackendStatSlots);
localclienthostname = (char *)
MemoryContextAlloc(backendStatusSnapContext,
- NAMEDATALEN * numBackendStatSlots);
+ NAMEDATALEN * NumBackendStatSlots);
localactivity = (char *)
MemoryContextAllocHuge(backendStatusSnapContext,
- pgstat_track_activity_query_size * numBackendStatSlots);
+ pgstat_track_activity_query_size * NumBackendStatSlots);
#ifdef USE_SSL
localsslstatus = (PgBackendSSLStatus *)
MemoryContextAlloc(backendStatusSnapContext,
- sizeof(PgBackendSSLStatus) * numBackendStatSlots);
+ sizeof(PgBackendSSLStatus) * NumBackendStatSlots);
#endif
#ifdef ENABLE_GSS
localgssstatus = (PgBackendGSSStatus *)
MemoryContextAlloc(backendStatusSnapContext,
- sizeof(PgBackendGSSStatus) * numBackendStatSlots);
+ sizeof(PgBackendGSSStatus) * NumBackendStatSlots);
#endif
localNumBackends = 0;
beentry = BackendStatusArray;
localentry = localtable;
- for (i = 1; i <= numBackendStatSlots; i++)
+ for (i = 1; i <= NumBackendStatSlots; i++)
{
/*
* Follow the protocol of retrying if st_changecount changes while we
{
PgBackendStatus *beentry;
int i;
- int max_backends = GetMaxBackends();
beentry = BackendStatusArray;
- for (i = 1; i <= max_backends; i++)
+ for (i = 1; i <= MaxBackends; i++)
{
/*
* Although we expect the target backend's entry to be stable, that
{
volatile PgBackendStatus *beentry;
int i;
- int max_backends = GetMaxBackends();
beentry = BackendStatusArray;
if (beentry == NULL || BackendActivityBuffer == NULL)
return NULL;
- for (i = 1; i <= max_backends; i++)
+ for (i = 1; i <= MaxBackends; i++)
{
if (beentry->st_procpid == pid)
{
int *blockers;
int num_blockers;
Datum *blocker_datums;
- int max_backends = GetMaxBackends();
/* A buffer big enough for any possible blocker list without truncation */
- blockers = (int *) palloc(max_backends * sizeof(int));
+ blockers = (int *) palloc(MaxBackends * sizeof(int));
/* Collect a snapshot of processes waited for by GetSafeSnapshot */
num_blockers =
- GetSafeSnapshotBlockingPids(blocked_pid, blockers, max_backends);
+ GetSafeSnapshotBlockingPids(blocked_pid, blockers, MaxBackends);
/* Convert int array to Datum array */
if (num_blockers > 0)
#include "access/session.h"
#include "access/sysattr.h"
#include "access/tableam.h"
-#include "access/twophase.h"
#include "access/xact.h"
#include "access/xlog.h"
#include "access/xloginsert.h"
#include "utils/syscache.h"
#include "utils/timeout.h"
-static int MaxBackends = 0;
-static int MaxBackendsInitialized = false;
-
static HeapTuple GetDatabaseTuple(const char *dbname);
static HeapTuple GetDatabaseTupleByOid(Oid dboid);
static void PerformAuthentication(Port *port);
/*
* Initialize MaxBackends value from config options.
*
- * This must be called after modules have had the chance to alter GUCs in
- * shared_preload_libraries and before shared memory size is determined.
+ * This must be called after modules have had the chance to register background
+ * workers in shared_preload_libraries, and before shared memory size is
+ * determined.
*
* Note that in EXEC_BACKEND environment, the value is passed down from
* postmaster to subprocesses via BackendParameters in SubPostmasterMain; only
void
InitializeMaxBackends(void)
{
- /* the extra unit accounts for the autovacuum launcher */
- SetMaxBackends(MaxConnections + autovacuum_max_workers + 1 +
- max_worker_processes + max_wal_senders);
-}
+ Assert(MaxBackends == 0);
-/*
- * Safely retrieve the value of MaxBackends.
- *
- * Previously, MaxBackends was externally visible, but it was often used before
- * it was initialized (e.g., in preloaded libraries' _PG_init() functions).
- * Unfortunately, we cannot initialize MaxBackends before processing
- * shared_preload_libraries because the libraries sometimes alter GUCs that are
- * used to calculate its value. Instead, we provide this function for accessing
- * MaxBackends, and we ERROR if someone calls it before it is initialized.
- */
-int
-GetMaxBackends(void)
-{
- if (unlikely(!MaxBackendsInitialized))
- elog(ERROR, "MaxBackends not yet initialized");
-
- return MaxBackends;
-}
-
-/*
- * Set the value of MaxBackends.
- *
- * This should only be used by InitializeMaxBackends() and
- * restore_backend_variables(). If MaxBackends is already initialized or the
- * specified value is greater than the maximum, this will ERROR.
- */
-void
-SetMaxBackends(int max_backends)
-{
- if (MaxBackendsInitialized)
- elog(ERROR, "MaxBackends already initialized");
+ /* the extra unit accounts for the autovacuum launcher */
+ MaxBackends = MaxConnections + autovacuum_max_workers + 1 +
+ max_worker_processes + max_wal_senders;
/* internal error because the values were all checked previously */
- if (max_backends > MAX_BACKENDS)
+ if (MaxBackends > MAX_BACKENDS)
elog(ERROR, "too many backends configured");
-
- MaxBackends = max_backends;
- MaxBackendsInitialized = true;
}
/*
SharedInvalBackendInit(false);
- if (MyBackendId > GetMaxBackends() || MyBackendId <= 0)
+ if (MyBackendId > MaxBackends || MyBackendId <= 0)
elog(FATAL, "bad backend ID: %d", MyBackendId);
/* Now that we have a BackendId, we can participate in ProcSignal */
extern PGDLLIMPORT int data_directory_mode;
extern PGDLLIMPORT int NBuffers;
+extern PGDLLIMPORT int MaxBackends;
extern PGDLLIMPORT int MaxConnections;
extern PGDLLIMPORT int max_worker_processes;
extern PGDLLIMPORT int max_parallel_workers;
/* in utils/init/postinit.c */
extern void pg_split_opts(char **argv, int *argcp, const char *optstr);
extern void InitializeMaxBackends(void);
-extern int GetMaxBackends(void);
-extern void SetMaxBackends(int max_backends);
extern void InitPostgres(const char *in_dbname, Oid dboid, const char *username,
Oid useroid, char *out_dbname, bool override_allow_connections);
extern void BaseInit(void);