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-2021, 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 */
55 extern PGDLLIMPORT MemoryContext TopMemoryContext;
56 extern PGDLLIMPORT MemoryContext ErrorContext;
57 extern PGDLLIMPORT MemoryContext PostmasterContext;
58 extern PGDLLIMPORT MemoryContext CacheMemoryContext;
59 extern PGDLLIMPORT MemoryContext MessageContext;
60 extern PGDLLIMPORT MemoryContext TopTransactionContext;
61 extern PGDLLIMPORT MemoryContext CurTransactionContext;
62
63 /* This is a transient link to the active portal's memory context: */
64 extern 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 */
73 extern void MemoryContextInit(void);
74 extern void MemoryContextReset(MemoryContext context);
75 extern void MemoryContextDelete(MemoryContext context);
76 extern void MemoryContextResetOnly(MemoryContext context);
77 extern void MemoryContextResetChildren(MemoryContext context);
78 extern void MemoryContextDeleteChildren(MemoryContext context);
79 extern void MemoryContextSetIdentifier(MemoryContext context, const char *id);
80 extern void MemoryContextSetParent(MemoryContext context,
81 MemoryContext new_parent);
82 extern Size GetMemoryChunkSpace(void *pointer);
83 extern MemoryContext MemoryContextGetParent(MemoryContext context);
84 extern bool MemoryContextIsEmpty(MemoryContext context);
85 extern Size MemoryContextMemAllocated(MemoryContext context, bool recurse);
86 extern void MemoryContextStats(MemoryContext context);
87 extern void MemoryContextStatsDetail(MemoryContext context, int max_children,
88 bool print_to_stderr);
89 extern void MemoryContextAllowInCriticalSection(MemoryContext context,
90 bool allow);
91
92 #ifdef MEMORY_CONTEXT_CHECKING
93 extern void MemoryContextCheck(MemoryContext context);
94 #endif
95 extern bool MemoryContextContains(MemoryContext context, void *pointer);
96
97 /* Handy macro for copying and assigning context ID ... but note double eval */
98 #define MemoryContextCopyAndSetIdentifier(cxt, id) \
99 MemoryContextSetIdentifier(cxt, MemoryContextStrdup(cxt, id))
100
101 /*
102 * GetMemoryChunkContext
103 * Given a currently-allocated chunk, determine the context
104 * it belongs to.
105 *
106 * All chunks allocated by any memory context manager are required to be
107 * preceded by the corresponding MemoryContext stored, without padding, in the
108 * preceding sizeof(void*) bytes. A currently-allocated chunk must contain a
109 * backpointer to its owning context. The backpointer is used by pfree() and
110 * repalloc() to find the context to call.
111 */
112 #ifndef FRONTEND
113 static inline MemoryContext
GetMemoryChunkContext(void * pointer)114 GetMemoryChunkContext(void *pointer)
115 {
116 MemoryContext context;
117
118 /*
119 * Try to detect bogus pointers handed to us, poorly though we can.
120 * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
121 * allocated chunk.
122 */
123 Assert(pointer != NULL);
124 Assert(pointer == (void *) MAXALIGN(pointer));
125
126 /*
127 * OK, it's probably safe to look at the context.
128 */
129 context = *(MemoryContext *) (((char *) pointer) - sizeof(void *));
130
131 AssertArg(MemoryContextIsValid(context));
132
133 return context;
134 }
135 #endif
136
137 /*
138 * This routine handles the context-type-independent part of memory
139 * context creation. It's intended to be called from context-type-
140 * specific creation routines, and noplace else.
141 */
142 extern void MemoryContextCreate(MemoryContext node,
143 NodeTag tag,
144 const MemoryContextMethods *methods,
145 MemoryContext parent,
146 const char *name);
147
148 extern void HandleLogMemoryContextInterrupt(void);
149 extern void ProcessLogMemoryContextInterrupt(void);
150
151 /*
152 * Memory-context-type-specific functions
153 */
154
155 /* aset.c */
156 extern MemoryContext AllocSetContextCreateInternal(MemoryContext parent,
157 const char *name,
158 Size minContextSize,
159 Size initBlockSize,
160 Size maxBlockSize);
161
162 /*
163 * This wrapper macro exists to check for non-constant strings used as context
164 * names; that's no longer supported. (Use MemoryContextSetIdentifier if you
165 * want to provide a variable identifier.)
166 */
167 #ifdef HAVE__BUILTIN_CONSTANT_P
168 #define AllocSetContextCreate(parent, name, ...) \
169 (StaticAssertExpr(__builtin_constant_p(name), \
170 "memory context names must be constant strings"), \
171 AllocSetContextCreateInternal(parent, name, __VA_ARGS__))
172 #else
173 #define AllocSetContextCreate \
174 AllocSetContextCreateInternal
175 #endif
176
177 /* slab.c */
178 extern MemoryContext SlabContextCreate(MemoryContext parent,
179 const char *name,
180 Size blockSize,
181 Size chunkSize);
182
183 /* generation.c */
184 extern MemoryContext GenerationContextCreate(MemoryContext parent,
185 const char *name,
186 Size blockSize);
187
188 /*
189 * Recommended default alloc parameters, suitable for "ordinary" contexts
190 * that might hold quite a lot of data.
191 */
192 #define ALLOCSET_DEFAULT_MINSIZE 0
193 #define ALLOCSET_DEFAULT_INITSIZE (8 * 1024)
194 #define ALLOCSET_DEFAULT_MAXSIZE (8 * 1024 * 1024)
195 #define ALLOCSET_DEFAULT_SIZES \
196 ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE
197
198 /*
199 * Recommended alloc parameters for "small" contexts that are never expected
200 * to contain much data (for example, a context to contain a query plan).
201 */
202 #define ALLOCSET_SMALL_MINSIZE 0
203 #define ALLOCSET_SMALL_INITSIZE (1 * 1024)
204 #define ALLOCSET_SMALL_MAXSIZE (8 * 1024)
205 #define ALLOCSET_SMALL_SIZES \
206 ALLOCSET_SMALL_MINSIZE, ALLOCSET_SMALL_INITSIZE, ALLOCSET_SMALL_MAXSIZE
207
208 /*
209 * Recommended alloc parameters for contexts that should start out small,
210 * but might sometimes grow big.
211 */
212 #define ALLOCSET_START_SMALL_SIZES \
213 ALLOCSET_SMALL_MINSIZE, ALLOCSET_SMALL_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE
214
215
216 /*
217 * Threshold above which a request in an AllocSet context is certain to be
218 * allocated separately (and thereby have constant allocation overhead).
219 * Few callers should be interested in this, but tuplesort/tuplestore need
220 * to know it.
221 */
222 #define ALLOCSET_SEPARATE_THRESHOLD 8192
223
224 #define SLAB_DEFAULT_BLOCK_SIZE (8 * 1024)
225 #define SLAB_LARGE_BLOCK_SIZE (8 * 1024 * 1024)
226
227 #endif /* MEMUTILS_H */
228