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-2017, 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 MemoryContextSetParent(MemoryContext context,
80 					   MemoryContext new_parent);
81 extern Size GetMemoryChunkSpace(void *pointer);
82 extern MemoryContext MemoryContextGetParent(MemoryContext context);
83 extern bool MemoryContextIsEmpty(MemoryContext context);
84 extern void MemoryContextStats(MemoryContext context);
85 extern void MemoryContextStatsDetail(MemoryContext context, int max_children);
86 extern void MemoryContextAllowInCriticalSection(MemoryContext context,
87 									bool allow);
88 
89 #ifdef MEMORY_CONTEXT_CHECKING
90 extern void MemoryContextCheck(MemoryContext context);
91 #endif
92 extern bool MemoryContextContains(MemoryContext context, void *pointer);
93 
94 /*
95  * GetMemoryChunkContext
96  *		Given a currently-allocated chunk, determine the context
97  *		it belongs to.
98  *
99  * All chunks allocated by any memory context manager are required to be
100  * preceded by the corresponding MemoryContext stored, without padding, in the
101  * preceding sizeof(void*) bytes.  A currently-allocated chunk must contain a
102  * backpointer to its owning context.  The backpointer is used by pfree() and
103  * repalloc() to find the context to call.
104  */
105 #ifndef FRONTEND
106 static inline MemoryContext
GetMemoryChunkContext(void * pointer)107 GetMemoryChunkContext(void *pointer)
108 {
109 	MemoryContext context;
110 
111 	/*
112 	 * Try to detect bogus pointers handed to us, poorly though we can.
113 	 * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
114 	 * allocated chunk.
115 	 */
116 	Assert(pointer != NULL);
117 	Assert(pointer == (void *) MAXALIGN(pointer));
118 
119 	/*
120 	 * OK, it's probably safe to look at the context.
121 	 */
122 	context = *(MemoryContext *) (((char *) pointer) - sizeof(void *));
123 
124 	AssertArg(MemoryContextIsValid(context));
125 
126 	return context;
127 }
128 #endif
129 
130 /*
131  * This routine handles the context-type-independent part of memory
132  * context creation.  It's intended to be called from context-type-
133  * specific creation routines, and noplace else.
134  */
135 extern MemoryContext MemoryContextCreate(NodeTag tag, Size size,
136 					MemoryContextMethods *methods,
137 					MemoryContext parent,
138 					const char *name);
139 
140 
141 /*
142  * Memory-context-type-specific functions
143  */
144 
145 /* aset.c */
146 extern MemoryContext AllocSetContextCreate(MemoryContext parent,
147 					  const char *name,
148 					  Size minContextSize,
149 					  Size initBlockSize,
150 					  Size maxBlockSize);
151 
152 /* slab.c */
153 extern MemoryContext SlabContextCreate(MemoryContext parent,
154 				  const char *name,
155 				  Size blockSize,
156 				  Size chunkSize);
157 
158 /*
159  * Recommended default alloc parameters, suitable for "ordinary" contexts
160  * that might hold quite a lot of data.
161  */
162 #define ALLOCSET_DEFAULT_MINSIZE   0
163 #define ALLOCSET_DEFAULT_INITSIZE  (8 * 1024)
164 #define ALLOCSET_DEFAULT_MAXSIZE   (8 * 1024 * 1024)
165 #define ALLOCSET_DEFAULT_SIZES \
166 	ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE
167 
168 /*
169  * Recommended alloc parameters for "small" contexts that are never expected
170  * to contain much data (for example, a context to contain a query plan).
171  */
172 #define ALLOCSET_SMALL_MINSIZE	 0
173 #define ALLOCSET_SMALL_INITSIZE  (1 * 1024)
174 #define ALLOCSET_SMALL_MAXSIZE	 (8 * 1024)
175 #define ALLOCSET_SMALL_SIZES \
176 	ALLOCSET_SMALL_MINSIZE, ALLOCSET_SMALL_INITSIZE, ALLOCSET_SMALL_MAXSIZE
177 
178 /*
179  * Recommended alloc parameters for contexts that should start out small,
180  * but might sometimes grow big.
181  */
182 #define ALLOCSET_START_SMALL_SIZES \
183 	ALLOCSET_SMALL_MINSIZE, ALLOCSET_SMALL_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE
184 
185 
186 /*
187  * Threshold above which a request in an AllocSet context is certain to be
188  * allocated separately (and thereby have constant allocation overhead).
189  * Few callers should be interested in this, but tuplesort/tuplestore need
190  * to know it.
191  */
192 #define ALLOCSET_SEPARATE_THRESHOLD  8192
193 
194 #define SLAB_DEFAULT_BLOCK_SIZE		(8 * 1024)
195 #define SLAB_LARGE_BLOCK_SIZE		(8 * 1024 * 1024)
196 
197 #endif							/* MEMUTILS_H */
198