PostgreSQL Source Code git master
memutils.h File Reference
#include "nodes/memnodes.h"
Include dependency graph for memutils.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define MaxAllocSize   ((Size) 0x3fffffff) /* 1 gigabyte - 1 */
 
#define AllocSizeIsValid(size)   ((Size) (size) <= MaxAllocSize)
 
#define MaxAllocHugeSize   (SIZE_MAX / 2)
 
#define InvalidAllocSize   SIZE_MAX
 
#define AllocHugeSizeIsValid(size)   ((Size) (size) <= MaxAllocHugeSize)
 
#define MemoryContextCopyAndSetIdentifier(cxt, id)    MemoryContextSetIdentifier(cxt, MemoryContextStrdup(cxt, id))
 
#define AllocSetContextCreate    AllocSetContextCreateInternal
 
#define ALLOCSET_DEFAULT_MINSIZE   0
 
#define ALLOCSET_DEFAULT_INITSIZE   (8 * 1024)
 
#define ALLOCSET_DEFAULT_MAXSIZE   (8 * 1024 * 1024)
 
#define ALLOCSET_DEFAULT_SIZES    ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE
 
#define ALLOCSET_SMALL_MINSIZE   0
 
#define ALLOCSET_SMALL_INITSIZE   (1 * 1024)
 
#define ALLOCSET_SMALL_MAXSIZE   (8 * 1024)
 
#define ALLOCSET_SMALL_SIZES    ALLOCSET_SMALL_MINSIZE, ALLOCSET_SMALL_INITSIZE, ALLOCSET_SMALL_MAXSIZE
 
#define ALLOCSET_START_SMALL_SIZES    ALLOCSET_SMALL_MINSIZE, ALLOCSET_SMALL_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE
 
#define ALLOCSET_SEPARATE_THRESHOLD   8192
 
#define SLAB_DEFAULT_BLOCK_SIZE   (8 * 1024)
 
#define SLAB_LARGE_BLOCK_SIZE   (8 * 1024 * 1024)
 

Functions

void MemoryContextInit (void)
 
void MemoryContextReset (MemoryContext context)
 
void MemoryContextDelete (MemoryContext context)
 
void MemoryContextResetOnly (MemoryContext context)
 
void MemoryContextResetChildren (MemoryContext context)
 
void MemoryContextDeleteChildren (MemoryContext context)
 
void MemoryContextSetIdentifier (MemoryContext context, const char *id)
 
void MemoryContextSetParent (MemoryContext context, MemoryContext new_parent)
 
MemoryContext GetMemoryChunkContext (void *pointer)
 
Size GetMemoryChunkSpace (void *pointer)
 
MemoryContext MemoryContextGetParent (MemoryContext context)
 
bool MemoryContextIsEmpty (MemoryContext context)
 
Size MemoryContextMemAllocated (MemoryContext context, bool recurse)
 
void MemoryContextMemConsumed (MemoryContext context, MemoryContextCounters *consumed)
 
void MemoryContextStats (MemoryContext context)
 
void MemoryContextStatsDetail (MemoryContext context, int max_level, int max_children, bool print_to_stderr)
 
void MemoryContextAllowInCriticalSection (MemoryContext context, bool allow)
 
void HandleLogMemoryContextInterrupt (void)
 
void ProcessLogMemoryContextInterrupt (void)
 
