diff options
Diffstat (limited to 'src/backend/storage/lmgr/proc.c')
-rw-r--r-- | src/backend/storage/lmgr/proc.c | 46 |
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. |