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 MemoryContextResetAndDeleteChildren(ctx)   MemoryContextReset(ctx)
 
#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 MemoryContextStats (MemoryContext context)
 
void MemoryContextStatsDetail (MemoryContext context, 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)
 

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 151 of file memutils.h.

◆ ALLOCSET_DEFAULT_MAXSIZE

#define ALLOCSET_DEFAULT_MAXSIZE   (8 * 1024 * 1024)

Definition at line 152 of file memutils.h.

◆ ALLOCSET_DEFAULT_MINSIZE

#define ALLOCSET_DEFAULT_MINSIZE   0

Definition at line 150 of file memutils.h.

◆ ALLOCSET_DEFAULT_SIZES

Definition at line 153 of file memutils.h.

◆ ALLOCSET_SEPARATE_THRESHOLD

#define ALLOCSET_SEPARATE_THRESHOLD   8192

Definition at line 180 of file memutils.h.

◆ ALLOCSET_SMALL_INITSIZE

#define ALLOCSET_SMALL_INITSIZE   (1 * 1024)

Definition at line 161 of file memutils.h.

◆ ALLOCSET_SMALL_MAXSIZE

#define ALLOCSET_SMALL_MAXSIZE   (8 * 1024)

Definition at line 162 of file memutils.h.

◆ ALLOCSET_SMALL_MINSIZE

#define ALLOCSET_SMALL_MINSIZE   0

Definition at line 160 of file memutils.h.

◆ ALLOCSET_SMALL_SIZES

Definition at line 163 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 170 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.

◆ MemoryContextResetAndDeleteChildren

#define MemoryContextResetAndDeleteChildren (   ctx)    MemoryContextReset(ctx)

Definition at line 70 of file memutils.h.

◆ SLAB_DEFAULT_BLOCK_SIZE

#define SLAB_DEFAULT_BLOCK_SIZE   (8 * 1024)

Definition at line 182 of file memutils.h.

◆ SLAB_LARGE_BLOCK_SIZE

#define SLAB_LARGE_BLOCK_SIZE   (8 * 1024 * 1024)

Definition at line 183 of file memutils.h.

Function Documentation

◆ AllocSetContextCreateInternal()

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

Definition at line 349 of file aset.c.

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

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, AllocSetContext::keeper, 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, StaticAssertStmt, TopMemoryContext, and VALGRIND_MAKE_MEM_NOACCESS.

◆ GenerationContextCreate()

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

Definition at line 158 of file generation.c.

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

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, GenerationContext::keeper, malloc, Max, MAXALIGN, GenerationContext::maxBlockSize, MCTX_GENERATION_ID, MEMORYCHUNK_MAX_BLOCKOFFSET, MEMORYCHUNK_MAX_VALUE, MemoryContextCreate(), MemoryContextStats(), Min, name, GenerationContext::nextBlockSize, GenerationBlock::node, StaticAssertStmt, and TopMemoryContext.

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

◆ GetMemoryChunkContext()

MemoryContext GetMemoryChunkContext ( void *  pointer)

Definition at line 589 of file mcxt.c.

590 {
591  return MCXT_METHOD(pointer, get_chunk_context) (pointer);
592 }
#define MCXT_METHOD(pointer, method)
Definition: mcxt.c:162

References MCXT_METHOD.

Referenced by create_unique_path(), enlarge_list(), guc_free(), guc_realloc(), list_delete_first_n(), list_delete_nth_cell(), mark_dummy_rel(), pfree(), repalloc(), repalloc_extended(), and reparameterize_path_by_child().

◆ GetMemoryChunkSpace()

◆ HandleLogMemoryContextInterrupt()

void HandleLogMemoryContextInterrupt ( void  )

Definition at line 1155 of file mcxt.c.

1156 {
1157  InterruptPending = true;
1158  LogMemoryContextPending = true;
1159  /* latch will be set by procsignal_sigusr1_handler */
1160 }
volatile sig_atomic_t LogMemoryContextPending
Definition: globals.c:38
volatile sig_atomic_t InterruptPending
Definition: globals.c:30

References InterruptPending, and LogMemoryContextPending.

Referenced by procsignal_sigusr1_handler().

◆ MemoryContextAllowInCriticalSection()

void MemoryContextAllowInCriticalSection ( MemoryContext  context,
bool  allow 
)

Definition at line 576 of file mcxt.c.

577 {
578  Assert(MemoryContextIsValid(context));
579 
580  context->allowInCritSection = allow;
581 }
#define MemoryContextIsValid(context)
Definition: memnodes.h:107
bool allowInCritSection
Definition: memnodes.h:86

References MemoryContextData::allowInCritSection, Assert(), and MemoryContextIsValid.

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

◆ MemoryContextDelete()

void MemoryContextDelete ( MemoryContext  context)

Definition at line 376 of file mcxt.c.

377 {
378  Assert(MemoryContextIsValid(context));
379  /* We had better not be deleting TopMemoryContext ... */
380  Assert(context != TopMemoryContext);
381  /* And not CurrentMemoryContext, either */
382  Assert(context != CurrentMemoryContext);
383 
384  /* save a function call in common case where there are no children */
385  if (context->firstchild != NULL)
387 
388  /*
389  * It's not entirely clear whether 'tis better to do this before or after
390  * delinking the context; but an error in a callback will likely result in
391  * leaking the whole context (if it's not a root context) if we do it
392  * after, so let's do it before.
393  */
395 
396  /*
397  * We delink the context from its parent before deleting it, so that if
398  * there's an error we won't have deleted/busted contexts still attached
399  * to the context tree. Better a leak than a crash.
400  */
401  MemoryContextSetParent(context, NULL);
402 
403  /*
404  * Also reset the context's ident pointer, in case it points into the
405  * context. This would only matter if someone tries to get stats on the
406  * (already unlinked) context, which is unlikely, but let's be safe.
407  */
408  context->ident = NULL;
409 
410  context->methods->delete_context(context);
411 
412  VALGRIND_DESTROY_MEMPOOL(context);
413 }
static void MemoryContextCallResetCallbacks(MemoryContext context)
Definition: mcxt.c:467
void MemoryContextSetParent(MemoryContext context, MemoryContext new_parent)
Definition: mcxt.c:519
void MemoryContextDeleteChildren(MemoryContext context)
Definition: mcxt.c:421
MemoryContext CurrentMemoryContext
Definition: mcxt.c:124
#define VALGRIND_DESTROY_MEMPOOL(context)
Definition: memdebug.h:25
MemoryContext firstchild
Definition: memnodes.h:90
const char * ident
Definition: memnodes.h:94
const MemoryContextMethods * methods
Definition: memnodes.h:88
void(* delete_context)(MemoryContext context)
Definition: memnodes.h:65

References Assert(), CurrentMemoryContext, MemoryContextMethods::delete_context, MemoryContextData::firstchild, MemoryContextData::ident, MemoryContextCallResetCallbacks(), MemoryContextDeleteChildren(), MemoryContextIsValid, MemoryContextSetParent(), MemoryContextData::methods, TopMemoryContext, and VALGRIND_DESTROY_MEMPOOL.

