On Fri, Jan 30, 2015 at 12:29 AM, Robert Haas <robertmh...@gmail.com> wrote: > On Wed, Jan 28, 2015 at 9:34 AM, Michael Paquier > <michael.paqu...@gmail.com> wrote: >> As a result of all the comments on this thread, here are 3 patches >> implementing incrementally the different ideas from everybody: >> 1) 0001 modifies aset.c to return unconditionally NULL in case of an >> OOM instead of reporting an error. All the OOM error reports are moved >> to mcxt.c (MemoryContextAlloc* and palloc*) > > This seems like a good idea, but I think it's pretty clear that the > MemoryContextStats(TopMemoryContext) calls ought to move along with > the OOM error report. The stats are basically another kind of > error-case output, and the whole point here is that the caller wants > to have control of what happens when malloc fails. Committed that > way. Thanks for the clarifications!
>> 2) 0002 adds the noerror routines for frontend and backend. > > We don't have consensus on this name; as I read it, Andres and I are > both strongly opposed to it. Instead of continuing to litigate that > point, I'd like to propose that we just leave this out. We are > unlikely to have so many callers who need the no-oom-error behavior to > justify adding a bunch of convenience functions --- and if that does > happen, we can resume arguing about the naming then. For now, let's > just say that if you want that behavior, you should use > MemoryContextAllocExtended(CurrentMemoryContext, ...). Fine for me, any extension or module can still define their own equivalent of palloc_noerror or whatever using the Extended interface. >> 3) 0003 adds MemoryContextAllocExtended > I recommend we leave the existing MemoryContextAlloc* functions alone > and add a new MemoryContextAllocExtended() function *in addition*. I > think the reason we have multiple copies of this code is because they > are sufficiently hot to make the effect of a few extra CPU > instructions potentially material. By having separate copies of the > code, we avoid introducing extra branches. Yes, this refactoring was good for testing actually... I have changed the flags as follows, appending MCXT_ seemed cleaner after waking up this morning: +#define MCXT_ALLOC_HUGE 0x01 /* huge allocation */ +#define MCXT_ALLOC_NO_OOM 0x02 /* no failure if out-of-memory */ +#define MCXT_ALLOC_ZERO 0x04 /* clear allocated memory using + * MemSetAligned */ +#define MCXT_ALLOC_ZERO_ALIGNED 0x08 /* clear allocated memory using + * MemSetLoop */ -- Michael
From b5d43fd598e177c402c354f0b76aca52305463c6 Mon Sep 17 00:00:00 2001 From: Michael Paquier <mich...@otacoo.com> Date: Fri, 30 Jan 2015 12:56:21 +0900 Subject: [PATCH] Create MemoryContextAllocExtended central routine for memory allocation This new routine is the central point can be used by extensions and third-part utilities in a more extensive way than the already present routines MemoryContextAlloc, one of the control flags introduced being particularly useful to avoid out-of-memory errors when allocation request cannot be completed correctly. --- src/backend/utils/mmgr/mcxt.c | 57 +++++++++++++++++++++++++++++++++++++++++++ src/include/utils/palloc.h | 12 +++++++++ 2 files changed, 69 insertions(+) diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c index c62922a..26579e3 100644 --- a/src/backend/utils/mmgr/mcxt.c +++ b/src/backend/utils/mmgr/mcxt.c @@ -603,6 +603,63 @@ MemoryContextCreate(NodeTag tag, Size size, } /* + * MemoryContextAllocExtended + * Allocate space within the specified context using flag options + * defined by caller. + * + * The following control flags can be used: + * - MCXT_ALLOC_HUGE, allocate possibly-expansive space. this is + * equivalent to MemoryContextAllocHuge. + * - MCXT_ALLOC_NO_OOM, not fail in case of allocation request + * failure and return NULL. + * - MCXT_ALLOC_ZERO, clear allocated memory using MemSetAligned. + * - MCXT_ALLOC_ZERO_ALIGNED, clear memory using MemSetLoop. + */ +void * +MemoryContextAllocExtended(MemoryContext context, Size size, int flags) +{ + void *ret; + + AssertArg(MemoryContextIsValid(context)); + AssertNotInCriticalSection(context); + + if (((flags & MCXT_ALLOC_HUGE) != 0 && !AllocHugeSizeIsValid(size)) || + !AllocSizeIsValid(size)) + elog(ERROR, "invalid memory alloc request size %zu", size); + + context->isReset = false; + + ret = (*context->methods->alloc) (context, size); + if ((flags & MCXT_ALLOC_NO_OOM) == 0 && ret == NULL) + { + MemoryContextStats(TopMemoryContext); + ereport(ERROR, + (errcode(ERRCODE_OUT_OF_MEMORY), + errmsg("out of memory"), + errdetail("Failed on request of size %zu.", size))); + } + + if (ret == NULL) + return NULL; + + VALGRIND_MEMPOOL_ALLOC(context, ret, size); + + /* + * MemSetAligned and MemSetLoop should not be called in the same + * context (see c.h for more details). + */ + Assert((flags & MCXT_ALLOC_ZERO) == 0 || + (flags & MCXT_ALLOC_ZERO_ALIGNED) == 0); + + if ((flags & MCXT_ALLOC_ZERO) != 0) + MemSetAligned(ret, 0, size); + if ((flags & MCXT_ALLOC_ZERO_ALIGNED) != 0) + MemSetLoop(ret, 0, size); + + return ret; +} + +/* * MemoryContextAlloc * Allocate space within the specified context. * diff --git a/src/include/utils/palloc.h b/src/include/utils/palloc.h index ca03f2b..34acabe 100644 --- a/src/include/utils/palloc.h +++ b/src/include/utils/palloc.h @@ -43,8 +43,20 @@ typedef struct MemoryContextData *MemoryContext; extern PGDLLIMPORT MemoryContext CurrentMemoryContext; /* + * Control flags for options of MemoryContextAllocExtended() + */ +#define MCXT_ALLOC_HUGE 0x01 /* huge allocation */ +#define MCXT_ALLOC_NO_OOM 0x02 /* no failure if out-of-memory */ +#define MCXT_ALLOC_ZERO 0x04 /* clear allocated memory using + * MemSetAligned */ +#define MCXT_ALLOC_ZERO_ALIGNED 0x08 /* clear allocated memory using + * MemSetLoop */ + +/* * Fundamental memory-allocation operations (more are in utils/memutils.h) */ +extern void *MemoryContextAllocExtended(MemoryContext context, + Size size, int flags); extern void *MemoryContextAlloc(MemoryContext context, Size size); extern void *MemoryContextAllocZero(MemoryContext context, Size size); extern void *MemoryContextAllocZeroAligned(MemoryContext context, Size size); -- 2.2.2
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers