diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c index 1efe0201a795a315e158d47bf41786d9d17c85ad..cc3af2d6156b61d8d708a7df125fe0aa6b2e46e5 100644 --- a/src/backend/storage/ipc/shmem.c +++ b/src/backend/storage/ipc/shmem.c @@ -163,14 +163,31 @@ InitShmemAllocation(void) /* * ShmemAlloc -- allocate max-aligned chunk from shared memory * - * Assumes ShmemLock and ShmemSegHdr are initialized. + * Throws error if request cannot be satisfied. * - * Returns: real pointer to memory or NULL if we are out - * of space. Has to return a real pointer in order - * to be compatible with malloc(). + * Assumes ShmemLock and ShmemSegHdr are initialized. */ void * ShmemAlloc(Size size) +{ + void *newSpace; + + newSpace = ShmemAllocNoError(size); + if (!newSpace) + ereport(ERROR, + (errcode(ERRCODE_OUT_OF_MEMORY), + errmsg("out of shared memory (%zu bytes requested)", + size))); + return newSpace; +} + +/* + * ShmemAllocNoError -- allocate max-aligned chunk from shared memory + * + * As ShmemAlloc, but returns NULL if out of space, rather than erroring. + */ +void * +ShmemAllocNoError(Size size) { Size newStart; Size newFree; @@ -206,11 +223,7 @@ ShmemAlloc(Size size) SpinLockRelease(ShmemLock); - if (!newSpace) - ereport(WARNING, - (errcode(ERRCODE_OUT_OF_MEMORY), - errmsg("out of shared memory"))); - + /* note this assert is okay with newSpace == NULL */ Assert(newSpace == (void *) CACHELINEALIGN(newSpace)); return newSpace; @@ -293,7 +306,7 @@ ShmemInitHash(const char *name, /* table string name for shmem index */ * The shared memory allocator must be specified too. */ infoP->dsize = infoP->max_dsize = hash_select_dirsize(max_size); - infoP->alloc = ShmemAlloc; + infoP->alloc = ShmemAllocNoError; hash_flags |= HASH_SHARED_MEM | HASH_ALLOC | HASH_DIRSIZE; /* look it up in the shmem index */ @@ -364,12 +377,6 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr) */ Assert(shmemseghdr->index == NULL); structPtr = ShmemAlloc(size); - if (structPtr == NULL) - ereport(ERROR, - (errcode(ERRCODE_OUT_OF_MEMORY), - errmsg("not enough shared memory for data structure" - " \"%s\" (%zu bytes requested)", - name, size))); shmemseghdr->index = structPtr; *foundPtr = FALSE; } @@ -410,7 +417,7 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr) else { /* It isn't in the table yet. allocate and initialize it */ - structPtr = ShmemAlloc(size); + structPtr = ShmemAllocNoError(size); if (structPtr == NULL) { /* out of memory; remove the failed ShmemIndex entry */ diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c index 7cdb35541bf5e620335470c6dd873086b76035e6..4064b2033ccb89c02d0e52a6683557bd0bba82d9 100644 --- a/src/backend/storage/lmgr/predicate.c +++ b/src/backend/storage/lmgr/predicate.c @@ -1184,12 +1184,6 @@ InitPredicateLocks(void) requestSize = mul_size((Size) max_table_size, PredXactListElementDataSize); PredXact->element = ShmemAlloc(requestSize); - if (PredXact->element == NULL) - ereport(ERROR, - (errcode(ERRCODE_OUT_OF_MEMORY), - errmsg("not enough shared memory for elements of data structure" - " \"%s\" (%zu bytes requested)", - "PredXactList", requestSize))); /* Add all elements to available list, clean. */ memset(PredXact->element, 0, requestSize); for (i = 0; i < max_table_size; i++) @@ -1255,12 +1249,6 @@ InitPredicateLocks(void) requestSize = mul_size((Size) max_table_size, RWConflictDataSize); RWConflictPool->element = ShmemAlloc(requestSize); - if (RWConflictPool->element == NULL) - ereport(ERROR, - (errcode(ERRCODE_OUT_OF_MEMORY), - errmsg("not enough shared memory for elements of data structure" - " \"%s\" (%zu bytes requested)", - "RWConflictPool", requestSize))); /* Add all elements to available list, clean. */ memset(RWConflictPool->element, 0, requestSize); for (i = 0; i < max_table_size; i++) diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 9a758bd91600b0839afadf3e3907e06a0902f8d5..33e7023656a6d6d675149061369870a7dc69efec 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -194,14 +194,10 @@ InitProcGlobal(void) * between groups. */ procs = (PGPROC *) ShmemAlloc(TotalProcs * sizeof(PGPROC)); + MemSet(procs, 0, TotalProcs * sizeof(PGPROC)); ProcGlobal->allProcs = procs; /* XXX allProcCount isn't really all of them; it excludes prepared xacts */ ProcGlobal->allProcCount = MaxBackends + NUM_AUXILIARY_PROCS; - if (!procs) - ereport(FATAL, - (errcode(ERRCODE_OUT_OF_MEMORY), - errmsg("out of shared memory"))); - MemSet(procs, 0, TotalProcs * sizeof(PGPROC)); /* * Also allocate a separate array of PGXACT structures. This is separate diff --git a/src/include/storage/shmem.h b/src/include/storage/shmem.h index 6468e6627ab601e19a23b056fb1f2fcc128deb40..2560e6c6da5764c3a118ba278568b0b6022d27da 100644 --- a/src/include/storage/shmem.h +++ b/src/include/storage/shmem.h @@ -35,6 +35,7 @@ typedef struct SHM_QUEUE extern void InitShmemAccess(void *seghdr); extern void InitShmemAllocation(void); extern void *ShmemAlloc(Size size); +extern void *ShmemAllocNoError(Size size); extern bool ShmemAddrIsValid(const void *addr); extern void InitShmemIndex(void); extern HTAB *ShmemInitHash(const char *name, long init_size, long max_size,