Referenced by AfterTriggerEndXact(), afterTriggerInvokeEvents(), ApplyLauncherMain(), AtCleanup_Memory(), AtCommit_Memory(), AtEOSubXact_SPI(), AtEOXact_LargeObject(), AtSubCleanup_Memory(), AtSubCommit_Memory(), AttachPartitionEnsureIndexes(), 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(), decr_dcc_refcount(), DeleteExpandedObject(), DiscreteKnapsack(), do_analyze_rel(), do_start_bgworker(), 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(), 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(), 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(), 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_plan_dealloc(), PLy_pop_execution_context(), PLy_procedure_delete(), PLy_spi_execute_fetch_result(), PortalDrop(), PostgresMain(), printtup_shutdown(), publicationListToArray(), rebuild_database_list(), ReindexMultipleTables(), ReindexPartitions(), ReindexRelationConcurrently(), RelationBuildDesc(), RelationBuildRuleLock(), RelationDestroyRelation(), ReleaseCachedPlan(), ReorderBufferFree(), ResetUnloggedRelations(), RevalidateCachedQuery(), shdepReassignOwned(), shutdown_MultiFuncCall(), spg_xlog_cleanup(), spgbuild(), spgendscan(), spginsert(), SPI_finish(), SPI_freeplan(), SPI_freetuptable(), StartChildProcess(), statext_dependencies_build(), strlist_to_textarray(), test_pattern(), tokenize_auth_file(), tuplesort_end(), union_tuples(), vacuum(), and validateForeignKeyConstraint().

◆ MemoryContextDeleteChildren()

void MemoryContextDeleteChildren ( MemoryContext  context)

Definition at line 421 of file mcxt.c.

422 {
423  Assert(MemoryContextIsValid(context));
424 
425  /*
426  * MemoryContextDelete will delink the child from me, so just iterate as
427  * long as there is a child.
428  */
429  while (context->firstchild != NULL)
431 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:376

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

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

◆ MemoryContextGetParent()

MemoryContext MemoryContextGetParent ( MemoryContext  context)

Definition at line 613 of file mcxt.c.

614 {
615  Assert(MemoryContextIsValid(context));
616 
617  return context->parent;
618 }
MemoryContext parent
Definition: memnodes.h:89

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

Referenced by advance_windowaggregate(), advance_windowaggregate_base(), ExecAggTransReparent(), GetCachedPlan(), pop_stmt_mcontext(), and push_stmt_mcontext().

◆ MemoryContextInit()

void MemoryContextInit ( void  )

Definition at line 259 of file mcxt.c.

260 {
261  Assert(TopMemoryContext == NULL);
262 
263  /*
264  * First, initialize TopMemoryContext, which is the parent of all others.
265  */
267  "TopMemoryContext",
269 
270  /*
271  * Not having any other place to point CurrentMemoryContext, make it point
272  * to TopMemoryContext. Caller should change this soon!
273  */
275 
276  /*
277  * Initialize ErrorContext as an AllocSetContext with slow growth rate ---
278  * we don't really expect much to be allocated in it. More to the point,
279  * require it to contain at least 8K at all times. This is the only case
280  * where retained memory in a context is *essential* --- we want to be
281  * sure ErrorContext still has some memory even if we've run out
282  * elsewhere! Also, allow allocations in ErrorContext within a critical
283  * section. Otherwise a PANIC will cause an assertion failure in the error
284  * reporting code, before printing out the real cause of the failure.
285  *
286  * This should be the last step in this function, as elog.c assumes memory
287  * management works once ErrorContext is non-null.
288  */
290  "ErrorContext",
291  8 * 1024,
292  8 * 1024,
293  8 * 1024);
295 }
MemoryContext ErrorContext
Definition: mcxt.c:131
void MemoryContextAllowInCriticalSection(MemoryContext context, bool allow)
Definition: mcxt.c:576
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:153

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

Referenced by main().

◆ MemoryContextIsEmpty()

bool MemoryContextIsEmpty ( MemoryContext  context)

Definition at line 625 of file mcxt.c.

626 {
627  Assert(MemoryContextIsValid(context));
628 
629  /*
630  * For now, we consider a memory context nonempty if it has any children;
631  * perhaps this should be changed later.
632  */
633  if (context->firstchild != NULL)
634  return false;
635  /* Otherwise use the type-specific inquiry */
636  return context->methods->is_empty(context);
637 }
bool(* is_empty)(MemoryContext context)
Definition: memnodes.h:68

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 644 of file mcxt.c.

