Provide a way to supress the "out of memory" error when allocating.
authorRobert Haas <rhaas@postgresql.org>
Fri, 30 Jan 2015 17:56:48 +0000 (12:56 -0500)
committerRobert Haas <rhaas@postgresql.org>
Fri, 30 Jan 2015 17:56:48 +0000 (12:56 -0500)
Using the new interface MemoryContextAllocExtended, callers can
specify MCXT_ALLOC_NO_OOM if they are prepared to handle a NULL
return value.

Michael Paquier, reviewed and somewhat revised by me.

src/backend/utils/mmgr/mcxt.c
src/include/utils/palloc.h

index c62922a187a8fcc9db89cb4dd884a4d5989ed776..202bc785bcfd2001088e201a36e369968cd1f7d7 100644 (file)
@@ -711,6 +711,46 @@ MemoryContextAllocZeroAligned(MemoryContext context, Size size)
        return ret;
 }
 
+/*
+ * MemoryContextAllocExtended
+ *             Allocate space within the specified context using the given flags.
+ */
+void *
+MemoryContextAllocExtended(MemoryContext context, Size size, int flags)
+{
+       void       *ret;
+
+       AssertArg(MemoryContextIsValid(context));
+       AssertNotInCriticalSection(context);
+
+       if (((flags & MCXT_ALLOC_HUGE) != 0 && !AllocHugeSizeIsValid(size)) ||
+               ((flags & MCXT_ALLOC_HUGE) == 0 && !AllocSizeIsValid(size)))
+               elog(ERROR, "invalid memory alloc request size %zu", size);
+
+       context->isReset = false;
+
+       ret = (*context->methods->alloc) (context, size);
+       if (ret == NULL)
+       {
+               if ((flags & MCXT_ALLOC_NO_OOM) == 0)
+               {
+                       MemoryContextStats(TopMemoryContext);
+                       ereport(ERROR,
+                                       (errcode(ERRCODE_OUT_OF_MEMORY),
+                                        errmsg("out of memory"),
+                                        errdetail("Failed on request of size %zu.", size)));
+               }
+               return NULL;
+       }
+
+       VALGRIND_MEMPOOL_ALLOC(context, ret, size);
+
+       if ((flags & MCXT_ALLOC_ZERO) != 0)
+               MemSetAligned(ret, 0, size);
+
+       return ret;
+}
+
 void *
 palloc(Size size)
 {
index ca03f2b3341d726d2d3576c25bdcd5e3ed62495b..f586fd5535b3ee42417036cb3cfb85840fb4f04c 100644 (file)
@@ -42,12 +42,21 @@ typedef struct MemoryContextData *MemoryContext;
  */
 extern PGDLLIMPORT MemoryContext CurrentMemoryContext;
 
+/*
+ * Flags for MemoryContextAllocExtended.
+ */
+#define MCXT_ALLOC_HUGE                        0x01    /* allow huge allocation (> 1 GB) */
+#define MCXT_ALLOC_NO_OOM              0x02    /* no failure if out-of-memory */
+#define MCXT_ALLOC_ZERO                        0x04    /* zero allocated memory */
+
 /*
  * Fundamental memory-allocation operations (more are in utils/memutils.h)
  */
 extern void *MemoryContextAlloc(MemoryContext context, Size size);
 extern void *MemoryContextAllocZero(MemoryContext context, Size size);
 extern void *MemoryContextAllocZeroAligned(MemoryContext context, Size size);
+extern void *MemoryContextAllocExtended(MemoryContext context,
+                                                                               Size size, int flags);
 
 extern void *palloc(Size size);
 extern void *palloc0(Size size);