#include "postgres.h"
+#include "miscadmin.h"
#include "utils/memdebug.h"
#include "utils/memutils.h"
static void MemoryContextStatsInternal(MemoryContext context, int level);
+/*
+ * You should not do memory allocations within a critical section, because
+ * an out-of-memory error will be escalated to a PANIC. To enforce that
+ * rule, the allocation functions Assert that.
+ *
+ * There are a two exceptions: 1) error recovery uses ErrorContext, which
+ * has some memory set aside so that you don't run out. And 2) checkpointer
+ * currently just hopes for the best, which is wrong and ought to be fixed,
+ * but it's a known issue so let's not complain about in the meanwhile.
+ */
+#define AssertNotInCriticalSection(context) \
+ Assert(CritSectionCount == 0 || (context) == ErrorContext || \
+ AmCheckpointerProcess())
/*****************************************************************************
* EXPORTED ROUTINES *
MemoryContext node;
Size needed = size + strlen(name) + 1;
+ Assert(CritSectionCount == 0);
+
/* Get space for node and name */
if (TopMemoryContext != NULL)
{
void *ret;
AssertArg(MemoryContextIsValid(context));
+ AssertNotInCriticalSection(context);
if (!AllocSizeIsValid(size))
elog(ERROR, "invalid memory alloc request size %zu", size);
void *ret;
AssertArg(MemoryContextIsValid(context));
+ AssertNotInCriticalSection(context);
if (!AllocSizeIsValid(size))
elog(ERROR, "invalid memory alloc request size %zu", size);
void *ret;
AssertArg(MemoryContextIsValid(context));
+ AssertNotInCriticalSection(context);
if (!AllocSizeIsValid(size))
elog(ERROR, "invalid memory alloc request size %zu", size);
void *ret;
AssertArg(MemoryContextIsValid(CurrentMemoryContext));
+ AssertNotInCriticalSection(CurrentMemoryContext);
if (!AllocSizeIsValid(size))
elog(ERROR, "invalid memory alloc request size %zu", size);
void *ret;
AssertArg(MemoryContextIsValid(CurrentMemoryContext));
+ AssertNotInCriticalSection(CurrentMemoryContext);
if (!AllocSizeIsValid(size))
elog(ERROR, "invalid memory alloc request size %zu", size);
((char *) pointer - STANDARDCHUNKHEADERSIZE))->context;
AssertArg(MemoryContextIsValid(context));
+ AssertNotInCriticalSection(context);
/* isReset must be false already */
Assert(!context->isReset);
void *ret;
AssertArg(MemoryContextIsValid(context));
+ AssertNotInCriticalSection(context);
if (!AllocHugeSizeIsValid(size))
elog(ERROR, "invalid memory alloc request size %zu", size);
((char *) pointer - STANDARDCHUNKHEADERSIZE))->context;
AssertArg(MemoryContextIsValid(context));
+ AssertNotInCriticalSection(context);
/* isReset must be false already */
Assert(!context->isReset);