645 {
646  Size total = context->mem_allocated;
647 
648  Assert(MemoryContextIsValid(context));
649 
650  if (recurse)
651  {
652  MemoryContext child;
653 
654  for (child = context->firstchild;
655  child != NULL;
656  child = child->nextchild)
657  total += MemoryContextMemAllocated(child, true);
658  }
659 
660  return total;
661 }
Size MemoryContextMemAllocated(MemoryContext context, bool recurse)
Definition: mcxt.c:644
Size mem_allocated
Definition: memnodes.h:87

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

Referenced by hash_agg_check_limits(), and hash_agg_update_metrics().

◆ MemoryContextReset()

void MemoryContextReset ( MemoryContext  context)

Definition at line 303 of file mcxt.c.

304 {
305  Assert(MemoryContextIsValid(context));
306 
307  /* save a function call in common case where there are no children */
308  if (context->firstchild != NULL)
310 
311  /* save a function call if no pallocs since startup or last reset */
312  if (!context->isReset)
313  MemoryContextResetOnly(context);
314 }
void MemoryContextResetOnly(MemoryContext context)
Definition: mcxt.c:322

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

Referenced by _bt_preprocess_array_keys(), AfterTriggerExecute(), apply_handle_stream_stop(), apply_spooled_messages(), basic_archive_file(), bloomBuildCallback(), brin_memtuple_initialize(), bt_check_level_from_leftmost(), btree_redo(), btvacuumpage(), BuildRelationExtStatistics(), buildSubPlanHash(), cache_purge_all(), check_domain_for_new_field(), check_domain_for_new_tuple(), CloneRowTriggersToPartition(), CopyOneRowTo(), CreateTriggerFiringOn(), dumptuples(), each_object_field_end(), each_worker_jsonb(), elements_array_element_end(), elements_worker_jsonb(), errstart(), 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(), execTuplesUnequal(), execute_foreign_modify(), expanded_record_set_field_internal(), expanded_record_set_tuple(), fetch_more_data(), file_acquire_sample_rows(), get_short_term_cxt(), gin_redo(), ginBuildCallback(), ginHeapTupleBulkInsert(), ginInsertCleanup(), ginVacuumPostingTreeLeaves(), gist_indexsortbuild(), gist_redo(), gistBuildCallback(), gistgetbitmap(), gistgettuple(), gistinsert(), gistProcessEmptyingQueue(), gistrescan(), gistScanPage(), gistSortedBuildCallback(), HandleParallelMessages(), heapam_index_build_range_scan(), heapam_index_validate_scan(), IndexCheckExclusion(), keyGetItem(), libpqrcv_processTuples(), LogicalRepApplyLoop(), lookup_ts_dictionary_cache(), make_tuple_from_result_row(), pg_backup_start(), pg_decode_change(), pg_decode_truncate(), pgoutput_change(), pgoutput_truncate(), plperl_return_next_internal(), PLy_input_convert(), PLy_input_from_tuple(), printtup(), process_ordered_aggregate_single(), ReScanExprContext(), resetSpGistScanOpaque(), scanPendingInsert(), sepgsql_avc_reset(), spg_redo(), spginsert(), spgistBuildCallback(), spgWalk(), startScanKey(), statext_dependencies_build(), storeRow(), tfuncFetchRows(), tfuncLoadRows(), tuplesort_free(), and validateForeignKeyConstraint().

◆ MemoryContextResetChildren()

void MemoryContextResetChildren ( MemoryContext  context)

Definition at line 353 of file mcxt.c.

354 {
355  MemoryContext child;
356 
357  Assert(MemoryContextIsValid(context));
358 
359  for (child = context->firstchild; child != NULL; child = child->nextchild)
360  {
362  MemoryContextResetOnly(child);
363  }
364 }
void MemoryContextResetChildren(MemoryContext context)
Definition: mcxt.c:353

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

◆ MemoryContextResetOnly()

void MemoryContextResetOnly ( MemoryContext  context)

Definition at line 322 of file mcxt.c.