MemoryContext AllocSetContextCreateInternal (MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
 
MemoryContext SlabContextCreate (MemoryContext parent, const char *name, Size blockSize, Size chunkSize)
 
MemoryContext GenerationContextCreate (MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
 
MemoryContext BumpContextCreate (MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
 
static bool pg_memory_is_all_zeros (const void *ptr, size_t len)
 

Variables

PGDLLIMPORT MemoryContext TopMemoryContext
 
PGDLLIMPORT MemoryContext ErrorContext
 
PGDLLIMPORT MemoryContext PostmasterContext
 
PGDLLIMPORT MemoryContext CacheMemoryContext
 
PGDLLIMPORT MemoryContext MessageContext
 
PGDLLIMPORT MemoryContext TopTransactionContext
 
PGDLLIMPORT MemoryContext CurTransactionContext
 
PGDLLIMPORT MemoryContext PortalContext
 

Macro Definition Documentation

◆ AllocHugeSizeIsValid

#define AllocHugeSizeIsValid (   size)    ((Size) (size) <= MaxAllocHugeSize)

Definition at line 49 of file memutils.h.

◆ ALLOCSET_DEFAULT_INITSIZE

#define ALLOCSET_DEFAULT_INITSIZE   (8 * 1024)

Definition at line 158 of file memutils.h.

◆ ALLOCSET_DEFAULT_MAXSIZE

#define ALLOCSET_DEFAULT_MAXSIZE   (8 * 1024 * 1024)

Definition at line 159 of file memutils.h.

◆ ALLOCSET_DEFAULT_MINSIZE

#define ALLOCSET_DEFAULT_MINSIZE   0

Definition at line 157 of file memutils.h.

◆ ALLOCSET_DEFAULT_SIZES

Definition at line 160 of file memutils.h.

◆ ALLOCSET_SEPARATE_THRESHOLD

#define ALLOCSET_SEPARATE_THRESHOLD   8192

Definition at line 187 of file memutils.h.

◆ ALLOCSET_SMALL_INITSIZE

#define ALLOCSET_SMALL_INITSIZE   (1 * 1024)

Definition at line 168 of file memutils.h.

◆ ALLOCSET_SMALL_MAXSIZE

#define ALLOCSET_SMALL_MAXSIZE   (8 * 1024)

Definition at line 169 of file memutils.h.

◆ ALLOCSET_SMALL_MINSIZE

#define ALLOCSET_SMALL_MINSIZE   0

Definition at line 167 of file memutils.h.

◆ ALLOCSET_SMALL_SIZES

Definition at line 170 of file memutils.h.

◆ ALLOCSET_START_SMALL_SIZES

#define ALLOCSET_START_SMALL_SIZES    ALLOCSET_SMALL_MINSIZE, ALLOCSET_SMALL_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE

Definition at line 177 of file memutils.h.

◆ AllocSetContextCreate

#define AllocSetContextCreate    AllocSetContextCreateInternal

Definition at line 129 of file memutils.h.

◆ AllocSizeIsValid

#define AllocSizeIsValid (   size)    ((Size) (size) <= MaxAllocSize)

Definition at line 42 of file memutils.h.

◆ InvalidAllocSize

#define InvalidAllocSize   SIZE_MAX

Definition at line 47 of file memutils.h.

◆ MaxAllocHugeSize

#define MaxAllocHugeSize   (SIZE_MAX / 2)

Definition at line 45 of file memutils.h.

◆ MaxAllocSize

#define MaxAllocSize   ((Size) 0x3fffffff) /* 1 gigabyte - 1 */

Definition at line 40 of file memutils.h.

◆ MemoryContextCopyAndSetIdentifier

#define MemoryContextCopyAndSetIdentifier (   cxt,
  id 
)     MemoryContextSetIdentifier(cxt, MemoryContextStrdup(cxt, id))

Definition at line 101 of file memutils.h.

◆ SLAB_DEFAULT_BLOCK_SIZE

#define SLAB_DEFAULT_BLOCK_SIZE   (8 * 1024)

Definition at line 189 of file memutils.h.

◆ SLAB_LARGE_BLOCK_SIZE

#define SLAB_LARGE_BLOCK_SIZE   (8 * 1024 * 1024)

Definition at line 190 of file memutils.h.

Function Documentation

◆ AllocSetContextCreateInternal()

MemoryContext AllocSetContextCreateInternal ( MemoryContext  parent,
const char *  name,
Size  minContextSize,
Size  initBlockSize,
Size  maxBlockSize 
)

Definition at line 347 of file aset.c.

352{
353 int freeListIndex;
354 Size firstBlockSize;
355 AllocSet set;
356 AllocBlock block;
357
358 /* ensure MemoryChunk's size is properly maxaligned */
360 "sizeof(MemoryChunk) is not maxaligned");
361 /* check we have enough space to store the freelist link */
363 "sizeof(AllocFreeListLink) larger than minimum allocation size");
364
365 /*
366 * First, validate allocation parameters. Once these were regular runtime
367 * tests and elog's, but in practice Asserts seem sufficient because
368 * nobody varies their parameters at runtime. We somewhat arbitrarily
369 * enforce a minimum 1K block size. We restrict the maximum block size to
370 * MEMORYCHUNK_MAX_BLOCKOFFSET as MemoryChunks are limited to this in
371 * regards to addressing the offset between the chunk and the block that
372 * the chunk is stored on. We would be unable to store the offset between
373 * the chunk and block for any chunks that were beyond
374 * MEMORYCHUNK_MAX_BLOCKOFFSET bytes into the block if the block was to be
375 * larger than this.
376 */
377 Assert(initBlockSize == MAXALIGN(initBlockSize) &&
378 initBlockSize >= 1024);
379 Assert(maxBlockSize == MAXALIGN(maxBlockSize) &&
380 maxBlockSize >= initBlockSize &&
381 AllocHugeSizeIsValid(maxBlockSize)); /* must be safe to double */
382 Assert(minContextSize == 0 ||
383 (minContextSize == MAXALIGN(minContextSize) &&
384 minContextSize >= 1024 &&
385 minContextSize <= maxBlockSize));
386 Assert(maxBlockSize <= MEMORYCHUNK_MAX_BLOCKOFFSET);
387
388 /*
389 * Check whether the parameters match either available freelist. We do
390 * not need to demand a match of maxBlockSize.
391 */
392 if (minContextSize == ALLOCSET_DEFAULT_MINSIZE &&
393 initBlockSize == ALLOCSET_DEFAULT_INITSIZE)
394 freeListIndex = 0;
395 else if (minContextSize == ALLOCSET_SMALL_MINSIZE &&
396 initBlockSize == ALLOCSET_SMALL_INITSIZE)
397 freeListIndex = 1;
398 else
399 freeListIndex = -1;
400
401 /*
402 * If a suitable freelist entry exists, just recycle that context.
403 */
404 if (freeListIndex >= 0)
405 {
406 AllocSetFreeList *freelist = &context_freelists[freeListIndex];
407
408 if (freelist->first_free != NULL)
409 {
410 /* Remove entry from freelist */
411 set = freelist->first_free;
412 freelist->first_free = (AllocSet) set->header.nextchild;
413 freelist->num_free--;
414
415 /* Update its maxBlockSize; everything else should be OK */
416 set->maxBlockSize = maxBlockSize;
417
418 /* Reinitialize its header, installing correct name and parent */
420 T_AllocSetContext,
422 parent,
423 name);
424
425 ((MemoryContext) set)->mem_allocated =
426 KeeperBlock(set)->endptr - ((char *) set);
427
428 return (MemoryContext) set;
429 }
430 }
431
432 /* Determine size of initial block */
433 firstBlockSize = MAXALIGN(sizeof(AllocSetContext)) +
435 if (minContextSize != 0)
436 firstBlockSize = Max(firstBlockSize, minContextSize);
437 else
438 firstBlockSize = Max(firstBlockSize, initBlockSize);
439
440 /*
441 * Allocate the initial block. Unlike other aset.c blocks, it starts with
442 * the context header and its block header follows that.
443 */
444 set = (AllocSet) malloc(firstBlockSize);
445 if (set == NULL)
446 {
450 (errcode(ERRCODE_OUT_OF_MEMORY),
451 errmsg("out of memory"),
452 errdetail("Failed while creating memory context \"%s\".",
453 name)));
454 }
455
456 /*
457 * Avoid writing code that can fail between here and MemoryContextCreate;
458 * we'd leak the header/initial block if we ereport in this stretch.
459 */
460
461 /* Fill in the initial block's block header */
462 block = KeeperBlock(set);
463 block->aset = set;
464 block->freeptr = ((char *) block) + ALLOC_BLOCKHDRSZ;
465 block->endptr = ((char *) set) + firstBlockSize;
466 block->prev = NULL;
467 block->next = NULL;
468
469 /* Mark unallocated space NOACCESS; leave the block header alone. */
470 VALGRIND_MAKE_MEM_NOACCESS(block->freeptr, block->endptr - block->freeptr);
471
472 /* Remember block as part of block list */
473 set->blocks = block;
474
475 /* Finish filling in aset-specific parts of the context header */
476 MemSetAligned(set->freelist, 0, sizeof(set->freelist));
477
478 set->initBlockSize = (uint32) initBlockSize;
479 set->maxBlockSize = (uint32) maxBlockSize;
480 set->nextBlockSize = (uint32) initBlockSize;
481 set->freeListIndex = freeListIndex;
482
483 /*
484 * Compute the allocation chunk size limit for this context. It can't be
485 * more than ALLOC_CHUNK_LIMIT because of the fixed number of freelists.
486 * If maxBlockSize is small then requests exceeding the maxBlockSize, or
487 * even a significant fraction of it, should be treated as large chunks
488 * too. For the typical case of maxBlockSize a power of 2, the chunk size
489 * limit will be at most 1/8th maxBlockSize, so that given a stream of
490 * requests that are all the maximum chunk size we will waste at most
491 * 1/8th of the allocated space.
492 *
493 * Also, allocChunkLimit must not exceed ALLOCSET_SEPARATE_THRESHOLD.
494 */
496 "ALLOC_CHUNK_LIMIT != ALLOCSET_SEPARATE_THRESHOLD");
497
498 /*
499 * Determine the maximum size that a chunk can be before we allocate an
500 * entire AllocBlock dedicated for that chunk. We set the absolute limit
501 * of that size as ALLOC_CHUNK_LIMIT but we reduce it further so that we
502 * can fit about ALLOC_CHUNK_FRACTION chunks this size on a maximally
503 * sized block. (We opt to keep allocChunkLimit a power-of-2 value
504 * primarily for legacy reasons rather than calculating it so that exactly
505 * ALLOC_CHUNK_FRACTION chunks fit on a maximally sized block.)
506 */
508 while ((Size) (set->allocChunkLimit + ALLOC_CHUNKHDRSZ) >
509 (Size) ((maxBlockSize - ALLOC_BLOCKHDRSZ) / ALLOC_CHUNK_FRACTION))
510 set->allocChunkLimit >>= 1;
511
512 /* Finally, do the type-independent part of context creation */
514 T_AllocSetContext,
516 parent,
517 name);
518
519 ((MemoryContext) set)->mem_allocated = firstBlockSize;
520
521 return (MemoryContext) set;
522}
#define ALLOC_CHUNKHDRSZ
Definition: aset.c:105
#define KeeperBlock(set)
Definition: aset.c:244
#define ALLOC_MINBITS
Definition: aset.c:83
#define ALLOC_BLOCKHDRSZ
Definition: aset.c:104
#define ALLOC_CHUNK_FRACTION
Definition: aset.c:87
#define ALLOC_CHUNK_LIMIT
Definition: aset.c:85
static AllocSetFreeList context_freelists[2]
Definition: aset.c:257
AllocSetContext * AllocSet
Definition: aset.c:167
#define MAXALIGN(LEN)
Definition: c.h:765
#define Max(x, y)
Definition: c.h:952
#define Assert(condition)
Definition: c.h:812
#define MemSetAligned(start, val, len)
Definition: c.h:1004
uint32_t uint32
Definition: c.h:485
#define StaticAssertDecl(condition, errmessage)
Definition: c.h:890
#define StaticAssertStmt(condition, errmessage)
Definition: c.h:892
size_t Size
Definition: c.h:559
int errdetail(const char *fmt,...)
Definition: elog.c:1203
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
#define malloc(a)
Definition: header.h:50
void MemoryContextCreate(MemoryContext node, NodeTag tag, MemoryContextMethodID method_id, MemoryContext parent, const char *name)
Definition: mcxt.c:1100
MemoryContext TopMemoryContext
Definition: mcxt.c:149
void MemoryContextStats(MemoryContext context)
Definition: mcxt.c:814
#define VALGRIND_MAKE_MEM_NOACCESS(addr, size)
Definition: memdebug.h:27
#define ALLOCSET_SMALL_MINSIZE
Definition: memutils.h:167
#define ALLOCSET_DEFAULT_MINSIZE
Definition: memutils.h:157
#define AllocHugeSizeIsValid(size)
Definition: memutils.h:49
#define ALLOCSET_SEPARATE_THRESHOLD
Definition: memutils.h:187
#define ALLOCSET_SMALL_INITSIZE
Definition: memutils.h:168
#define ALLOCSET_DEFAULT_INITSIZE
Definition: memutils.h:158
@ MCTX_ASET_ID
#define MEMORYCHUNK_MAX_BLOCKOFFSET
struct MemoryContextData * MemoryContext
Definition: palloc.h:36
AllocBlock prev
Definition: aset.c:184
AllocSet aset
Definition: aset.c:183
char * freeptr
Definition: aset.c:186
AllocBlock next
Definition: aset.c:185
char * endptr
Definition: aset.c:187
uint32 initBlockSize
Definition: aset.c:159
uint32 maxBlockSize
Definition: aset.c:160
uint32 allocChunkLimit
Definition: aset.c:162
MemoryContextData header
Definition: aset.c:154
int freeListIndex
Definition: aset.c:164
AllocBlock blocks
Definition: aset.c:156
uint32 nextBlockSize
Definition: aset.c:161
MemoryChunk * freelist[ALLOCSET_NUM_FREELISTS]
Definition: aset.c:157
int num_free
Definition: aset.c:252
AllocSetContext * first_free
Definition: aset.c:253
MemoryContext nextchild
Definition: memnodes.h:130
const char * name

References ALLOC_BLOCKHDRSZ, ALLOC_CHUNK_FRACTION, ALLOC_CHUNK_LIMIT, ALLOC_CHUNKHDRSZ, ALLOC_MINBITS, AllocSetContext::allocChunkLimit, AllocHugeSizeIsValid, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_SEPARATE_THRESHOLD, ALLOCSET_SMALL_INITSIZE, ALLOCSET_SMALL_MINSIZE, AllocBlockData::aset, Assert, AllocSetContext::blocks, context_freelists, AllocBlockData::endptr, ereport, errcode(), errdetail(), errmsg(), ERROR, AllocSetFreeList::first_free, AllocSetContext::freelist, AllocSetContext::freeListIndex, AllocBlockData::freeptr, AllocSetContext::header, AllocSetContext::initBlockSize, KeeperBlock, malloc, Max, MAXALIGN, AllocSetContext::maxBlockSize, MCTX_ASET_ID, MEMORYCHUNK_MAX_BLOCKOFFSET, MemoryContextCreate(), MemoryContextStats(), MemSetAligned, name, AllocBlockData::next, AllocSetContext::nextBlockSize, MemoryContextData::nextchild, AllocSetFreeList::num_free, AllocBlockData::prev, StaticAssertDecl, StaticAssertStmt, TopMemoryContext, and VALGRIND_MAKE_MEM_NOACCESS.

◆ BumpContextCreate()

MemoryContext BumpContextCreate ( MemoryContext  parent,
const char *  name,
Size  minContextSize,
Size  initBlockSize,
Size  maxBlockSize 
)

Definition at line 131 of file bump.c.

133{
134 Size firstBlockSize;
135 Size allocSize;
136 BumpContext *set;
137 BumpBlock *block;
138
139 /* ensure MemoryChunk's size is properly maxaligned */
141 "sizeof(MemoryChunk) is not maxaligned");
142
143 /*
144 * First, validate allocation parameters. Asserts seem sufficient because
145 * nobody varies their parameters at runtime. We somewhat arbitrarily
146 * enforce a minimum 1K block size. We restrict the maximum block size to
147 * MEMORYCHUNK_MAX_BLOCKOFFSET as MemoryChunks are limited to this in
148 * regards to addressing the offset between the chunk and the block that
149 * the chunk is stored on. We would be unable to store the offset between
150 * the chunk and block for any chunks that were beyond
151 * MEMORYCHUNK_MAX_BLOCKOFFSET bytes into the block if the block was to be
152 * larger than this.
153 */
154 Assert(initBlockSize == MAXALIGN(initBlockSize) &&
155 initBlockSize >= 1024);
156 Assert(maxBlockSize == MAXALIGN(maxBlockSize) &&
157 maxBlockSize >= initBlockSize &&
158 AllocHugeSizeIsValid(maxBlockSize)); /* must be safe to double */
159 Assert(minContextSize == 0 ||
160 (minContextSize == MAXALIGN(minContextSize) &&
161 minContextSize >= 1024 &&
162 minContextSize <= maxBlockSize));
163 Assert(maxBlockSize <= MEMORYCHUNK_MAX_BLOCKOFFSET);
164
165 /* Determine size of initial block */
166 allocSize = MAXALIGN(sizeof(BumpContext)) + Bump_BLOCKHDRSZ +
168 if (minContextSize != 0)
169 allocSize = Max(allocSize, minContextSize);
170 else
171 allocSize = Max(allocSize, initBlockSize);
172
173 /*
174 * Allocate the initial block. Unlike other bump.c blocks, it starts with
175 * the context header and its block header follows that.
176 */
177 set = (BumpContext *) malloc(allocSize);
178 if (set == NULL)
179 {
182 (errcode(ERRCODE_OUT_OF_MEMORY),
183 errmsg("out of memory"),
184 errdetail("Failed while creating memory context \"%s\".",
185 name)));
186 }
187
188 /*
189 * Avoid writing code that can fail between here and MemoryContextCreate;
190 * we'd leak the header and initial block if we ereport in this stretch.
191 */
192 dlist_init(&set->blocks);
193
194 /* Fill in the initial block's block header */
195 block = KeeperBlock(set);
196 /* determine the block size and initialize it */
197 firstBlockSize = allocSize - MAXALIGN(sizeof(BumpContext));
198 BumpBlockInit(set, block, firstBlockSize);
199
200 /* add it to the doubly-linked list of blocks */
201 dlist_push_head(&set->blocks, &block->node);
202
203 /*
204 * Fill in BumpContext-specific header fields. The Asserts above should
205 * ensure that these all fit inside a uint32.
206 */
207 set->initBlockSize = (uint32) initBlockSize;
208 set->maxBlockSize = (uint32) maxBlockSize;
209 set->nextBlockSize = (uint32) initBlockSize;
210
211 /*
212 * Compute the allocation chunk size limit for this context.
213 *
214 * Limit the maximum size a non-dedicated chunk can be so that we can fit
215 * at least Bump_CHUNK_FRACTION of chunks this big onto the maximum sized
216 * block. We must further limit this value so that it's no more than
217 * MEMORYCHUNK_MAX_VALUE. We're unable to have non-external chunks larger
218 * than that value as we store the chunk size in the MemoryChunk 'value'
219 * field in the call to MemoryChunkSetHdrMask().
220 */
221 set->allocChunkLimit = Min(maxBlockSize, MEMORYCHUNK_MAX_VALUE);
222 while ((Size) (set->allocChunkLimit + Bump_CHUNKHDRSZ) >
223 (Size) ((Size) (maxBlockSize - Bump_BLOCKHDRSZ) / Bump_CHUNK_FRACTION))
224 set->allocChunkLimit >>= 1;
225
226 /* Finally, do the type-independent part of context creation */
227 MemoryContextCreate((MemoryContext) set, T_BumpContext, MCTX_BUMP_ID,
228 parent, name);
229
230 ((MemoryContext) set)->mem_allocated = allocSize;
231
232 return (MemoryContext) set;
233}
#define Bump_CHUNK_FRACTION
Definition: bump.c:57
#define KeeperBlock(set)
Definition: bump.c:60
#define Bump_CHUNKHDRSZ
Definition: bump.c:54
static void BumpBlockInit(BumpContext *context, BumpBlock *block, Size blksize)
Definition: bump.c:535
#define Bump_BLOCKHDRSZ
Definition: bump.c:48
#define Min(x, y)
Definition: c.h:958
static void dlist_init(dlist_head *head)
Definition: ilist.h:314
static void dlist_push_head(dlist_head *head, dlist_node *node)
Definition: ilist.h:347
@ MCTX_BUMP_ID
#define MEMORYCHUNK_MAX_VALUE
Definition: bump.c:87
dlist_node node
Definition: bump.c:88
dlist_head blocks
Definition: bump.c:76
uint32 initBlockSize
Definition: bump.c:71
uint32 maxBlockSize
Definition: bump.c:72
uint32 nextBlockSize
Definition: bump.c:73
uint32 allocChunkLimit
Definition: bump.c:74

References BumpContext::allocChunkLimit, AllocHugeSizeIsValid, Assert, BumpContext::blocks, Bump_BLOCKHDRSZ, Bump_CHUNK_FRACTION, Bump_CHUNKHDRSZ, BumpBlockInit(), dlist_init(), dlist_push_head(), ereport, errcode(), errdetail(), errmsg(), ERROR, BumpContext::initBlockSize, KeeperBlock, malloc, Max, MAXALIGN, BumpContext::maxBlockSize, MCTX_BUMP_ID, MEMORYCHUNK_MAX_BLOCKOFFSET, MEMORYCHUNK_MAX_VALUE, MemoryContextCreate(), MemoryContextStats(), Min, name, BumpContext::nextBlockSize, BumpBlock::node, StaticAssertDecl, and TopMemoryContext.

Referenced by TidStoreCreateLocal(), and tuplesort_begin_batch().

◆ GenerationContextCreate()

MemoryContext GenerationContextCreate ( MemoryContext  parent,
const char *  name,
Size  minContextSize,
Size  initBlockSize,
Size  maxBlockSize 
)

Definition at line 160 of file generation.c.

165{
166 Size firstBlockSize;
167 Size allocSize;
169 GenerationBlock *block;
170
171 /* ensure MemoryChunk's size is properly maxaligned */
173 "sizeof(MemoryChunk) is not maxaligned");
174
175 /*
176 * First, validate allocation parameters. Asserts seem sufficient because
177 * nobody varies their parameters at runtime. We somewhat arbitrarily
178 * enforce a minimum 1K block size. We restrict the maximum block size to
179 * MEMORYCHUNK_MAX_BLOCKOFFSET as MemoryChunks are limited to this in
180 * regards to addressing the offset between the chunk and the block that
181 * the chunk is stored on. We would be unable to store the offset between
182 * the chunk and block for any chunks that were beyond
183 * MEMORYCHUNK_MAX_BLOCKOFFSET bytes into the block if the block was to be
184 * larger than this.
185 */
186 Assert(initBlockSize == MAXALIGN(initBlockSize) &&
187 initBlockSize >= 1024);
188 Assert(maxBlockSize == MAXALIGN(maxBlockSize) &&
189 maxBlockSize >= initBlockSize &&
190 AllocHugeSizeIsValid(maxBlockSize)); /* must be safe to double */
191 Assert(minContextSize == 0 ||
192 (minContextSize == MAXALIGN(minContextSize) &&
193 minContextSize >= 1024 &&
194 minContextSize <= maxBlockSize));
195 Assert(maxBlockSize <= MEMORYCHUNK_MAX_BLOCKOFFSET);
196
197 /* Determine size of initial block */
198 allocSize = MAXALIGN(sizeof(GenerationContext)) +
200 if (minContextSize != 0)
201 allocSize = Max(allocSize, minContextSize);
202 else
203 allocSize = Max(allocSize, initBlockSize);
204
205 /*
206 * Allocate the initial block. Unlike other generation.c blocks, it
207 * starts with the context header and its block header follows that.
208 */
209 set = (GenerationContext *) malloc(allocSize);
210 if (set == NULL)
211 {
214 (errcode(ERRCODE_OUT_OF_MEMORY),
215 errmsg("out of memory"),
216 errdetail("Failed while creating memory context \"%s\".",
217 name)));
218 }
219
220 /*
221 * Avoid writing code that can fail between here and MemoryContextCreate;
222 * we'd leak the header if we ereport in this stretch.
223 */
224 dlist_init(&set->blocks);
225
226 /* Fill in the initial block's block header */
227 block = KeeperBlock(set);
228 /* determine the block size and initialize it */
229 firstBlockSize = allocSize - MAXALIGN(sizeof(GenerationContext));
230 GenerationBlockInit(set, block, firstBlockSize);
231
232 /* add it to the doubly-linked list of blocks */
233 dlist_push_head(&set->blocks, &block->node);
234
235 /* use it as the current allocation block */
236 set->block = block;
237
238 /* No free block, yet */
239 set->freeblock = NULL;
240
241 /* Fill in GenerationContext-specific header fields */
242 set->initBlockSize = (uint32) initBlockSize;
243 set->maxBlockSize = (uint32) maxBlockSize;
244 set->nextBlockSize = (uint32) initBlockSize;
245
246 /*
247 * Compute the allocation chunk size limit for this context.
248 *
249 * Limit the maximum size a non-dedicated chunk can be so that we can fit
250 * at least Generation_CHUNK_FRACTION of chunks this big onto the maximum
251 * sized block. We must further limit this value so that it's no more
252 * than MEMORYCHUNK_MAX_VALUE. We're unable to have non-external chunks
253 * larger than that value as we store the chunk size in the MemoryChunk
254 * 'value' field in the call to MemoryChunkSetHdrMask().
255 */
256 set->allocChunkLimit = Min(maxBlockSize, MEMORYCHUNK_MAX_VALUE);
257 while ((Size) (set->allocChunkLimit + Generation_CHUNKHDRSZ) >
259 set->allocChunkLimit >>= 1;
260
261 /* Finally, do the type-independent part of context creation */
263 T_GenerationContext,
265 parent,
266 name);
267
268 ((MemoryContext) set)->mem_allocated = firstBlockSize;
269
270 return (MemoryContext) set;
271}
static void GenerationBlockInit(GenerationContext *context, GenerationBlock *block, Size blksize)
Definition: generation.c:609
#define Generation_CHUNK_FRACTION
Definition: generation.c:49
#define KeeperBlock(set)
Definition: generation.c:127
#define Generation_CHUNKHDRSZ
Definition: generation.c:47
#define Generation_BLOCKHDRSZ
Definition: generation.c:46
@ MCTX_GENERATION_ID
dlist_node node
Definition: generation.c:89
GenerationBlock * freeblock
Definition: generation.c:70
uint32 maxBlockSize
Definition: generation.c:65
uint32 nextBlockSize
Definition: generation.c:66
dlist_head blocks
Definition: generation.c:72
uint32 initBlockSize
Definition: generation.c:64
GenerationBlock * block
Definition: generation.c:69
uint32 allocChunkLimit
Definition: generation.c:67

References GenerationContext::allocChunkLimit, AllocHugeSizeIsValid, Assert, GenerationContext::block, GenerationContext::blocks, dlist_init(), dlist_push_head(), ereport, errcode(), errdetail(), errmsg(), ERROR, GenerationContext::freeblock, Generation_BLOCKHDRSZ, Generation_CHUNK_FRACTION, Generation_CHUNKHDRSZ, GenerationBlockInit(), GenerationContext::initBlockSize, KeeperBlock, malloc, Max, MAXALIGN, GenerationContext::maxBlockSize, MCTX_GENERATION_ID, MEMORYCHUNK_MAX_BLOCKOFFSET, MEMORYCHUNK_MAX_VALUE, MemoryContextCreate(), MemoryContextStats(), Min, name, GenerationContext::nextBlockSize, GenerationBlock::node, StaticAssertDecl, and TopMemoryContext.

Referenced by gistvacuumscan(), ReorderBufferAllocate(), and tuplestore_begin_common().

◆ GetMemoryChunkContext()

MemoryContext GetMemoryChunkContext ( void *  pointer)

◆ GetMemoryChunkSpace()

◆ HandleLogMemoryContextInterrupt()

void HandleLogMemoryContextInterrupt ( void  )

Definition at line 1272 of file mcxt.c.

1273{
1274 InterruptPending = true;
1276 /* latch will be set by procsignal_sigusr1_handler */
1277}
volatile sig_atomic_t LogMemoryContextPending
Definition: globals.c:40
volatile sig_atomic_t InterruptPending
Definition: globals.c:31

References InterruptPending, and LogMemoryContextPending.

Referenced by procsignal_sigusr1_handler().

◆ MemoryContextAllowInCriticalSection()

void MemoryContextAllowInCriticalSection ( MemoryContext  context,
bool  allow 
)

Definition at line 694 of file mcxt.c.

695{
697
698 context->allowInCritSection = allow;
699}
#define MemoryContextIsValid(context)
Definition: memnodes.h:145
bool allowInCritSection
Definition: memnodes.h:124

References MemoryContextData::allowInCritSection, Assert, and MemoryContextIsValid.

Referenced by InitSync(), MemoryContextInit(), and XLOGShmemInit().

◆ MemoryContextDelete()

void MemoryContextDelete ( MemoryContext  context)

Definition at line 454 of file mcxt.c.

455{
456 MemoryContext curr;
457
459
460 /*
461 * Delete subcontexts from the bottom up.
462 *
463 * Note: Do not use recursion here. A "stack depth limit exceeded" error
464 * would be unpleasant if we're already in the process of cleaning up from
465 * transaction abort. We also cannot use MemoryContextTraverseNext() here
466 * because we modify the tree as we go.
467 */
468 curr = context;
469 for (;;)
470 {
471 MemoryContext parent;
472
473 /* Descend down until we find a leaf context with no children */
474 while (curr->firstchild != NULL)
475 curr = curr->firstchild;
476
477 /*
478 * We're now at a leaf with no children. Free it and continue from the
479 * parent. Or if this was the original node, we're all done.
480 */
481 parent = curr->parent;
483
484 if (curr == context)
485 break;
486 curr = parent;
487 }
488}
static void MemoryContextDeleteOnly(MemoryContext context)
Definition: mcxt.c:496
MemoryContext firstchild
Definition: memnodes.h:128
MemoryContext parent
Definition: memnodes.h:127

References Assert, MemoryContextData::firstchild, MemoryContextDeleteOnly(), MemoryContextIsValid, and MemoryContextData::parent.

Referenced by _brin_parallel_merge(), AfterTriggerEndXact(), afterTriggerInvokeEvents(), ApplyLauncherMain(), AtEOSubXact_SPI(), AtEOXact_LargeObject(), AtSubCleanup_Memory(), AtSubCommit_Memory(), AttachPartitionEnsureIndexes(), autovacuum_do_vac_analyze(), AutoVacWorkerMain(), AuxiliaryProcessMainCommon(), BackgroundWorkerMain(), blbuild(), blinsert(), brin_free_desc(), brin_minmax_multi_union(), bringetbitmap(), brininsert(), bt_check_every_level(), btendscan(), btree_xlog_cleanup(), btvacuumscan(), BuildParamLogString(), BuildRelationExtStatistics(), CloneRowTriggersToPartition(), cluster(), compactify_ranges(), compile_plperl_function(), compile_pltcl_function(), compute_expr_stats(), compute_index_stats(), ComputeExtStatisticsRows(), createTrgmNFA(), CreateTriggerFiringOn(), daitch_mokotoff(), decr_dcc_refcount(), DeleteExpandedObject(), DiscreteKnapsack(), do_analyze_rel(), do_start_worker(), DoCopyTo(), DropCachedPlan(), each_worker(), each_worker_jsonb(), elements_worker(), elements_worker_jsonb(), end_heap_rewrite(), EndCopy(), EndCopyFrom(), ensure_free_space_in_buffer(), EventTriggerEndCompleteQuery(), EventTriggerInvoke(), exec_replication_command(), exec_simple_query(), ExecEndAgg(), ExecEndMemoize(), ExecEndRecursiveUnion(), ExecEndSetOp(), ExecEndWindowAgg(), ExecHashTableDestroy(), execute_sql_string(), ExecVacuum(), file_acquire_sample_rows(), fill_hba_view(), fill_ident_view(), fmgr_sql(), free_auth_file(), free_plperl_function(), FreeCachedExpression(), FreeDecodingContext(), FreeExecutorState(), FreeExprContext(), freeGISTstate(), FreeSnapshotBuilder(), geqo_eval(), get_actual_variable_range(), get_rel_sync_entry(), GetWALRecordsInfo(), GetXLogSummaryStats(), gin_xlog_cleanup(), ginbuild(), ginbulkdelete(), ginendscan(), gininsert(), ginInsertCleanup(), ginPlaceToPage(), gist_xlog_cleanup(), gistbuild(), gistvacuumscan(), hash_destroy(), inline_function(), inline_set_returning_function(), libpqrcv_processTuples(), load_hba(), load_ident(), load_tzoffsets(), makeArrayResultArr(), makeMdArrayResult(), MemoryContextDeleteChildren(), NIFinishBuild(), pg_backup_stop(), pg_decode_shutdown(), pg_get_wal_block_info(), pgstat_clear_backend_activity_snapshot(), pgstat_clear_snapshot(), plperl_spi_freeplan(), plperl_spi_prepare(), plpgsql_free_function_memory(), pltcl_handler(), pltcl_SPI_prepare(), PLy_cursor_dealloc(), PLy_cursor_plan(), PLy_plan_dealloc(), PLy_pop_execution_context(), PLy_procedure_delete(), PLy_spi_execute_fetch_result(), PLy_spi_execute_plan(), PortalDrop(), PostgresMain(), printtup_shutdown(), ProcessConfigFile(), publicationListToArray(), RE_compile_and_cache(), rebuild_database_list(), ReindexMultipleTables(), ReindexPartitions(), ReindexRelationConcurrently(), RelationBuildDesc(), RelationBuildRuleLock(), RelationDestroyRelation(), ReleaseCachedPlan(), ReorderBufferFree(), ResetUnloggedRelations(), RevalidateCachedQuery(), serializeAnalyzeShutdown(), shdepReassignOwned(), shutdown_MultiFuncCall(), spg_xlog_cleanup(), spgbuild(), spgendscan(), spginsert(), SPI_finish(), SPI_freeplan(), SPI_freetuptable(), statext_dependencies_build(), strlist_to_textarray(), SysLoggerMain(), test_pattern(), TidStoreDestroy(), tokenize_auth_file(), tuplesort_end(), tuplestore_end(), union_tuples(), UploadManifest(), and validateForeignKeyConstraint().

◆ MemoryContextDeleteChildren()

void MemoryContextDeleteChildren ( MemoryContext  context)

Definition at line 539 of file mcxt.c.

540{
542
543 /*
544 * MemoryContextDelete will delink the child from me, so just iterate as
545 * long as there is a child.
546 */
547 while (context->firstchild != NULL)
549}
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:454

References Assert, MemoryContextData::firstchild, MemoryContextDelete(), and MemoryContextIsValid.

Referenced by AtAbort_Portals(), AtSubAbort_Portals(), exec_stmt_block(), MemoryContextReset(), PersistHoldablePortal(), PortalRunMulti(), and RelationCloseCleanup().

◆ MemoryContextGetParent()

MemoryContext MemoryContextGetParent ( MemoryContext  context)

◆ MemoryContextInit()

void MemoryContextInit ( void  )

Definition at line 339 of file mcxt.c.

340{
341 Assert(TopMemoryContext == NULL);
342
343 /*
344 * First, initialize TopMemoryContext, which is the parent of all others.
345 */
347 "TopMemoryContext",
349
350 /*
351 * Not having any other place to point CurrentMemoryContext, make it point
352 * to TopMemoryContext. Caller should change this soon!
353 */
355
356 /*
357 * Initialize ErrorContext as an AllocSetContext with slow growth rate ---
358 * we don't really expect much to be allocated in it. More to the point,
359 * require it to contain at least 8K at all times. This is the only case
360 * where retained memory in a context is *essential* --- we want to be
361 * sure ErrorContext still has some memory even if we've run out
362 * elsewhere! Also, allow allocations in ErrorContext within a critical
363 * section. Otherwise a PANIC will cause an assertion failure in the error
364 * reporting code, before printing out the real cause of the failure.
365 *
366 * This should be the last step in this function, as elog.c assumes memory
367 * management works once ErrorContext is non-null.
368 */
370 "ErrorContext",
371 8 * 1024,
372 8 * 1024,
373 8 * 1024);
375}
MemoryContext CurrentMemoryContext
Definition: mcxt.c:143
MemoryContext ErrorContext
Definition: mcxt.c:150
void MemoryContextAllowInCriticalSection(MemoryContext context, bool allow)
Definition: mcxt.c:694
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:160

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, Assert, CurrentMemoryContext, ErrorContext, MemoryContextAllowInCriticalSection(), and TopMemoryContext.

Referenced by main().

◆ MemoryContextIsEmpty()

bool MemoryContextIsEmpty ( MemoryContext  context)

Definition at line 743 of file mcxt.c.

744{
746
747 /*
748 * For now, we consider a memory context nonempty if it has any children;
749 * perhaps this should be changed later.
750 */
751 if (context->firstchild != NULL)
752 return false;
753 /* Otherwise use the type-specific inquiry */
754 return context->methods->is_empty(context);
755}
const MemoryContextMethods * methods
Definition: memnodes.h:126
bool(* is_empty)(MemoryContext context)
Definition: memnodes.h:101

References Assert, MemoryContextData::firstchild, MemoryContextMethods::is_empty, MemoryContextIsValid, and MemoryContextData::methods.

Referenced by AtSubCommit_Memory().

◆ MemoryContextMemAllocated()

Size MemoryContextMemAllocated ( MemoryContext  context,
bool  recurse 
)

Definition at line 762 of file mcxt.c.

763{
764 Size total = context->mem_allocated;
765
767
768 if (recurse)
769 {
770 for (MemoryContext curr = context->firstchild;
771 curr != NULL;
772 curr = MemoryContextTraverseNext(curr, context))
773 {
774 total += curr->mem_allocated;
775 }
776 }
777
778 return total;
779}
static MemoryContext MemoryContextTraverseNext(MemoryContext curr, MemoryContext top)
Definition: mcxt.c:257

References Assert, MemoryContextData::firstchild, MemoryContextData::mem_allocated, MemoryContextIsValid, and MemoryContextTraverseNext().

Referenced by hash_agg_check_limits(), hash_agg_update_metrics(), and RT_MEMORY_USAGE().

◆ MemoryContextMemConsumed()

void MemoryContextMemConsumed ( MemoryContext  context,
MemoryContextCounters consumed 
)

Definition at line 786 of file mcxt.c.

788{
790
791 memset(consumed, 0, sizeof(*consumed));
792
793 /* Examine the context itself */
794 context->methods->stats(context, NULL, NULL, consumed, false);
795
796 /* Examine children, using iteration not recursion */
797 for (MemoryContext curr = context->firstchild;
798 curr != NULL;
799 curr = MemoryContextTraverseNext(curr, context))
800 {
801 curr->methods->stats(curr, NULL, NULL, consumed, false);
802 }
803}
void(* stats)(MemoryContext context, MemoryStatsPrintFunc printfunc, void *passthru, MemoryContextCounters *totals, bool print_to_stderr)
Definition: memnodes.h:102

