aboutsummaryrefslogtreecommitdiff
path: root/src/backend/storage/lmgr/proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/storage/lmgr/proc.c')
-rw-r--r--src/backend/storage/lmgr/proc.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index ac66da8638f..9b72829725a 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -103,6 +103,8 @@ ProcGlobalShmemSize(void)
Size size = 0;
Size TotalProcs =
add_size(MaxBackends, add_size(NUM_AUXILIARY_PROCS, max_prepared_xacts));
+ Size fpLockBitsSize,
+ fpRelIdSize;
/* ProcGlobal */
size = add_size(size, sizeof(PROC_HDR));
@@ -113,6 +115,15 @@ ProcGlobalShmemSize(void)
size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->subxidStates)));
size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->statusFlags)));
+ /*
+ * Memory needed for PGPROC fast-path lock arrays. Make sure the sizes are
+ * nicely aligned in each backend.
+ */
+ fpLockBitsSize = MAXALIGN(FastPathLockGroupsPerBackend * sizeof(uint64));
+ fpRelIdSize = MAXALIGN(FastPathLockGroupsPerBackend * sizeof(Oid) * FP_LOCK_SLOTS_PER_GROUP);
+
+ size = add_size(size, mul_size(TotalProcs, (fpLockBitsSize + fpRelIdSize)));
+
return size;
}
@@ -163,6 +174,12 @@ InitProcGlobal(void)
bool found;
uint32 TotalProcs = MaxBackends + NUM_AUXILIARY_PROCS + max_prepared_xacts;
+ /* Used for setup of per-backend fast-path slots. */
+ char *fpPtr,
+ *fpEndPtr PG_USED_FOR_ASSERTS_ONLY;
+ Size fpLockBitsSize,
+ fpRelIdSize;
+
/* Create the ProcGlobal shared structure */
ProcGlobal = (PROC_HDR *)
ShmemInitStruct("Proc Header", sizeof(PROC_HDR), &found);
@@ -211,6 +228,20 @@ InitProcGlobal(void)
ProcGlobal->statusFlags = (uint8 *) ShmemAlloc(TotalProcs * sizeof(*ProcGlobal->statusFlags));
MemSet(ProcGlobal->statusFlags, 0, TotalProcs * sizeof(*ProcGlobal->statusFlags));
+ /*
+ * Allocate arrays for fast-path locks. Those are variable-length, so
+ * can't be included in PGPROC directly. We allocate a separate piece of
+ * shared memory and then divide that between backends.
+ */
+ fpLockBitsSize = MAXALIGN(FastPathLockGroupsPerBackend * sizeof(uint64));
+ fpRelIdSize = MAXALIGN(FastPathLockGroupsPerBackend * sizeof(Oid) * FP_LOCK_SLOTS_PER_GROUP);
+
+ fpPtr = ShmemAlloc(TotalProcs * (fpLockBitsSize + fpRelIdSize));
+ MemSet(fpPtr, 0, TotalProcs * (fpLockBitsSize + fpRelIdSize));
+
+ /* For asserts checking we did not overflow. */
+ fpEndPtr = fpPtr + (TotalProcs * (fpLockBitsSize + fpRelIdSize));
+
for (i = 0; i < TotalProcs; i++)
{
PGPROC *proc = &procs[i];
@@ -218,6 +249,18 @@ InitProcGlobal(void)
/* Common initialization for all PGPROCs, regardless of type. */
/*
+ * Set the fast-path lock arrays, and move the pointer. We interleave
+ * the two arrays, to (hopefully) get some locality for each backend.
+ */
+ proc->fpLockBits = (uint64 *) fpPtr;
+ fpPtr += fpLockBitsSize;
+
+ proc->fpRelId = (Oid *) fpPtr;
+ fpPtr += fpRelIdSize;
+
+ Assert(fpPtr <= fpEndPtr);
+
+ /*
* Set up per-PGPROC semaphore, latch, and fpInfoLock. Prepared xact
* dummy PGPROCs don't need these though - they're never associated
* with a real process
@@ -278,6 +321,9 @@ InitProcGlobal(void)
pg_atomic_init_u64(&(proc->waitStart), 0);
}
+ /* Should have consumed exactly the expected amount of fast-path memory. */
+ Assert(fpPtr = fpEndPtr);
+
/*
* Save pointers to the blocks of PGPROC structures reserved for auxiliary
* processes and prepared transactions.