diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c index 5b21a053981..d82114ffca1 100644 --- a/src/backend/storage/lmgr/predicate.c +++ b/src/backend/storage/lmgr/predicate.c @@ -1226,14 +1226,21 @@ PredicateLockShmemInit(void) */ max_table_size *= 10; + requestSize = add_size(PredXactListDataSize, + (mul_size((Size) max_table_size, + sizeof(SERIALIZABLEXACT)))); + PredXact = ShmemInitStruct("PredXactList", - PredXactListDataSize, + requestSize, &found); Assert(found == IsUnderPostmaster); if (!found) { int i; + /* clean everything, both the header and the element */ + memset(PredXact, 0, requestSize); + dlist_init(&PredXact->availableList); dlist_init(&PredXact->activeList); PredXact->SxactGlobalXmin = InvalidTransactionId; @@ -1242,11 +1249,9 @@ PredicateLockShmemInit(void) PredXact->LastSxactCommitSeqNo = FirstNormalSerCommitSeqNo - 1; PredXact->CanPartialClearThrough = 0; PredXact->HavePartialClearedThrough = 0; - requestSize = mul_size((Size) max_table_size, - sizeof(SERIALIZABLEXACT)); - PredXact->element = ShmemAlloc(requestSize); + PredXact->element + = (SERIALIZABLEXACT *) ((char *) PredXact + PredXactListDataSize); /* Add all elements to available list, clean. */ - memset(PredXact->element, 0, requestSize); for (i = 0; i < max_table_size; i++) { LWLockInitialize(&PredXact->element[i].perXactPredicateListLock, @@ -1300,20 +1305,25 @@ PredicateLockShmemInit(void) */ max_table_size *= 5; + requestSize = RWConflictPoolHeaderDataSize + + mul_size((Size) max_table_size, + RWConflictDataSize); + RWConflictPool = ShmemInitStruct("RWConflictPool", - RWConflictPoolHeaderDataSize, + requestSize, &found); Assert(found == IsUnderPostmaster); if (!found) { int i; + /* clean everything, including the elements */ + memset(RWConflictPool, 0, requestSize); + dlist_init(&RWConflictPool->availableList); - requestSize = mul_size((Size) max_table_size, - RWConflictDataSize); - RWConflictPool->element = ShmemAlloc(requestSize); + RWConflictPool->element = (RWConflict) ((char *) RWConflictPool + + RWConflictPoolHeaderDataSize); /* Add all elements to available list, clean. */ - memset(RWConflictPool->element, 0, requestSize); for (i = 0; i < max_table_size; i++) { dlist_push_tail(&RWConflictPool->availableList, diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 066319afe2b..e9ef0fbfe32 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -91,10 +91,28 @@ static void CheckDeadLock(void); /* - * Report shared-memory space needed by InitProcGlobal. + * Report shared-memory space needed by PGPROC. */ -Size -ProcGlobalShmemSize(void) +static Size +PGProcShmemSize(void) +{ + Size size = 0; + Size TotalProcs = + add_size(MaxBackends, add_size(NUM_AUXILIARY_PROCS, max_prepared_xacts)); + + size = add_size(size, mul_size(TotalProcs, sizeof(PGPROC))); + size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->xids))); + size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->subxidStates))); + size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->statusFlags))); + + return size; +} + +/* + * Report shared-memory space needed by Fast-Path locks. + */ +static Size +FastPathLockShmemSize(void) { Size size = 0; Size TotalProcs = @@ -102,15 +120,6 @@ ProcGlobalShmemSize(void) Size fpLockBitsSize, fpRelIdSize; - /* ProcGlobal */ - size = add_size(size, sizeof(PROC_HDR)); - size = add_size(size, mul_size(TotalProcs, sizeof(PGPROC))); - size = add_size(size, sizeof(slock_t)); - - size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->xids))); - 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. @@ -123,6 +132,24 @@ ProcGlobalShmemSize(void) return size; } +/* + * Report shared-memory space needed by InitProcGlobal. + */ +Size +ProcGlobalShmemSize(void) +{ + Size size = 0; + + /* ProcGlobal */ + size = add_size(size, sizeof(PROC_HDR)); + size = add_size(size, sizeof(slock_t)); + + size = add_size(size, PGProcShmemSize()); + size = add_size(size, FastPathLockShmemSize()); + + return size; +} + /* * Report number of semaphores needed by InitProcGlobal. */ @@ -175,6 +202,8 @@ InitProcGlobal(void) *fpEndPtr PG_USED_FOR_ASSERTS_ONLY; Size fpLockBitsSize, fpRelIdSize; + Size requestSize; + char *ptr; /* Create the ProcGlobal shared structure */ ProcGlobal = (PROC_HDR *) @@ -204,8 +233,17 @@ InitProcGlobal(void) * with a single freelist.) Each PGPROC structure is dedicated to exactly * one of these purposes, and they do not move between groups. */ - procs = (PGPROC *) ShmemAlloc(TotalProcs * sizeof(PGPROC)); - MemSet(procs, 0, TotalProcs * sizeof(PGPROC)); + requestSize = PGProcShmemSize(); + + ptr = ShmemInitStruct("PGPROC structures", + requestSize, + &found); + + MemSet(ptr, 0, requestSize); + + procs = (PGPROC *) ptr; + ptr = (char *) ptr + TotalProcs * sizeof(PGPROC); + ProcGlobal->allProcs = procs; /* XXX allProcCount isn't really all of them; it excludes prepared xacts */ ProcGlobal->allProcCount = MaxBackends + NUM_AUXILIARY_PROCS; @@ -217,13 +255,17 @@ InitProcGlobal(void) * XXX: It might make sense to increase padding for these arrays, given * how hotly they are accessed. */ - ProcGlobal->xids = - (TransactionId *) ShmemAlloc(TotalProcs * sizeof(*ProcGlobal->xids)); - MemSet(ProcGlobal->xids, 0, TotalProcs * sizeof(*ProcGlobal->xids)); - ProcGlobal->subxidStates = (XidCacheStatus *) ShmemAlloc(TotalProcs * sizeof(*ProcGlobal->subxidStates)); - MemSet(ProcGlobal->subxidStates, 0, TotalProcs * sizeof(*ProcGlobal->subxidStates)); - ProcGlobal->statusFlags = (uint8 *) ShmemAlloc(TotalProcs * sizeof(*ProcGlobal->statusFlags)); - MemSet(ProcGlobal->statusFlags, 0, TotalProcs * sizeof(*ProcGlobal->statusFlags)); + ProcGlobal->xids = (TransactionId *) ptr; + ptr = (char *) ptr + (TotalProcs * sizeof(*ProcGlobal->xids)); + + ProcGlobal->subxidStates = (XidCacheStatus *) ptr; + ptr = (char *) ptr + (TotalProcs * sizeof(*ProcGlobal->subxidStates)); + + ProcGlobal->statusFlags = (uint8 *) ptr; + ptr = (char *) ptr + (TotalProcs * sizeof(*ProcGlobal->statusFlags)); + + /* make sure wer didn't overflow */ + Assert((ptr > (char *) procs) && (ptr <= (char *) procs + requestSize)); /* * Allocate arrays for fast-path locks. Those are variable-length, so @@ -233,11 +275,16 @@ InitProcGlobal(void) fpLockBitsSize = MAXALIGN(FastPathLockGroupsPerBackend * sizeof(uint64)); fpRelIdSize = MAXALIGN(FastPathLockSlotsPerBackend() * sizeof(Oid)); - fpPtr = ShmemAlloc(TotalProcs * (fpLockBitsSize + fpRelIdSize)); - MemSet(fpPtr, 0, TotalProcs * (fpLockBitsSize + fpRelIdSize)); + requestSize = FastPathLockShmemSize(); + + fpPtr = ShmemInitStruct("Fast-Path Lock Array", + requestSize, + &found); + + MemSet(fpPtr, 0, requestSize); /* For asserts checking we did not overflow. */ - fpEndPtr = fpPtr + (TotalProcs * (fpLockBitsSize + fpRelIdSize)); + fpEndPtr = fpPtr + requestSize; for (i = 0; i < TotalProcs; i++) { @@ -330,7 +377,9 @@ InitProcGlobal(void) PreparedXactProcs = &procs[MaxBackends + NUM_AUXILIARY_PROCS]; /* Create ProcStructLock spinlock, too */ - ProcStructLock = (slock_t *) ShmemAlloc(sizeof(slock_t)); + ProcStructLock = (slock_t *) ShmemInitStruct("ProcStructLock spinlock", + sizeof(slock_t), + &found); SpinLockInit(ProcStructLock); }