323 {
324  Assert(MemoryContextIsValid(context));
325 
326  /* Nothing to do if no pallocs since startup or last reset */
327  if (!context->isReset)
328  {
330 
331  /*
332  * If context->ident points into the context's memory, it will become
333  * a dangling pointer. We could prevent that by setting it to NULL
334  * here, but that would break valid coding patterns that keep the
335  * ident elsewhere, e.g. in a parent context. So for now we assume
336  * the programmer got it right.
337  */
338 
339  context->methods->reset(context);
340  context->isReset = true;
341  VALGRIND_DESTROY_MEMPOOL(context);
342  VALGRIND_CREATE_MEMPOOL(context, 0, false);
343  }
344 }
#define VALGRIND_CREATE_MEMPOOL(context, redzones, zeroed)
Definition: memdebug.h:24
void(* reset)(MemoryContext context)
Definition: memnodes.h:64

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

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

◆ MemoryContextSetIdentifier()

void MemoryContextSetIdentifier ( MemoryContext  context,
const char *  id 
)

◆ MemoryContextSetParent()

void MemoryContextSetParent ( MemoryContext  context,
MemoryContext  new_parent 
)

Definition at line 519 of file mcxt.c.

520 {
521  Assert(MemoryContextIsValid(context));
522  Assert(context != new_parent);
523 
524  /* Fast path if it's got correct parent already */
525  if (new_parent == context->parent)
526  return;
527 
528  /* Delink from existing parent, if any */
529  if (context->parent)
530  {
531  MemoryContext parent = context->parent;
532 
533  if (context->prevchild != NULL)
534  context->prevchild->nextchild = context->nextchild;
535  else
536  {
537  Assert(parent->firstchild == context);
538  parent->firstchild = context->nextchild;
539  }
540 
541  if (context->nextchild != NULL)
542  context->nextchild->prevchild = context->prevchild;
543  }
544 
545  /* And relink */
546  if (new_parent)
547  {
548  Assert(MemoryContextIsValid(new_parent));
549  context->parent = new_parent;
550  context->prevchild = NULL;
551  context->nextchild = new_parent->firstchild;
552  if (new_parent->firstchild != NULL)
553  new_parent->firstchild->prevchild = context;
554  new_parent->firstchild = context;
555  }
556  else
557  {
558  context->parent = NULL;
559  context->prevchild = NULL;
560  context->nextchild = NULL;
561  }
562 }
MemoryContext prevchild
Definition: memnodes.h:91

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(), MemoryContextDelete(), RelationBuildPartitionDesc(), RelationBuildPartitionKey(), RelationBuildRowSecurity(), RelationClearRelation(), RevalidateCachedQuery(), SaveCachedPlan(), SPI_keepplan(), and TransferExpandedObject().

◆ MemoryContextStats()

void MemoryContextStats ( MemoryContext  context)

Definition at line 672 of file mcxt.c.

673 {
674  /* A hard-wired limit on the number of children is usually good enough */
675  MemoryContextStatsDetail(context, 100, true);
676 }
void MemoryContextStatsDetail(MemoryContext context, int max_children, bool print_to_stderr)
Definition: mcxt.c:687

References MemoryContextStatsDetail().

Referenced by AllocSetContextCreateInternal(), finish_xact_command(), GenerationContextCreate(), MemoryContextAlloc(), MemoryContextAllocExtended(), MemoryContextAllocHuge(), MemoryContextAllocZero(), MemoryContextAllocZeroAligned(), palloc(), palloc0(), palloc_extended(), repalloc(), repalloc_extended(), SlabContextCreate(), and test_pattern().

◆ MemoryContextStatsDetail()

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

Definition at line 687 of file mcxt.c.

689 {
690  MemoryContextCounters grand_totals;
691 
692  memset(&grand_totals, 0, sizeof(grand_totals));
693 
694  MemoryContextStatsInternal(context, 0, true, max_children, &grand_totals, print_to_stderr);
695 
696  if (print_to_stderr)
697  fprintf(stderr,
698  "Grand total: %zu bytes in %zu blocks; %zu free (%zu chunks); %zu used\n",
699  grand_totals.totalspace, grand_totals.nblocks,
700  grand_totals.freespace, grand_totals.freechunks,
701  grand_totals.totalspace - grand_totals.freespace);
702  else
703 
704  /*
705  * Use LOG_SERVER_ONLY to prevent the memory contexts from being sent
706  * to the connected client.
707  *
708  * We don't buffer the information about all memory contexts in a
709  * backend into StringInfo and log it as one message. Otherwise which
710  * may require the buffer to be enlarged very much and lead to OOM
711  * error since there can be a large number of memory contexts in a
712  * backend. Instead, we log one message per memory context.
713  */
715  (errhidestmt(true),
716  errhidecontext(true),
717  errmsg_internal("Grand total: %zu bytes in %zu blocks; %zu free (%zu chunks); %zu used",
718  grand_totals.totalspace, grand_totals.nblocks,
719  grand_totals.freespace, grand_totals.freechunks,
720  grand_totals.totalspace - grand_totals.freespace)));
721 }
int errmsg_internal(const char *fmt,...)
Definition: elog.c:993
int errhidestmt(bool hide_stmt)
Definition: elog.c:1247
int errhidecontext(bool hide_ctx)
Definition: elog.c:1266
#define LOG_SERVER_ONLY
Definition: elog.h:28
static void MemoryContextStatsInternal(MemoryContext context, int level, bool print, int max_children, MemoryContextCounters *totals, bool print_to_stderr)
Definition: mcxt.c:731
#define fprintf
Definition: port.h:242

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().

◆ ProcessLogMemoryContextInterrupt()

void ProcessLogMemoryContextInterrupt ( void  )

Definition at line 1172 of file mcxt.c.

1173 {
1174  LogMemoryContextPending = false;
1175 
1176  /*
1177  * Use LOG_SERVER_ONLY to prevent this message from being sent to the
1178  * connected client.
1179  */
1181  (errhidestmt(true),
1182  errhidecontext(true),
1183  errmsg("logging memory contexts of PID %d", MyProcPid)));
1184 
1185  /*
1186  * When a backend process is consuming huge memory, logging all its memory
1187  * contexts might overrun available disk space. To prevent this, we limit
1188  * the number of child contexts to log per parent to 100.
1189  *
1190  * As with MemoryContextStats(), we suppose that practical cases where the
1191  * dump gets long will typically be huge numbers of siblings under the
1192  * same parent context; while the additional debugging value from seeing
1193  * details about individual siblings beyond 100 will not be large.
1194  */
1196 }
int MyProcPid
Definition: globals.c:44

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

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

◆ SlabContextCreate()

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

Definition at line 141 of file slab.c.

145 {
146  int chunksPerBlock;
147  Size fullChunkSize;
148  Size freelistSize;
149  Size headerSize;
150  SlabContext *slab;
151  int i;
152 
153  /* ensure MemoryChunk's size is properly maxaligned */
155  "sizeof(MemoryChunk) is not maxaligned");
156  Assert(MAXALIGN(chunkSize) <= MEMORYCHUNK_MAX_VALUE);
157 
158  /* Make sure the linked list node fits inside a freed chunk */
159  if (chunkSize < sizeof(int))
160  chunkSize = sizeof(int);
161 
162  /* chunk, including SLAB header (both addresses nicely aligned) */
163 #ifdef MEMORY_CONTEXT_CHECKING
164  /* ensure there's always space for the sentinel byte */
165  fullChunkSize = Slab_CHUNKHDRSZ + MAXALIGN(chunkSize + 1);
166 #else
167  fullChunkSize = Slab_CHUNKHDRSZ + MAXALIGN(chunkSize);
168 #endif
169 
170  /* Make sure the block can store at least one chunk. */
171  if (blockSize < fullChunkSize + Slab_BLOCKHDRSZ)
172  elog(ERROR, "block size %zu for slab is too small for %zu chunks",
173  blockSize, chunkSize);
174 
175  /* Compute maximum number of chunks per block */
176  chunksPerBlock = (blockSize - Slab_BLOCKHDRSZ) / fullChunkSize;
177 
178  /* The freelist starts with 0, ends with chunksPerBlock. */
179  freelistSize = sizeof(dlist_head) * (chunksPerBlock + 1);
180 
181  /*
182  * Allocate the context header. Unlike aset.c, we never try to combine
183  * this with the first regular block; not worth the extra complication.
184  */
185 
186  /* Size of the memory context header */
187  headerSize = offsetof(SlabContext, freelist) + freelistSize;
188 
189 #ifdef MEMORY_CONTEXT_CHECKING
190 
191  /*
192  * With memory checking, we need to allocate extra space for the bitmap of
193  * free chunks. The bitmap is an array of bools, so we don't need to worry
194  * about alignment.
195  */
196  headerSize += chunksPerBlock * sizeof(bool);
197 #endif
198 
199  slab = (SlabContext *) malloc(headerSize);
200  if (slab == NULL)
201  {
203  ereport(ERROR,
204  (errcode(ERRCODE_OUT_OF_MEMORY),
205  errmsg("out of memory"),
206  errdetail("Failed while creating memory context \"%s\".",
207  name)));
208  }
209 
210  /*
211  * Avoid writing code that can fail between here and MemoryContextCreate;
212  * we'd leak the header if we ereport in this stretch.
213  */
214 
215  /* Fill in SlabContext-specific header fields */
216  slab->chunkSize = chunkSize;
217  slab->fullChunkSize = fullChunkSize;
218  slab->blockSize = blockSize;
219  slab->headerSize = headerSize;
220  slab->chunksPerBlock = chunksPerBlock;
221  slab->minFreeChunks = 0;
222  slab->nblocks = 0;
223 
224  /* initialize the freelist slots */
225  for (i = 0; i < (slab->chunksPerBlock + 1); i++)
226  dlist_init(&slab->freelist[i]);
227 
228 #ifdef MEMORY_CONTEXT_CHECKING
229  /* set the freechunks pointer right after the freelists array */
230  slab->freechunks
231  = (bool *) slab + offsetof(SlabContext, freelist) + freelistSize;
232 #endif
233 
234  /* Finally, do the type-independent part of context creation */
236  T_SlabContext,
237  MCTX_SLAB_ID,
238  parent,
239  name);
240 
241  return (MemoryContext) slab;
242 }
unsigned char bool
Definition: c.h:392
struct dlist_head dlist_head
int i
Definition: isn.c:73
@ MCTX_SLAB_ID
#define Slab_BLOCKHDRSZ
Definition: slab.c:61
#define Slab_CHUNKHDRSZ
Definition: slab.c:101

References Assert(), SlabContext::blockSize, SlabContext::chunkSize, SlabContext::chunksPerBlock, dlist_init(), elog(), ereport, errcode(), errdetail(), errmsg(), ERROR, SlabContext::freelist, SlabContext::fullChunkSize, SlabContext::headerSize, i, malloc, MAXALIGN, MCTX_SLAB_ID, MEMORYCHUNK_MAX_VALUE, MemoryContextCreate(), MemoryContextStats(), SlabContext::minFreeChunks, name, SlabContext::nblocks, Slab_BLOCKHDRSZ, Slab_CHUNKHDRSZ, StaticAssertStmt, and TopMemoryContext.

Referenced by ReorderBufferAllocate().

Variable Documentation

◆ CacheMemoryContext

PGDLLIMPORT MemoryContext CacheMemoryContext
extern

Definition at line 133 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_rel_sync_entry(), get_tablespace(), GetCachedExpression(), GetCachedPlan(), GetFdwRoutineForRelation(), init_ts_config_cache(), init_tuple_slot(), 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(), 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(), and SPI_keepplan().

◆ CurTransactionContext

◆ ErrorContext

◆ MessageContext

◆ PortalContext

◆ PostmasterContext

◆ TopMemoryContext

PGDLLIMPORT MemoryContext TopMemoryContext
extern

Definition at line 130 of file mcxt.c.

Referenced by _PG_init(), add_reloption(), allocate_reloption(), AllocateAttribute(), AllocSetContextCreateInternal(), ApplyLauncherMain(), ApplyWorkerMain(), AtAbort_Memory(), AtCleanup_Memory(), AtCommit_Memory(), AtStart_Memory(), AttachSession(), AutoVacLauncherMain(), BackendRun(), BackgroundWriterMain(), BaseBackupAddTarget(), be_tls_open_server(), build_guc_variables(), cache_single_string(), check_foreign_key(), check_primary_key(), CheckpointerMain(), ClientAuthentication(), compile_plperl_function(), compile_pltcl_function(), CreateCacheMemoryContext(), dblink_connect(), dblink_init(), DCH_cache_getnew(), do_autovacuum(), do_compile(), do_start_bgworker(), dsm_create_descriptor(), dsm_impl_sysv(), EnablePortalManager(), EventTriggerBeginCompleteQuery(), Exec_ListenCommit(), executeDateTimeMethod(), find_plan(), finish_xact_command(), GenerationContextCreate(), GetLocalBufferStorage(), GetLockConflicts(), GetSessionDsmHandle(), HandleParallelMessages(), hash_create(), init_string_reloption(), InitDeadLockChecking(), initialize_reloptions(), initialize_target_list(), InitializeClientEncoding(), InitializeLatchWaitSet(), InitializeParallelDSM(), InitializeSearchPath(), InitializeSession(), InitializeSystemUser(), InitSync(), InitXLogInsert(), llvm_compile_module(), llvm_create_context(), llvm_session_initialize(), LockAcquireExtended(), LogicalRepApplyLoop(), LWLockRegisterTranche(), make_icu_collator(), mdinit(), MemoryContextAlloc(), MemoryContextAllocExtended(), MemoryContextAllocHuge(), MemoryContextAllocZero(), MemoryContextAllocZeroAligned(), MemoryContextDelete(), MemoryContextInit(), mxid_to_string(), newLOfd(), NUM_cache_getnew(), on_dsm_detach(), PageSetChecksumCopy(), palloc(), palloc0(), palloc_extended(), ParallelWorkerMain(), PerformAuthentication(), pg_backup_start(), pg_get_backend_memory_contexts(), pg_newlocale_from_collation(), pgstat_attach_shmem(), pgstat_prep_pending_entry(), pgstat_prep_snapshot(), pgstat_setup_backend_status_context(), pgstat_setup_memcxt(), plperl_spi_prepare(), plpgsql_estate_setup(), 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(), PostmasterMain(), pq_init(), PrepareClientEncoding(), ProcessLogMemoryContextInterrupt(), ProcessStartupPacket(), PushOverrideSearchPath(), px_find_cipher(), px_find_digest(), recomputeNamespacePath(), register_label_provider(), RegisterResourceReleaseCallback(), RegisterSubXactCallback(), RegisterXactCallback(), RelationCreateStorage(), RelationDropStorage(), repalloc(), repalloc_extended(), RequestNamedLWLockTranche(), ResourceArrayEnlarge(), ResourceOwnerCreate(), RestoreClientConnectionInfo(), RestoreReindexState(), ri_HashCompareOp(), roles_is_member_of(), secure_open_gssapi(), sepgsql_avc_init(), sepgsql_xact_callback(), set_authn_id(), SetDatabasePath(), SharedRecordTypmodRegistryAttach(), SharedRecordTypmodRegistryInit(), SlabContextCreate(), SPI_connect_ext(), StartChildProcess(), WalWriterMain(), and XLOGShmemInit().

◆ TopTransactionContext