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 | */ |
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 void MemoryContextStats(MemoryContext context); |
86 | extern void MemoryContextStatsDetail(MemoryContext context, int max_children); |
87 | extern void MemoryContextAllowInCriticalSection(MemoryContext context, |
88 | bool allow); |
89 | |
90 | #ifdef MEMORY_CONTEXT_CHECKING |
91 | extern void MemoryContextCheck(MemoryContext context); |
92 | #endif |
93 | extern 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 |
111 | static inline MemoryContext |
112 | GetMemoryChunkContext(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 | */ |
140 | extern 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 */ |
152 | extern 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 */ |
174 | extern MemoryContext SlabContextCreate(MemoryContext parent, |
175 | const char *name, |
176 | Size blockSize, |
177 | Size chunkSize); |
178 | |
179 | /* generation.c */ |
180 | extern 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 | |