summaryrefslogtreecommitdiffstats
path: root/src/include/utils/memutils.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/utils/memutils.h')
-rw-r--r--src/include/utils/memutils.h224
1 files changed, 224 insertions, 0 deletions
diff --git a/src/include/utils/memutils.h b/src/include/utils/memutils.h
new file mode 100644
index 0000000..909bc2e
--- /dev/null
+++ b/src/include/utils/memutils.h
@@ -0,0 +1,224 @@
+/*-------------------------------------------------------------------------
+ *
+ * memutils.h
+ * This file contains declarations for memory allocation utility
+ * functions. These are functions that are not quite widely used
+ * enough to justify going in utils/palloc.h, but are still part
+ * of the API of the memory management subsystem.
+ *
+ *
+ * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/utils/memutils.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef MEMUTILS_H
+#define MEMUTILS_H
+
+#include "nodes/memnodes.h"
+
+
+/*
+ * MaxAllocSize, MaxAllocHugeSize
+ * Quasi-arbitrary limits on size of allocations.
+ *
+ * Note:
+ * There is no guarantee that smaller allocations will succeed, but
+ * larger requests will be summarily denied.
+ *
+ * palloc() enforces MaxAllocSize, chosen to correspond to the limiting size
+ * of varlena objects under TOAST. See VARSIZE_4B() and related macros in
+ * postgres.h. Many datatypes assume that any allocatable size can be
+ * represented in a varlena header. This limit also permits a caller to use
+ * an "int" variable for an index into or length of an allocation. Callers
+ * careful to avoid these hazards can access the higher limit with
+ * MemoryContextAllocHuge(). Both limits permit code to assume that it may
+ * compute twice an allocation's size without overflow.
+ */
+#define MaxAllocSize ((Size) 0x3fffffff) /* 1 gigabyte - 1 */
+
+#define AllocSizeIsValid(size) ((Size) (size) <= MaxAllocSize)
+
+#define MaxAllocHugeSize (SIZE_MAX / 2)
+
+#define AllocHugeSizeIsValid(size) ((Size) (size) <= MaxAllocHugeSize)
+
+
+/*
+ * Standard top-level memory contexts.
+ *
+ * Only TopMemoryContext and ErrorContext are initialized by
+ * MemoryContextInit() itself.
+ */
+extern PGDLLIMPORT MemoryContext TopMemoryContext;
+extern PGDLLIMPORT MemoryContext ErrorContext;
+extern PGDLLIMPORT MemoryContext PostmasterContext;
+extern PGDLLIMPORT MemoryContext CacheMemoryContext;
+extern PGDLLIMPORT MemoryContext MessageContext;
+extern PGDLLIMPORT MemoryContext TopTransactionContext;
+extern PGDLLIMPORT MemoryContext CurTransactionContext;
+
+/* This is a transient link to the active portal's memory context: */
+extern PGDLLIMPORT MemoryContext PortalContext;
+
+/* Backwards compatibility macro */
+#define MemoryContextResetAndDeleteChildren(ctx) MemoryContextReset(ctx)
+
+
+/*
+ * Memory-context-type-independent functions in mcxt.c
+ */
+extern void MemoryContextInit(void);
+extern void MemoryContextReset(MemoryContext context);
+extern void MemoryContextDelete(MemoryContext context);
+extern void MemoryContextResetOnly(MemoryContext context);
+extern void MemoryContextResetChildren(MemoryContext context);
+extern void MemoryContextDeleteChildren(MemoryContext context);
+extern void MemoryContextSetIdentifier(MemoryContext context, const char *id);
+extern void MemoryContextSetParent(MemoryContext context,
+ MemoryContext new_parent);
+extern Size GetMemoryChunkSpace(void *pointer);
+extern MemoryContext MemoryContextGetParent(MemoryContext context);
+extern bool MemoryContextIsEmpty(MemoryContext context);
+extern Size MemoryContextMemAllocated(MemoryContext context, bool recurse);
+extern void MemoryContextStats(MemoryContext context);
+extern void MemoryContextStatsDetail(MemoryContext context, int max_children);
+extern void MemoryContextAllowInCriticalSection(MemoryContext context,
+ bool allow);
+
+#ifdef MEMORY_CONTEXT_CHECKING
+extern void MemoryContextCheck(MemoryContext context);
+#endif
+extern bool MemoryContextContains(MemoryContext context, void *pointer);
+
+/* Handy macro for copying and assigning context ID ... but note double eval */
+#define MemoryContextCopyAndSetIdentifier(cxt, id) \
+ MemoryContextSetIdentifier(cxt, MemoryContextStrdup(cxt, id))
+
+/*
+ * GetMemoryChunkContext
+ * Given a currently-allocated chunk, determine the context
+ * it belongs to.
+ *
+ * All chunks allocated by any memory context manager are required to be
+ * preceded by the corresponding MemoryContext stored, without padding, in the
+ * preceding sizeof(void*) bytes. A currently-allocated chunk must contain a
+ * backpointer to its owning context. The backpointer is used by pfree() and
+ * repalloc() to find the context to call.
+ */
+#ifndef FRONTEND
+static inline MemoryContext
+GetMemoryChunkContext(void *pointer)
+{
+ MemoryContext context;
+
+ /*
+ * Try to detect bogus pointers handed to us, poorly though we can.
+ * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
+ * allocated chunk.
+ */
+ Assert(pointer != NULL);
+ Assert(pointer == (void *) MAXALIGN(pointer));
+
+ /*
+ * OK, it's probably safe to look at the context.
+ */
+ context = *(MemoryContext *) (((char *) pointer) - sizeof(void *));
+
+ AssertArg(MemoryContextIsValid(context));
+
+ return context;
+}
+#endif
+
+/*
+ * This routine handles the context-type-independent part of memory
+ * context creation. It's intended to be called from context-type-
+ * specific creation routines, and noplace else.
+ */
+extern void MemoryContextCreate(MemoryContext node,
+ NodeTag tag,
+ const MemoryContextMethods *methods,
+ MemoryContext parent,
+ const char *name);
+
+
+/*
+ * Memory-context-type-specific functions
+ */
+
+/* aset.c */
+extern MemoryContext AllocSetContextCreateInternal(MemoryContext parent,
+ const char *name,
+ Size minContextSize,
+ Size initBlockSize,
+ Size maxBlockSize);
+
+/*
+ * This wrapper macro exists to check for non-constant strings used as context
+ * names; that's no longer supported. (Use MemoryContextSetIdentifier if you
+ * want to provide a variable identifier.)
+ */
+#ifdef HAVE__BUILTIN_CONSTANT_P
+#define AllocSetContextCreate(parent, name, ...) \
+ (StaticAssertExpr(__builtin_constant_p(name), \
+ "memory context names must be constant strings"), \
+ AllocSetContextCreateInternal(parent, name, __VA_ARGS__))
+#else
+#define AllocSetContextCreate \
+ AllocSetContextCreateInternal
+#endif
+
+/* slab.c */
+extern MemoryContext SlabContextCreate(MemoryContext parent,
+ const char *name,
+ Size blockSize,
+ Size chunkSize);
+
+/* generation.c */
+extern MemoryContext GenerationContextCreate(MemoryContext parent,
+ const char *name,
+ Size blockSize);
+
+/*
+ * Recommended default alloc parameters, suitable for "ordinary" contexts
+ * that might hold quite a lot of data.
+ */
+#define ALLOCSET_DEFAULT_MINSIZE 0
+#define ALLOCSET_DEFAULT_INITSIZE (8 * 1024)
+#define ALLOCSET_DEFAULT_MAXSIZE (8 * 1024 * 1024)
+#define ALLOCSET_DEFAULT_SIZES \
+ ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE
+
+/*
+ * Recommended alloc parameters for "small" contexts that are never expected
+ * to contain much data (for example, a context to contain a query plan).
+ */
+#define ALLOCSET_SMALL_MINSIZE 0
+#define ALLOCSET_SMALL_INITSIZE (1 * 1024)
+#define ALLOCSET_SMALL_MAXSIZE (8 * 1024)
+#define ALLOCSET_SMALL_SIZES \
+ ALLOCSET_SMALL_MINSIZE, ALLOCSET_SMALL_INITSIZE, ALLOCSET_SMALL_MAXSIZE
+
+/*
+ * Recommended alloc parameters for contexts that should start out small,
+ * but might sometimes grow big.
+ */
+#define ALLOCSET_START_SMALL_SIZES \
+ ALLOCSET_SMALL_MINSIZE, ALLOCSET_SMALL_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE
+
+
+/*
+ * Threshold above which a request in an AllocSet context is certain to be
+ * allocated separately (and thereby have constant allocation overhead).
+ * Few callers should be interested in this, but tuplesort/tuplestore need
+ * to know it.
+ */
+#define ALLOCSET_SEPARATE_THRESHOLD 8192
+
+#define SLAB_DEFAULT_BLOCK_SIZE (8 * 1024)
+#define SLAB_LARGE_BLOCK_SIZE (8 * 1024 * 1024)
+
+#endif /* MEMUTILS_H */