References Assert, MemoryContextData::firstchild, MemoryContextIsValid, MemoryContextTraverseNext(), MemoryContextData::methods, and MemoryContextMethods::stats.

Referenced by ExplainExecuteQuery(), and standard_ExplainOneQuery().

◆ MemoryContextReset()

void MemoryContextReset ( MemoryContext  context)

Definition at line 383 of file mcxt.c.

384{
386
387 /* save a function call in common case where there are no children */
388 if (context->firstchild != NULL)
390
391 /* save a function call if no pallocs since startup or last reset */
392 if (!context->isReset)
393 MemoryContextResetOnly(context);
394}
void MemoryContextDeleteChildren(MemoryContext context)
Definition: mcxt.c:539
void MemoryContextResetOnly(MemoryContext context)
Definition: mcxt.c:402

References Assert, MemoryContextData::firstchild, MemoryContextData::isReset, MemoryContextDeleteChildren(), MemoryContextIsValid, and MemoryContextResetOnly().

Referenced by _brin_parallel_merge(), _bt_preprocess_array_keys(), _SPI_end_call(), AfterTriggerExecute(), apply_spooled_messages(), AtCleanup_Memory(), AtCommit_Memory(), AtEOSubXact_SPI(), AtSubCleanup_Memory(), BackgroundWriterMain(), bloomBuildCallback(), brin_memtuple_initialize(), bringetbitmap(), brininsert(), bt_check_level_from_leftmost(), btree_redo(), btvacuumpage(), BuildEventTriggerCache(), BuildRelationExtStatistics(), buildSubPlanHash(), cache_purge_all(), check_domain_for_new_field(), check_domain_for_new_tuple(), CheckpointerMain(), CloneRowTriggersToPartition(), compute_expr_stats(), compute_index_stats(), CopyOneRowTo(), CreateTriggerFiringOn(), do_analyze_rel(), do_autovacuum(), dumptuples(), each_object_field_end(), each_worker_jsonb(), elements_array_element_end(), elements_worker_jsonb(), errstart(), eval_windowaggregates(), EventTriggerInvoke(), exec_dynquery_with_params(), exec_stmt_block(), exec_stmt_dynexecute(), exec_stmt_forc(), exec_stmt_foreach_a(), exec_stmt_open(), exec_stmt_raise(), exec_stmt_return_query(), ExecFindMatchingSubPlans(), ExecHashTableReset(), ExecMakeTableFunctionResult(), ExecProjectSet(), ExecQualAndReset(), ExecRecursiveUnion(), ExecReScanRecursiveUnion(), ExecReScanSetOp(), execTuplesUnequal(), execute_foreign_modify(), expanded_record_set_field_internal(), expanded_record_set_tuple(), fetch_more_data(), file_acquire_sample_rows(), FlushErrorState(), get_rel_sync_entry(), get_short_term_cxt(), GetWALRecordsInfo(), GetXLogSummaryStats(), gin_redo(), ginBuildCallback(), ginFreeScanKeys(), ginHeapTupleBulkInsert(), ginInsertCleanup(), ginVacuumPostingTreeLeaves(), gist_indexsortbuild(), gist_redo(), gistBuildCallback(), gistgetbitmap(), gistgettuple(), gistinsert(), gistProcessEmptyingQueue(), gistrescan(), gistScanPage(), gistSortedBuildCallback(), HandleParallelApplyMessages(), HandleParallelMessages(), heapam_index_build_range_scan(), heapam_index_validate_scan(), IndexCheckExclusion(), initialize_windowaggregate(), InvalidateEventCacheCallback(), keyGetItem(), libpqrcv_processTuples(), LogicalParallelApplyLoop(), LogicalRepApplyLoop(), lookup_ts_dictionary_cache(), make_tuple_from_result_row(), perform_work_item(), pg_backup_start(), pg_decode_change(), pg_decode_truncate(), pg_get_wal_block_info(), pgarch_archiveXlog(), pgoutput_change(), pgoutput_truncate(), plperl_return_next_internal(), PLy_input_convert(), PLy_input_from_tuple(), PostgresMain(), printtup(), process_ordered_aggregate_single(), release_partition(), ReScanExprContext(), resetSpGistScanOpaque(), RT_FREE(), scanPendingInsert(), sepgsql_avc_reset(), serializeAnalyzeReceive(), spcache_init(), spg_redo(), spginsert(), spgistBuildCallback(), spgWalk(), startScanKey(), statext_dependencies_build(), storeRow(), stream_stop_internal(), tfuncFetchRows(), tfuncLoadRows(), tuplesort_free(), tuplestore_clear(), validateForeignKeyConstraint(), WalSummarizerMain(), and WalWriterMain().

◆ MemoryContextResetChildren()

void MemoryContextResetChildren ( MemoryContext  context)

Definition at line 433 of file mcxt.c.

434{
436
437 for (MemoryContext curr = context->firstchild;
438 curr != NULL;
439 curr = MemoryContextTraverseNext(curr, context))
440 {
442 }
443}

References Assert, MemoryContextData::firstchild, MemoryContextIsValid, MemoryContextResetOnly(), and MemoryContextTraverseNext().

◆ MemoryContextResetOnly()

void MemoryContextResetOnly ( MemoryContext  context)

Definition at line 402 of file mcxt.c.

403{
405
406 /* Nothing to do if no pallocs since startup or last reset */
407 if (!context->isReset)
408 {
410
411 /*
412 * If context->ident points into the context's memory, it will become
413 * a dangling pointer. We could prevent that by setting it to NULL
414 * here, but that would break valid coding patterns that keep the
415 * ident elsewhere, e.g. in a parent context. So for now we assume
416 * the programmer got it right.
417 */
418
419 context->methods->reset(context);
420 context->isReset = true;
422 VALGRIND_CREATE_MEMPOOL(context, 0, false);
423 }
424}
static void MemoryContextCallResetCallbacks(MemoryContext context)
Definition: mcxt.c:585
#define VALGRIND_DESTROY_MEMPOOL(context)
Definition: memdebug.h:25
#define VALGRIND_CREATE_MEMPOOL(context, redzones, zeroed)
Definition: memdebug.h:24
void(* reset)(MemoryContext context)
Definition: memnodes.h:83

References Assert, MemoryContextData::isReset, MemoryContextCallResetCallbacks(), MemoryContextIsValid, MemoryContextData::methods, MemoryContextMethods::reset, VALGRIND_CREATE_MEMPOOL, and VALGRIND_DESTROY_MEMPOOL.

Referenced by AllocSetDelete(), JsonTableResetRowPattern(), MemoryContextReset(), MemoryContextResetChildren(), and mergeruns().

◆ MemoryContextSetIdentifier()

◆ MemoryContextSetParent()

void MemoryContextSetParent ( MemoryContext  context,
MemoryContext  new_parent 
)

Definition at line 637 of file mcxt.c.

638{
640 Assert(context != new_parent);
641
642 /* Fast path if it's got correct parent already */
643 if (new_parent == context->parent)
644 return;
645
646 /* Delink from existing parent, if any */
647 if (context->parent)
648 {
649 MemoryContext parent = context->parent;
650
651 if (context->prevchild != NULL)
652 context->prevchild->nextchild = context->nextchild;
653 else
654 {
655 Assert(parent->firstchild == context);
656 parent->firstchild = context->nextchild;
657 }
658
659 if (context->nextchild != NULL)
660 context->nextchild->prevchild = context->prevchild;
661 }
662
663 /* And relink */
664 if (new_parent)
665 {
666 Assert(MemoryContextIsValid(new_parent));
667 context->parent = new_parent;
668 context->prevchild = NULL;
669 context->nextchild = new_parent->firstchild;
670 if (new_parent->firstchild != NULL)
671 new_parent->firstchild->prevchild = context;
672 new_parent->firstchild = context;
673 }
674 else
675 {
676 context->parent = NULL;
677 context->prevchild = NULL;
678 context->nextchild = NULL;
679 }
680}
MemoryContext prevchild
Definition: memnodes.h:129

References Assert, MemoryContextData::firstchild, MemoryContextIsValid, MemoryContextData::nextchild, MemoryContextData::parent, and MemoryContextData::prevchild.

Referenced by _SPI_save_plan(), CachedPlanSetParentContext(), CompleteCachedPlan(), exec_parse_message(), GetCachedExpression(), GetCachedPlan(), load_domaintype_info(), MemoryContextDeleteOnly(), RE_compile_and_cache(), RelationBuildPartitionDesc(), RelationBuildPartitionKey(), RelationBuildRowSecurity(), RelationRebuildRelation(), RevalidateCachedQuery(), SaveCachedPlan(), SPI_keepplan(), TransferExpandedObject(), and UploadManifest().

