PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
memutils.h
Go to the documentation of this file.
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-2024, 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/* Must be less than SIZE_MAX */
45#define MaxAllocHugeSize (SIZE_MAX / 2)
46
47#define InvalidAllocSize SIZE_MAX
48
49#define AllocHugeSizeIsValid(size) ((Size) (size) <= MaxAllocHugeSize)
50
51
52/*
53 * Standard top-level memory contexts.
54 *
55 * Only TopMemoryContext and ErrorContext are initialized by
56 * MemoryContextInit() itself.
57 */
65
66/* This is a transient link to the active portal's memory context: */
68
69
70/*
71 * Memory-context-type-independent functions in mcxt.c
72 */
73extern void MemoryContextInit(void);
79extern void MemoryContextSetIdentifier(MemoryContext context, const char *id);
81 MemoryContext new_parent);
82extern MemoryContext GetMemoryChunkContext(void *pointer);
83extern Size GetMemoryChunkSpace(void *pointer);
88 MemoryContextCounters *consumed);
91 int max_level, int max_children,
92 bool print_to_stderr);
94 bool allow);
95
96#ifdef MEMORY_CONTEXT_CHECKING
97extern void MemoryContextCheck(MemoryContext context);
98#endif
99
100/* Handy macro for copying and assigning context ID ... but note double eval */
101#define MemoryContextCopyAndSetIdentifier(cxt, id) \
102 MemoryContextSetIdentifier(cxt, MemoryContextStrdup(cxt, id))
103
104extern void HandleLogMemoryContextInterrupt(void);
105extern void ProcessLogMemoryContextInterrupt(void);
106
107/*
108 * Memory-context-type-specific functions
109 */
110
111/* aset.c */
113 const char *name,
114 Size minContextSize,
115 Size initBlockSize,
116 Size maxBlockSize);
117
118/*
119 * This wrapper macro exists to check for non-constant strings used as context
120 * names; that's no longer supported. (Use MemoryContextSetIdentifier if you
121 * want to provide a variable identifier.)
122 */
123#ifdef HAVE__BUILTIN_CONSTANT_P
124#define AllocSetContextCreate(parent, name, ...) \
125 (StaticAssertExpr(__builtin_constant_p(name), \
126 "memory context names must be constant strings"), \
127 AllocSetContextCreateInternal(parent, name, __VA_ARGS__))
128#else
129#define AllocSetContextCreate \
130 AllocSetContextCreateInternal
131#endif
132
133/* slab.c */
135 const char *name,
136 Size blockSize,
137 Size chunkSize);
138
139/* generation.c */
141 const char *name,
142 Size minContextSize,
143 Size initBlockSize,
144 Size maxBlockSize);
145
146/* bump.c */
148 const char *name,
149 Size minContextSize,
150 Size initBlockSize,
151 Size maxBlockSize);
152
153/*
154 * Recommended default alloc parameters, suitable for "ordinary" contexts
155 * that might hold quite a lot of data.
156 */
157#define ALLOCSET_DEFAULT_MINSIZE 0
158#define ALLOCSET_DEFAULT_INITSIZE (8 * 1024)
159#define ALLOCSET_DEFAULT_MAXSIZE (8 * 1024 * 1024)
160#define ALLOCSET_DEFAULT_SIZES \
161 ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE
162
163/*
164 * Recommended alloc parameters for "small" contexts that are never expected
165 * to contain much data (for example, a context to contain a query plan).
166 */
167#define ALLOCSET_SMALL_MINSIZE 0
168#define ALLOCSET_SMALL_INITSIZE (1 * 1024)
169#define ALLOCSET_SMALL_MAXSIZE (8 * 1024)
170#define ALLOCSET_SMALL_SIZES \
171 ALLOCSET_SMALL_MINSIZE, ALLOCSET_SMALL_INITSIZE, ALLOCSET_SMALL_MAXSIZE
172
173/*
174 * Recommended alloc parameters for contexts that should start out small,
175 * but might sometimes grow big.
176 */
177#define ALLOCSET_START_SMALL_SIZES \
178 ALLOCSET_SMALL_MINSIZE, ALLOCSET_SMALL_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE
179
180
181/*
182 * Threshold above which a request in an AllocSet context is certain to be
183 * allocated separately (and thereby have constant allocation overhead).
184 * Few callers should be interested in this, but tuplesort/tuplestore need
185 * to know it.
186 */
187#define ALLOCSET_SEPARATE_THRESHOLD 8192
188
189#define SLAB_DEFAULT_BLOCK_SIZE (8 * 1024)
190#define SLAB_LARGE_BLOCK_SIZE (8 * 1024 * 1024)
191
192/*
193 * pg_memory_is_all_zeros
194 *
195 * Test if a memory region starting at "ptr" and of size "len" is full of
196 * zeroes.
197 *
198 * The test is divided into multiple cases for safety reason and multiple
199 * phases for efficiency.
200 *
201 * Case 1: len < sizeof(size_t) bytes, then byte-by-byte comparison.
202 * Case 2: len < (sizeof(size_t) * 8 - 1) bytes:
203 * - Phase 1: byte-by-byte comparison, until the pointer is aligned.
204 * - Phase 2: size_t comparisons, with aligned pointers, up to the last
205 * location possible.
206 * - Phase 3: byte-by-byte comparison, until the end location.
207 * Case 3: len >= (sizeof(size_t) * 8) bytes, same as case 2 except that an
208 * additional phase is placed between Phase 1 and Phase 2, with
209 * (8 * sizeof(size_t)) comparisons using bitwise OR to encourage
210 * compilers to use SIMD instructions if available, up to the last
211 * aligned location possible.
212 *
213 * Case 1 and Case 2 are mandatory to ensure that we won't read beyond the
214 * memory area. This is portable for 32-bit and 64-bit architectures.
215 *
216 * Caller must ensure that "ptr" is not NULL.
217 */
218static inline bool
219pg_memory_is_all_zeros(const void *ptr, size_t len)
220{
221 const unsigned char *p = (const unsigned char *) ptr;
222 const unsigned char *end = &p[len];
223 const unsigned char *aligned_end = (const unsigned char *)
224 ((uintptr_t) end & (~(sizeof(size_t) - 1)));
225
226 if (len < sizeof(size_t))
227 {
228 while (p < end)
229 {
230 if (*p++ != 0)
231 return false;
232 }
233 return true;
234 }
235
236 /* "len" in the [sizeof(size_t), sizeof(size_t) * 8 - 1] range */
237 if (len < sizeof(size_t) * 8)
238 {
239 /* Compare bytes until the pointer "p" is aligned */
240 while (((uintptr_t) p & (sizeof(size_t) - 1)) != 0)
241 {
242 if (p == end)
243 return true;
244 if (*p++ != 0)
245 return false;
246 }
247
248 /*
249 * Compare remaining size_t-aligned chunks.
250 *
251 * There is no risk to read beyond the memory area, as "aligned_end"
252 * cannot be higher than "end".
253 */
254 for (; p < aligned_end; p += sizeof(size_t))
255 {
256 if (*(size_t *) p != 0)
257 return false;
258 }
259
260 /* Compare remaining bytes until the end */
261 while (p < end)
262 {
263 if (*p++ != 0)
264 return false;
265 }
266 return true;
267 }
268
269 /* "len" in the [sizeof(size_t) * 8, inf) range */
270
271 /* Compare bytes until the pointer "p" is aligned */
272 while (((uintptr_t) p & (sizeof(size_t) - 1)) != 0)
273 {
274 if (p == end)
275 return true;
276
277 if (*p++ != 0)
278 return false;
279 }
280
281 /*
282 * Compare 8 * sizeof(size_t) chunks at once.
283 *
284 * For performance reasons, we manually unroll this loop and purposefully
285 * use bitwise-ORs to combine each comparison. This prevents boolean
286 * short-circuiting and lets the compiler know that it's safe to access
287 * all 8 elements regardless of the result of the other comparisons. This
288 * seems to be enough to coax a few compilers into using SIMD
289 * instructions.
290 */
291 for (; p < aligned_end - (sizeof(size_t) * 7); p += sizeof(size_t) * 8)
292 {
293 if ((((size_t *) p)[0] != 0) | (((size_t *) p)[1] != 0) |
294 (((size_t *) p)[2] != 0) | (((size_t *) p)[3] != 0) |
295 (((size_t *) p)[4] != 0) | (((size_t *) p)[5] != 0) |
296 (((size_t *) p)[6] != 0) | (((size_t *) p)[7] != 0))
297 return false;
298 }
299
300 /*
301 * Compare remaining size_t-aligned chunks.
302 *
303 * There is no risk to read beyond the memory area, as "aligned_end"
304 * cannot be higher than "end".
305 */
306 for (; p < aligned_end; p += sizeof(size_t))
307 {
308 if (*(size_t *) p != 0)
309 return false;
310 }
311
312 /* Compare remaining bytes until the end */
313 while (p < end)
314 {
315 if (*p++ != 0)
316 return false;
317 }
318
319 return true;
320}
321
322#endif /* MEMUTILS_H */
#define PGDLLIMPORT
Definition: c.h:1274
size_t Size
Definition: c.h:559
PGDLLIMPORT MemoryContext CurTransactionContext
Definition: mcxt.c:155
bool MemoryContextIsEmpty(MemoryContext context)
Definition: mcxt.c:743
void MemoryContextMemConsumed(MemoryContext context, MemoryContextCounters *consumed)
Definition: mcxt.c:786
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:383
PGDLLIMPORT MemoryContext MessageContext
Definition: mcxt.c:153
PGDLLIMPORT MemoryContext TopMemoryContext
Definition: mcxt.c:149
PGDLLIMPORT MemoryContext TopTransactionContext
Definition: mcxt.c:154
void HandleLogMemoryContextInterrupt(void)
Definition: mcxt.c:1272
void MemoryContextSetParent(MemoryContext context, MemoryContext new_parent)
Definition: mcxt.c:637
Size GetMemoryChunkSpace(void *pointer)
Definition: mcxt.c:721
void MemoryContextDeleteChildren(MemoryContext context)
Definition: mcxt.c:539
MemoryContext GetMemoryChunkContext(void *pointer)
Definition: mcxt.c:707
PGDLLIMPORT MemoryContext PostmasterContext
Definition: mcxt.c:151
void MemoryContextStatsDetail(MemoryContext context, int max_level, int max_children, bool print_to_stderr)
Definition: mcxt.c:829
Size MemoryContextMemAllocated(MemoryContext context, bool recurse)
Definition: mcxt.c:762
void MemoryContextStats(MemoryContext context)
Definition: mcxt.c:814
MemoryContext SlabContextCreate(MemoryContext parent, const char *name, Size blockSize, Size chunkSize)
Definition: slab.c:322
void MemoryContextInit(void)
Definition: mcxt.c:339
MemoryContext BumpContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: bump.c:131
PGDLLIMPORT MemoryContext CacheMemoryContext
Definition: mcxt.c:152
MemoryContext MemoryContextGetParent(MemoryContext context)
Definition: mcxt.c:731
void ProcessLogMemoryContextInterrupt(void)
Definition: mcxt.c:1289
PGDLLIMPORT MemoryContext PortalContext
Definition: mcxt.c:158
MemoryContext GenerationContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: generation.c:160
static bool pg_memory_is_all_zeros(const void *ptr, size_t len)
Definition: memutils.h:219
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:454
void MemoryContextAllowInCriticalSection(MemoryContext context, bool allow)
Definition: mcxt.c:694
void MemoryContextResetChildren(MemoryContext context)
Definition: mcxt.c:433
void MemoryContextSetIdentifier(MemoryContext context, const char *id)
Definition: mcxt.c:612
void MemoryContextResetOnly(MemoryContext context)
Definition: mcxt.c:402
PGDLLIMPORT MemoryContext ErrorContext
Definition: mcxt.c:150
MemoryContext AllocSetContextCreateInternal(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:347
const void size_t len
tree context
Definition: radixtree.h:1837
const char * name