1/*-------------------------------------------------------------------------
2 *
3 * memutils.h
4 * This file contains declarations for memory allocation utility
5 * functions. These are functions that are not quite widely used
6 * enough to justify going in utils/palloc.h, but are still part
7 * of the API of the memory management subsystem.
8 *
9 *
10 * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
11 * Portions Copyright (c) 1994, Regents of the University of California
12 *
13 * src/include/utils/memutils.h
14 *
15 *-------------------------------------------------------------------------
16 */
17#ifndef MEMUTILS_H
18#define MEMUTILS_H
19
20#include "nodes/memnodes.h"
21
22
23/*
24 * MaxAllocSize, MaxAllocHugeSize
25 * Quasi-arbitrary limits on size of allocations.
26 *
27 * Note:
28 * There is no guarantee that smaller allocations will succeed, but
29 * larger requests will be summarily denied.
30 *
31 * palloc() enforces MaxAllocSize, chosen to correspond to the limiting size
32 * of varlena objects under TOAST. See VARSIZE_4B() and related macros in
33 * postgres.h. Many datatypes assume that any allocatable size can be
34 * represented in a varlena header. This limit also permits a caller to use
35 * an "int" variable for an index into or length of an allocation. Callers
36 * careful to avoid these hazards can access the higher limit with
37 * MemoryContextAllocHuge(). Both limits permit code to assume that it may
38 * compute twice an allocation's size without overflow.
39 */
40#define MaxAllocSize ((Size) 0x3fffffff) /* 1 gigabyte - 1 */
41
42#define AllocSizeIsValid(size) ((Size) (size) <= MaxAllocSize)
43
44#define MaxAllocHugeSize (SIZE_MAX / 2)
45
46#define AllocHugeSizeIsValid(size) ((Size) (size) <= MaxAllocHugeSize)
47
48
49/*
50 * Standard top-level memory contexts.
51 *
52 * Only TopMemoryContext and ErrorContext are initialized by
53 * MemoryContextInit() itself.
54 */
55extern PGDLLIMPORT MemoryContext TopMemoryContext;
56extern PGDLLIMPORT MemoryContext ErrorContext;
57extern PGDLLIMPORT MemoryContext PostmasterContext;
58extern PGDLLIMPORT MemoryContext CacheMemoryContext;
59extern PGDLLIMPORT MemoryContext MessageContext;
60extern PGDLLIMPORT MemoryContext TopTransactionContext;
61extern PGDLLIMPORT MemoryContext CurTransactionContext;
62
63/* This is a transient link to the active portal's memory context: */
64extern PGDLLIMPORT MemoryContext PortalContext;
65
66/* Backwards compatibility macro */
67#define MemoryContextResetAndDeleteChildren(ctx) MemoryContextReset(ctx)
68
69
70/*
71 * Memory-context-type-independent functions in mcxt.c
72 */
73extern void MemoryContextInit(void);
74extern void MemoryContextReset(MemoryContext context);
75extern void MemoryContextDelete(MemoryContext context);
76extern void MemoryContextResetOnly(MemoryContext context);
77extern void MemoryContextResetChildren(MemoryContext context);
78extern void MemoryContextDeleteChildren(MemoryContext context);
79extern void MemoryContextSetIdentifier(MemoryContext context, const char *id);
80extern void MemoryContextSetParent(MemoryContext context,
81 MemoryContext new_parent);
82extern Size GetMemoryChunkSpace(void *pointer);
83extern MemoryContext MemoryContextGetParent(MemoryContext context);
84extern bool MemoryContextIsEmpty(MemoryContext context);
85extern void MemoryContextStats(MemoryContext context);
86extern void MemoryContextStatsDetail(MemoryContext context, int max_children);
87extern void MemoryContextAllowInCriticalSection(MemoryContext context,
88 bool allow);
89
90#ifdef MEMORY_CONTEXT_CHECKING
91extern void MemoryContextCheck(MemoryContext context);
92#endif
93extern bool MemoryContextContains(MemoryContext context, void *pointer);
94
95/* Handy macro for copying and assigning context ID ... but note double eval */
96#define MemoryContextCopyAndSetIdentifier(cxt, id) \
97 MemoryContextSetIdentifier(cxt, MemoryContextStrdup(cxt, id))
98
99/*
100 * GetMemoryChunkContext
101 * Given a currently-allocated chunk, determine the context
102 * it belongs to.
103 *
104 * All chunks allocated by any memory context manager are required to be
105 * preceded by the corresponding MemoryContext stored, without padding, in the
106 * preceding sizeof(void*) bytes. A currently-allocated chunk must contain a
107 * backpointer to its owning context. The backpointer is used by pfree() and
108 * repalloc() to find the context to call.
109 */
110#ifndef FRONTEND
111static inline MemoryContext
112GetMemoryChunkContext(void *pointer)
113{
114 MemoryContext context;
115
116 /*
117 * Try to detect bogus pointers handed to us, poorly though we can.
118 * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
119 * allocated chunk.
120 */
121 Assert(pointer != NULL);
122 Assert(pointer == (void *) MAXALIGN(pointer));
123
124 /*
125 * OK, it's probably safe to look at the context.
126 */
127 context = *(MemoryContext *) (((char *) pointer) - sizeof(void *));
128
129 AssertArg(MemoryContextIsValid(context));
130
131 return context;
132}
133#endif
134
135/*
136 * This routine handles the context-type-independent part of memory
137 * context creation. It's intended to be called from context-type-
138 * specific creation routines, and noplace else.
139 */
140extern void MemoryContextCreate(MemoryContext node,
141 NodeTag tag,
142 const MemoryContextMethods *methods,
143 MemoryContext parent,
144 const char *name);
145
146
147/*
148 * Memory-context-type-specific functions
149 */
150
151/* aset.c */
152extern MemoryContext AllocSetContextCreateInternal(MemoryContext parent,
153 const char *name,
154 Size minContextSize,
155 Size initBlockSize,
156 Size maxBlockSize);
157
158/*
159 * This wrapper macro exists to check for non-constant strings used as context
160 * names; that's no longer supported. (Use MemoryContextSetIdentifier if you
161 * want to provide a variable identifier.)
162 */
163#ifdef HAVE__BUILTIN_CONSTANT_P
164#define AllocSetContextCreate(parent, name, ...) \
165 (StaticAssertExpr(__builtin_constant_p(name), \
166 "memory context names must be constant strings"), \
167 AllocSetContextCreateInternal(parent, name, __VA_ARGS__))
168#else
169#define AllocSetContextCreate \
170 AllocSetContextCreateInternal
171#endif
172
173/* slab.c */
174extern MemoryContext SlabContextCreate(MemoryContext parent,
175 const char *name,
176 Size blockSize,
177 Size chunkSize);
178
179/* generation.c */
180extern MemoryContext GenerationContextCreate(MemoryContext parent,
181 const char *name,
182 Size blockSize);
183
184/*
185 * Recommended default alloc parameters, suitable for "ordinary" contexts
186 * that might hold quite a lot of data.
187 */
188#define ALLOCSET_DEFAULT_MINSIZE 0
189#define ALLOCSET_DEFAULT_INITSIZE (8 * 1024)
190#define ALLOCSET_DEFAULT_MAXSIZE (8 * 1024 * 1024)
191#define ALLOCSET_DEFAULT_SIZES \
192 ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE
193
194/*
195 * Recommended alloc parameters for "small" contexts that are never expected
196 * to contain much data (for example, a context to contain a query plan).
197 */
198#define ALLOCSET_SMALL_MINSIZE 0
199#define ALLOCSET_SMALL_INITSIZE (1 * 1024)
200#define ALLOCSET_SMALL_MAXSIZE (8 * 1024)
201#define ALLOCSET_SMALL_SIZES \
202 ALLOCSET_SMALL_MINSIZE, ALLOCSET_SMALL_INITSIZE, ALLOCSET_SMALL_MAXSIZE
203
204/*
205 * Recommended alloc parameters for contexts that should start out small,
206 * but might sometimes grow big.
207 */
208#define ALLOCSET_START_SMALL_SIZES \
209 ALLOCSET_SMALL_MINSIZE, ALLOCSET_SMALL_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE
210
211
212/*
213 * Threshold above which a request in an AllocSet context is certain to be
214 * allocated separately (and thereby have constant allocation overhead).
215 * Few callers should be interested in this, but tuplesort/tuplestore need
216 * to know it.
217 */
218#define ALLOCSET_SEPARATE_THRESHOLD 8192
219
220#define SLAB_DEFAULT_BLOCK_SIZE (8 * 1024)
221#define SLAB_LARGE_BLOCK_SIZE (8 * 1024 * 1024)
222
223#endif /* MEMUTILS_H */
224