◆ MemoryContextStats()

void MemoryContextStats ( MemoryContext  context)

Definition at line 814 of file mcxt.c.

815{
816 /* Hard-wired limits are usually good enough */
817 MemoryContextStatsDetail(context, 100, 100, true);
818}
void MemoryContextStatsDetail(MemoryContext context, int max_level, int max_children, bool print_to_stderr)
Definition: mcxt.c:829

References MemoryContextStatsDetail().

Referenced by AllocSetContextCreateInternal(), BumpContextCreate(), finish_xact_command(), GenerationContextCreate(), MemoryContextAllocationFailure(), SlabContextCreate(), and test_pattern().

◆ MemoryContextStatsDetail()

void MemoryContextStatsDetail ( MemoryContext  context,
int  max_level,
int  max_children,
bool  print_to_stderr 
)

Definition at line 829 of file mcxt.c.

832{
833 MemoryContextCounters grand_totals;
834
835 memset(&grand_totals, 0, sizeof(grand_totals));
836
837 MemoryContextStatsInternal(context, 0, max_level, max_children,
838 &grand_totals, print_to_stderr);
839
840 if (print_to_stderr)
841 fprintf(stderr,
842 "Grand total: %zu bytes in %zu blocks; %zu free (%zu chunks); %zu used\n",
843 grand_totals.totalspace, grand_totals.nblocks,
844 grand_totals.freespace, grand_totals.freechunks,
845 grand_totals.totalspace - grand_totals.freespace);
846 else
847 {
848 /*
849 * Use LOG_SERVER_ONLY to prevent the memory contexts from being sent
850 * to the connected client.
851 *
852 * We don't buffer the information about all memory contexts in a
853 * backend into StringInfo and log it as one message. That would
854 * require the buffer to be enlarged, risking an OOM as there could be
855 * a large number of memory contexts in a backend. Instead, we log
856 * one message per memory context.
857 */
859 (errhidestmt(true),
860 errhidecontext(true),
861 errmsg_internal("Grand total: %zu bytes in %zu blocks; %zu free (%zu chunks); %zu used",
862 grand_totals.totalspace, grand_totals.nblocks,
863 grand_totals.freespace, grand_totals.freechunks,
864 grand_totals.totalspace - grand_totals.freespace)));
865 }
866}
#define fprintf(file, fmt, msg)
Definition: cubescan.l:21
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1157
int errhidestmt(bool hide_stmt)
Definition: elog.c:1411
int errhidecontext(bool hide_ctx)
Definition: elog.c:1430
#define LOG_SERVER_ONLY
Definition: elog.h:32
static void MemoryContextStatsInternal(MemoryContext context, int level, int max_level, int max_children, MemoryContextCounters *totals, bool print_to_stderr)
Definition: mcxt.c:876

References ereport, errhidecontext(), errhidestmt(), errmsg_internal(), fprintf, MemoryContextCounters::freechunks, MemoryContextCounters::freespace, LOG_SERVER_ONLY, MemoryContextStatsInternal(), MemoryContextCounters::nblocks, and MemoryContextCounters::totalspace.

Referenced by MemoryContextStats(), and ProcessLogMemoryContextInterrupt().

◆ pg_memory_is_all_zeros()

static bool pg_memory_is_all_zeros ( const void *  ptr,
size_t  len 
)
inlinestatic

Definition at line 219 of file memutils.h.

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}
const void size_t len

References len.

Referenced by PageIsVerifiedExtended(), pg_stat_get_activity(), pg_stat_get_backend_client_addr(), pg_stat_get_backend_client_port(), pgstat_relation_flush_cb(), pgstat_report_bgwriter(), and pgstat_report_checkpointer().

◆ ProcessLogMemoryContextInterrupt()

void ProcessLogMemoryContextInterrupt ( void  )

Definition at line 1289 of file mcxt.c.

1290{
1292
1293 /*
1294 * Use LOG_SERVER_ONLY to prevent this message from being sent to the
1295 * connected client.
1296 */
1298 (errhidestmt(true),
1299 errhidecontext(true),
1300 errmsg("logging memory contexts of PID %d", MyProcPid)));
1301
1302 /*
1303 * When a backend process is consuming huge memory, logging all its memory
1304 * contexts might overrun available disk space. To prevent this, we limit
1305 * the depth of the hierarchy, as well as the number of child contexts to
1306 * log per parent to 100.
1307 *
1308 * As with MemoryContextStats(), we suppose that practical cases where the
1309 * dump gets long will typically be huge numbers of siblings under the
1310 * same parent context; while the additional debugging value from seeing
1311 * details about individual siblings beyond 100 will not be large.
1312 */
1314}
int MyProcPid
Definition: globals.c:46

References ereport, errhidecontext(), errhidestmt(), errmsg(), LOG_SERVER_ONLY, LogMemoryContextPending, MemoryContextStatsDetail(), MyProcPid, and TopMemoryContext.

Referenced by HandleAutoVacLauncherInterrupts(), HandleCheckpointerInterrupts(), HandleMainLoopInterrupts(), HandlePgArchInterrupts(), HandleStartupProcInterrupts(), HandleWalSummarizerInterrupts(), and ProcessInterrupts().

◆ SlabContextCreate()

MemoryContext SlabContextCreate ( MemoryContext  parent,
const char *  name,
Size  blockSize,
Size  chunkSize 
)

Definition at line 322 of file slab.c.

326{
327 int chunksPerBlock;
328 Size fullChunkSize;
329 SlabContext *slab;
330 int i;
331
332 /* ensure MemoryChunk's size is properly maxaligned */
334 "sizeof(MemoryChunk) is not maxaligned");
336
337 /*
338 * Ensure there's enough space to store the pointer to the next free chunk
339 * in the memory of the (otherwise) unused allocation.
340 */
341 if (chunkSize < sizeof(MemoryChunk *))
342 chunkSize = sizeof(MemoryChunk *);
343
344 /* length of the maxaligned chunk including the chunk header */
345#ifdef MEMORY_CONTEXT_CHECKING
346 /* ensure there's always space for the sentinel byte */
347 fullChunkSize = Slab_CHUNKHDRSZ + MAXALIGN(chunkSize + 1);
348#else
349 fullChunkSize = Slab_CHUNKHDRSZ + MAXALIGN(chunkSize);
350#endif
351
352 Assert(fullChunkSize <= MEMORYCHUNK_MAX_VALUE);
353
354 /* compute the number of chunks that will fit on each block */
355 chunksPerBlock = (blockSize - Slab_BLOCKHDRSZ) / fullChunkSize;
356
357 /* Make sure the block can store at least one chunk. */
358 if (chunksPerBlock == 0)
359 elog(ERROR, "block size %zu for slab is too small for %zu-byte chunks",
360 blockSize, chunkSize);
361
362
363
364 slab = (SlabContext *) malloc(Slab_CONTEXT_HDRSZ(chunksPerBlock));
365 if (slab == NULL)
366 {
369 (errcode(ERRCODE_OUT_OF_MEMORY),
370 errmsg("out of memory"),
371 errdetail("Failed while creating memory context \"%s\".",
372 name)));
373 }
374
375 /*
376 * Avoid writing code that can fail between here and MemoryContextCreate;
377 * we'd leak the header if we ereport in this stretch.
378 */
379
380 /* Fill in SlabContext-specific header fields */
381 slab->chunkSize = (uint32) chunkSize;
382 slab->fullChunkSize = (uint32) fullChunkSize;
383 slab->blockSize = (uint32) blockSize;
384 slab->chunksPerBlock = chunksPerBlock;
385 slab->curBlocklistIndex = 0;
386
387 /*
388 * Compute a shift that guarantees that shifting chunksPerBlock with it is
389 * < SLAB_BLOCKLIST_COUNT - 1. The reason that we subtract 1 from
390 * SLAB_BLOCKLIST_COUNT in this calculation is that we reserve the 0th
391 * blocklist element for blocks which have no free chunks.
392 *
393 * We calculate the number of bits to shift by rather than a divisor to
394 * divide by as performing division each time we need to find the
395 * blocklist index would be much slower.
396 */
397 slab->blocklist_shift = 0;
398 while ((slab->chunksPerBlock >> slab->blocklist_shift) >= (SLAB_BLOCKLIST_COUNT - 1))
399 slab->blocklist_shift++;
400
401 /* initialize the list to store empty blocks to be reused */
402 dclist_init(&slab->emptyblocks);
403
404 /* initialize each blocklist slot */
405 for (i = 0; i < SLAB_BLOCKLIST_COUNT; i++)
406 dlist_init(&slab->blocklist[i]);
407
408#ifdef MEMORY_CONTEXT_CHECKING
409 /* set the isChunkFree pointer right after the end of the context */
410 slab->isChunkFree = (bool *) ((char *) slab + sizeof(SlabContext));
411#endif
412
413 /* Finally, do the type-independent part of context creation */
415 T_SlabContext,
417 parent,
418 name);
419
420 return (MemoryContext) slab;
421}
static void dclist_init(dclist_head *head)
Definition: ilist.h:671
int i
Definition: isn.c:72
@ MCTX_SLAB_ID
elog(ERROR, "unexpected alloc chunk size %zu (expected %u)", size, slab->chunkSize)
#define Slab_BLOCKHDRSZ
Definition: slab.c:77
#define Slab_CHUNKHDRSZ
Definition: slab.c:157
struct SlabContext SlabContext
#define Slab_CONTEXT_HDRSZ(chunksPerBlock)
Definition: slab.c:88
#define SLAB_BLOCKLIST_COUNT
Definition: slab.c:95
dlist_head blocklist[SLAB_BLOCKLIST_COUNT]
Definition: slab.c:129
int32 chunksPerBlock
Definition: slab.c:110
uint32 fullChunkSize
Definition: slab.c:108
uint32 blockSize
Definition: slab.c:109
int32 curBlocklistIndex
Definition: slab.c:111
int32 blocklist_shift
Definition: slab.c:118
uint32 chunkSize
Definition: slab.c:107
dclist_head emptyblocks
Definition: slab.c:120

References Assert, SlabContext::blocklist, SlabContext::blocklist_shift, SlabContext::blockSize, SlabContext::chunkSize, SlabContext::chunksPerBlock, SlabContext::curBlocklistIndex, dclist_init(), dlist_init(), elog(), SlabContext::emptyblocks, ereport, errcode(), errdetail(), errmsg(), ERROR, SlabContext::fullChunkSize, i, malloc, MAXALIGN, MCTX_SLAB_ID, MEMORYCHUNK_MAX_BLOCKOFFSET, MEMORYCHUNK_MAX_VALUE, MemoryContextCreate(), MemoryContextStats(), name, Slab_BLOCKHDRSZ, SLAB_BLOCKLIST_COUNT, Slab_CHUNKHDRSZ, Slab_CONTEXT_HDRSZ, StaticAssertDecl, and TopMemoryContext.

Referenced by for(), ReorderBufferAllocate(), and test_random().

Variable Documentation

◆ CacheMemoryContext

PGDLLIMPORT MemoryContext CacheMemoryContext
extern

Definition at line 152 of file mcxt.c.

Referenced by _SPI_save_plan(), AllocateRelationDesc(), assign_record_type_typmod(), AttrDefaultFetch(), BuildEventTriggerCache(), BuildHardcodedDescriptor(), CatalogCacheCreateEntry(), CatalogCacheInitializeCache(), CheckConstraintFetch(), CreateCacheMemoryContext(), ensure_record_cache_typmod_slot_exists(), FetchTableStates(), generate_partition_qual(), get_attribute_options(), get_tablespace(), GetCachedExpression(), GetCachedPlan(), GetFdwRoutineForRelation(), init_ts_config_cache(), InitCatCache(), InitializeAttoptCache(), InitializeRelfilenumberMap(), InitializeTableSpaceCache(), load_domaintype_info(), load_enum_cache_data(), load_rangetype_info(), load_relcache_init_file(), logicalrep_partmap_init(), logicalrep_relmap_init(), lookup_ts_config_cache(), lookup_ts_dictionary_cache(), lookup_ts_parser_cache(), lookup_type_cache(), LookupOpclassInfo(), pgoutput_startup(), register_on_commit_action(), RehashCatCache(), RehashCatCacheLists(), RelationBuildLocalRelation(), RelationBuildPartitionDesc(), RelationBuildPartitionKey(), RelationBuildPublicationDesc(), RelationBuildRowSecurity(), RelationBuildRuleLock(), RelationBuildTriggers(), RelationBuildTupleDesc(), RelationCacheInitialize(), RelationCacheInitializePhase2(), RelationCacheInitializePhase3(), RelationGetFKeyList(), RelationGetIdentityKeyBitmap(), RelationGetIndexAttrBitmap(), RelationGetIndexList(), RelationGetStatExtList(), RelationInitIndexAccessInfo(), RelationParseRelOptions(), RememberToFreeTupleDescAtEOX(), SaveCachedPlan(), SearchCatCacheList(), set_schema_sent_in_streamed_txn(), SPI_keepplan(), and UploadManifest().

◆ CurTransactionContext

◆ ErrorContext

◆ MessageContext

◆ PortalContext

◆ PostmasterContext

◆ TopMemoryContext

PGDLLIMPORT MemoryContext TopMemoryContext
extern

Definition at line 149 of file mcxt.c.

Referenced by _PG_init(), AbortOutOfAnyTransaction(), add_reloption(), allocate_reloption(), AllocateAttribute(), AllocSetContextCreateInternal(), ApplyLauncherMain(), AtAbort_Memory(), AtStart_Memory(), AttachSession(), BackendInitialize(), BackendMain(), BackgroundWorkerMain(), BackgroundWriterMain(), BaseBackupAddTarget(), be_tls_open_server(), build_guc_variables(), BumpContextCreate(), cache_single_string(), check_foreign_key(), check_primary_key(), CheckpointerMain(), ClientAuthentication(), compile_plperl_function(), compile_pltcl_function(), CreateCacheMemoryContext(), CreateWaitEventSet(), dblink_connect(), dblink_init(), DCH_cache_getnew(), do_autovacuum(), do_compile(), dsm_create_descriptor(), dsm_impl_sysv(), EnablePortalManager(), EventTriggerBeginCompleteQuery(), Exec_ListenCommit(), executeDateTimeMethod(), find_plan(), finish_xact_command(), GenerationContextCreate(), GetLocalBufferStorage(), GetLockConflicts(), getmissingattr(), GetNamedDSMSegment(), GetSessionDsmHandle(), HandleParallelApplyMessages(), HandleParallelMessages(), hash_create(), init_database_collation(), init_missing_cache(), init_string_reloption(), InitDeadLockChecking(), initialize_reloptions(), initialize_target_list(), InitializeClientEncoding(), InitializeLogRepWorker(), InitializeParallelDSM(), InitializeSearchPath(), InitializeSession(), InitializeSystemUser(), InitSync(), InitXLogInsert(), injection_points_attach(), injection_points_detach(), llvm_compile_module(), llvm_create_context(), llvm_session_initialize(), LockAcquireExtended(), logicalrep_launcher_attach_dshmem(), LogicalRepApplyLoop(), LWLockRegisterTranche(), mdinit(), MemoryContextAllocationFailure(), MemoryContextDeleteOnly(), MemoryContextInit(), mxid_to_string(), newLOfd(), NUM_cache_getnew(), on_dsm_detach(), PageSetChecksumCopy(), ParallelWorkerMain(), PerformAuthentication(), pg_backup_start(), pg_get_backend_memory_contexts(), pg_newlocale_from_collation(), PgArchiverMain(), pgstat_attach_shmem(), pgstat_init_snapshot_fixed(), pgstat_prep_pending_entry(), pgstat_prep_snapshot(), pgstat_register_kind(), pgstat_setup_backend_status_context(), pgstat_setup_memcxt(), plperl_spi_prepare(), plpython3_inline_handler(), plsample_func_handler(), pltcl_SPI_prepare(), PLy_cursor_plan(), PLy_cursor_query(), PLy_procedure_create(), PLy_spi_execute_fetch_result(), PLy_spi_prepare(), populate_typ_list(), PostgresMain(), postmaster_child_launch(), PostmasterMain(), pq_init(), PrepareClientEncoding(), ProcessLogMemoryContextInterrupt(), ProcessStartupPacket(), px_find_cipher(), px_find_digest(), RE_compile_and_cache(), recomputeNamespacePath(), register_label_provider(), RegisterResourceReleaseCallback(), RegisterSubXactCallback(), RegisterXactCallback(), RelationCreateStorage(), RelationDropStorage(), RequestNamedLWLockTranche(), ResourceOwnerCreate(), ResourceOwnerEnlarge(), RestoreClientConnectionInfo(), RestoreReindexState(), ri_HashCompareOp(), roles_is_member_of(), secure_open_gssapi(), sepgsql_avc_init(), sepgsql_xact_callback(), set_authn_id(), SetDatabasePath(), SharedRecordTypmodRegistryAttach(), SharedRecordTypmodRegistryInit(), SlabContextCreate(), spcache_init(), SPI_connect_ext(), test_create(), WalSummarizerMain(), WalWriterMain(), and XLOGShmemInit().

◆ TopTransactionContext