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)
 

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.

◆ 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 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,
421  MCTX_ASET_ID,
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  {
447  if (TopMemoryContext)
449  ereport(ERROR,
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,
515  MCTX_ASET_ID,
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
unsigned int uint32
Definition: c.h:493
#define MAXALIGN(LEN)
Definition: c.h:798
#define Max(x, y)
Definition: c.h:985
#define MemSetAligned(start, val, len)
Definition: c.h:1037
#define StaticAssertDecl(condition, errmessage)
Definition: c.h:923
#define StaticAssertStmt(condition, errmessage)
Definition: c.h:925
size_t Size
Definition: c.h:592
int errdetail(const char *fmt,...)
Definition: elog.c:1205
int errcode(int sqlerrcode)
Definition: elog.c:859
int errmsg(const char *fmt,...)
Definition: elog.c:1072
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
#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:1088
MemoryContext TopMemoryContext
Definition: mcxt.c:137
void MemoryContextStats(MemoryContext context)
Definition: mcxt.c:802
#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: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.

◆ 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;
168  GenerationContext *set;
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  {
213  ereport(ERROR,
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) >
258  (Size) ((Size) (maxBlockSize - Generation_BLOCKHDRSZ) / Generation_CHUNK_FRACTION))
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 }
#define Min(x, y)
Definition: c.h:991
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
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_GENERATION_ID
#define MEMORYCHUNK_MAX_VALUE
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 tuplesort_begin_batch().

◆ GetMemoryChunkContext()

MemoryContext GetMemoryChunkContext ( void *  pointer)

Definition at line 695 of file mcxt.c.

696 {
697  return MCXT_METHOD(pointer, get_chunk_context) (pointer);
698 }
#define MCXT_METHOD(pointer, method)
Definition: mcxt.c:170

References MCXT_METHOD.

Referenced by AlignedAllocFree(), AlignedAllocGetChunkContext(), AlignedAllocRealloc(), 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 1259 of file mcxt.c.

1260 {
1261  InterruptPending = true;
1262  LogMemoryContextPending = true;
1263  /* latch will be set by procsignal_sigusr1_handler */
1264 }
volatile sig_atomic_t LogMemoryContextPending
Definition: globals.c:39
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 682 of file mcxt.c.

683 {
684  Assert(MemoryContextIsValid(context));
685 
686  context->allowInCritSection = allow;
687 }
#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 442 of file mcxt.c.

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

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

Referenced by _brin_end_parallel(), AfterTriggerEndXact(), afterTriggerInvokeEvents(), ApplyLauncherMain(), AtCleanup_Memory(), AtCommit_Memory(), AtEOSubXact_SPI(), AtEOXact_LargeObject(), AtSubCleanup_Memory(), AtSubCommit_Memory(), AttachPartitionEnsureIndexes(), autovacuum_do_vac_analyze(), AutoVacWorkerMain(), AuxiliaryProcessMainCommon(), BackgroundWorkerMain(), basic_archive_shutdown(), 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_plan_dealloc(), PLy_pop_execution_context(), PLy_procedure_delete(), PLy_spi_execute_fetch_result(), PortalDrop(), PostgresMain(), printtup_shutdown(), publicationListToArray(), RE_compile_and_cache(), 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(), statext_dependencies_build(), strlist_to_textarray(), SysLoggerMain(), test_pattern(), tokenize_auth_file(), tuplesort_end(), union_tuples(), UploadManifest(), and validateForeignKeyConstraint().

◆ MemoryContextDeleteChildren()

void MemoryContextDeleteChildren ( MemoryContext  context)

Definition at line 527 of file mcxt.c.

528 {
529  Assert(MemoryContextIsValid(context));
530 
531  /*
532  * MemoryContextDelete will delink the child from me, so just iterate as
533  * long as there is a child.
534  */
535  while (context->firstchild != NULL)
537 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:442

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

328 {
329  Assert(TopMemoryContext == NULL);
330 
331  /*
332  * First, initialize TopMemoryContext, which is the parent of all others.
333  */
335  "TopMemoryContext",
337 
338  /*
339  * Not having any other place to point CurrentMemoryContext, make it point
340  * to TopMemoryContext. Caller should change this soon!
341  */
343 
344  /*
345  * Initialize ErrorContext as an AllocSetContext with slow growth rate ---
346  * we don't really expect much to be allocated in it. More to the point,
347  * require it to contain at least 8K at all times. This is the only case
348  * where retained memory in a context is *essential* --- we want to be
349  * sure ErrorContext still has some memory even if we've run out
350  * elsewhere! Also, allow allocations in ErrorContext within a critical
351  * section. Otherwise a PANIC will cause an assertion failure in the error
352  * reporting code, before printing out the real cause of the failure.
353  *
354  * This should be the last step in this function, as elog.c assumes memory
355  * management works once ErrorContext is non-null.
356  */
358  "ErrorContext",
359  8 * 1024,
360  8 * 1024,
361  8 * 1024);
363 }
MemoryContext CurrentMemoryContext
Definition: mcxt.c:131
MemoryContext ErrorContext
Definition: mcxt.c:138
void MemoryContextAllowInCriticalSection(MemoryContext context, bool allow)
Definition: mcxt.c:682
#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 731 of file mcxt.c.

732 {
733  Assert(MemoryContextIsValid(context));
734 
735  /*
736  * For now, we consider a memory context nonempty if it has any children;
737  * perhaps this should be changed later.
738  */
739  if (context->firstchild != NULL)
740  return false;
741  /* Otherwise use the type-specific inquiry */
742  return context->methods->is_empty(context);
743 }
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 750 of file mcxt.c.

751 {
752  Size total = context->mem_allocated;
753 
754  Assert(MemoryContextIsValid(context));
755 
756  if (recurse)
757  {
758  for (MemoryContext curr = context->firstchild;
759  curr != NULL;
760  curr = MemoryContextTraverseNext(curr, context))
761  {
762  total += curr->mem_allocated;
763  }
764  }
765 
766  return total;
767 }
static MemoryContext MemoryContextTraverseNext(MemoryContext curr, MemoryContext top)
Definition: mcxt.c:245

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

Referenced by hash_agg_check_limits(), and hash_agg_update_metrics().

◆ MemoryContextMemConsumed()

void MemoryContextMemConsumed ( MemoryContext  context,
MemoryContextCounters consumed 
)

Definition at line 774 of file mcxt.c.

776 {
777  Assert(MemoryContextIsValid(context));
778 
779  memset(consumed, 0, sizeof(*consumed));
780 
781  /* Examine the context itself */
782  context->methods->stats(context, NULL, NULL, consumed, false);
783 
784  /* Examine children, using iteration not recursion */
785  for (MemoryContext curr = context->firstchild;
786  curr != NULL;
787  curr = MemoryContextTraverseNext(curr, context))
788  {
789  curr->methods->stats(curr, NULL, NULL, consumed, false);
790  }
791 }
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 371 of file mcxt.c.

372 {
373  Assert(MemoryContextIsValid(context));
374 
375  /* save a function call in common case where there are no children */
376  if (context->firstchild != NULL)
378 
379  /* save a function call if no pallocs since startup or last reset */
380  if (!context->isReset)
381  MemoryContextResetOnly(context);
382 }
void MemoryContextDeleteChildren(MemoryContext context)
Definition: mcxt.c:527
void MemoryContextResetOnly(MemoryContext context)
Definition: mcxt.c:390

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

Referenced by _brin_end_parallel(), _bt_preprocess_array_keys(), _SPI_end_call(), AfterTriggerExecute(), apply_spooled_messages(), AtCleanup_Memory(), AtEOSubXact_SPI(), AtSubCleanup_Memory(), BackgroundWriterMain(), basic_archive_file(), 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_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(), 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(), scanPendingInsert(), sepgsql_avc_reset(), spcache_init(), spg_redo(), spginsert(), spgistBuildCallback(), spgWalk(), startScanKey(), statext_dependencies_build(), storeRow(), stream_stop_internal(), tfuncFetchRows(), tfuncLoadRows(), tuplesort_free(), validateForeignKeyConstraint(), WalSummarizerMain(), and WalWriterMain().

◆ MemoryContextResetChildren()

void MemoryContextResetChildren ( MemoryContext  context)

Definition at line 421 of file mcxt.c.

422 {
423  Assert(MemoryContextIsValid(context));
424 
425  for (MemoryContext curr = context->firstchild;
426  curr != NULL;
427  curr = MemoryContextTraverseNext(curr, context))
428  {
430  }
431 }

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

◆ MemoryContextResetOnly()

void MemoryContextResetOnly ( MemoryContext  context)

Definition at line 390 of file mcxt.c.

391 {
392  Assert(MemoryContextIsValid(context));
393 
394  /* Nothing to do if no pallocs since startup or last reset */
395  if (!context->isReset)
396  {
398 
399  /*
400  * If context->ident points into the context's memory, it will become
401  * a dangling pointer. We could prevent that by setting it to NULL
402  * here, but that would break valid coding patterns that keep the
403  * ident elsewhere, e.g. in a parent context. So for now we assume
404  * the programmer got it right.
405  */
406 
407  context->methods->reset(context);
408  context->isReset = true;
409  VALGRIND_DESTROY_MEMPOOL(context);
410  VALGRIND_CREATE_MEMPOOL(context, 0, false);
411  }
412 }
static void MemoryContextCallResetCallbacks(MemoryContext context)
Definition: mcxt.c:573
#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(), MemoryContextReset(), MemoryContextResetChildren(), and mergeruns().

◆ MemoryContextSetIdentifier()

void MemoryContextSetIdentifier ( MemoryContext  context,
const char *  id 
)

◆ MemoryContextSetParent()

void MemoryContextSetParent ( MemoryContext  context,
MemoryContext  new_parent 
)

Definition at line 625 of file mcxt.c.

626 {
627  Assert(MemoryContextIsValid(context));
628  Assert(context != new_parent);
629 
630  /* Fast path if it's got correct parent already */
631  if (new_parent == context->parent)
632  return;
633 
634  /* Delink from existing parent, if any */
635  if (context->parent)
636  {
637  MemoryContext parent = context->parent;
638 
639  if (context->prevchild != NULL)
640  context->prevchild->nextchild = context->nextchild;
641  else
642  {
643  Assert(parent->firstchild == context);
644  parent->firstchild = context->nextchild;
645  }
646 
647  if (context->nextchild != NULL)
648  context->nextchild->prevchild = context->prevchild;
649  }
650 
651  /* And relink */
652  if (new_parent)
653  {
654  Assert(MemoryContextIsValid(new_parent));
655  context->parent = new_parent;
656  context->prevchild = NULL;
657  context->nextchild = new_parent->firstchild;
658  if (new_parent->firstchild != NULL)
659  new_parent->firstchild->prevchild = context;
660  new_parent->firstchild = context;
661  }
662  else
663  {
664  context->parent = NULL;
665  context->prevchild = NULL;
666  context->nextchild = NULL;
667  }
668 }
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(), RelationClearRelation(), RevalidateCachedQuery(), SaveCachedPlan(), SPI_keepplan(), TransferExpandedObject(), and UploadManifest().

◆ MemoryContextStats()

void MemoryContextStats ( MemoryContext  context)

Definition at line 802 of file mcxt.c.

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

References MemoryContextStatsDetail().

Referenced by AllocSetContextCreateInternal(), 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 817 of file mcxt.c.

820 {
821  MemoryContextCounters grand_totals;
822 
823  memset(&grand_totals, 0, sizeof(grand_totals));
824 
825  MemoryContextStatsInternal(context, 0, max_level, max_children,
826  &grand_totals, print_to_stderr);
827 
828  if (print_to_stderr)
829  fprintf(stderr,
830  "Grand total: %zu bytes in %zu blocks; %zu free (%zu chunks); %zu used\n",
831  grand_totals.totalspace, grand_totals.nblocks,
832  grand_totals.freespace, grand_totals.freechunks,
833  grand_totals.totalspace - grand_totals.freespace);
834  else
835  {
836  /*
837  * Use LOG_SERVER_ONLY to prevent the memory contexts from being sent
838  * to the connected client.
839  *
840  * We don't buffer the information about all memory contexts in a
841  * backend into StringInfo and log it as one message. That would
842  * require the buffer to be enlarged, risking an OOM as there could be
843  * a large number of memory contexts in a backend. Instead, we log
844  * one message per memory context.
845  */
847  (errhidestmt(true),
848  errhidecontext(true),
849  errmsg_internal("Grand total: %zu bytes in %zu blocks; %zu free (%zu chunks); %zu used",
850  grand_totals.totalspace, grand_totals.nblocks,
851  grand_totals.freespace, grand_totals.freechunks,
852  grand_totals.totalspace - grand_totals.freespace)));
853  }
854 }
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1159
int errhidestmt(bool hide_stmt)
Definition: elog.c:1413
int errhidecontext(bool hide_ctx)
Definition: elog.c:1432
#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:864
#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 1276 of file mcxt.c.

1277 {
1278  LogMemoryContextPending = false;
1279 
1280  /*
1281  * Use LOG_SERVER_ONLY to prevent this message from being sent to the
1282  * connected client.
1283  */
1285  (errhidestmt(true),
1286  errhidecontext(true),
1287  errmsg("logging memory contexts of PID %d", MyProcPid)));
1288 
1289  /*
1290  * When a backend process is consuming huge memory, logging all its memory
1291  * contexts might overrun available disk space. To prevent this, we limit
1292  * the depth of the hierarchy, as well as the number of child contexts to
1293  * log per parent to 100.
1294  *
1295  * As with MemoryContextStats(), we suppose that practical cases where the
1296  * dump gets long will typically be huge numbers of siblings under the
1297  * same parent context; while the additional debugging value from seeing
1298  * details about individual siblings beyond 100 will not be large.
1299  */
1300  MemoryContextStatsDetail(TopMemoryContext, 100, 100, false);
1301 }
int MyProcPid
Definition: globals.c:45

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");
335  Assert(blockSize <= MEMORYCHUNK_MAX_BLOCKOFFSET);
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  {
368  ereport(ERROR,
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,
416  MCTX_SLAB_ID,
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:73
@ 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 ReorderBufferAllocate().

Variable Documentation

◆ CacheMemoryContext

PGDLLIMPORT MemoryContext CacheMemoryContext
extern

Definition at line 140 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(), SPI_keepplan(), and UploadManifest().

◆ CurTransactionContext

◆ ErrorContext

◆ MessageContext

◆ PortalContext

◆ PostmasterContext

◆ TopMemoryContext

PGDLLIMPORT MemoryContext TopMemoryContext
extern

Definition at line 137 of file mcxt.c.

Referenced by _PG_init(), add_reloption(), allocate_reloption(), AllocateAttribute(), AllocSetContextCreateInternal(), ApplyLauncherMain(), AtAbort_Memory(), AtCleanup_Memory(), AtCommit_Memory(), AtStart_Memory(), AttachSession(), BackendInitialize(), BackendMain(), BackgroundWorkerMain(), BackgroundWriterMain(), BaseBackupAddTarget(), basic_archive_startup(), be_tls_open_server(), build_guc_variables(), cache_single_string(), check_foreign_key(), check_primary_key(), CheckMyDatabase(), 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_missing_cache(), init_string_reloption(), InitDeadLockChecking(), initialize_reloptions(), initialize_target_list(), InitializeClientEncoding(), InitializeLogRepWorker(), InitializeParallelDSM(), InitializeSearchPath(), InitializeSession(), InitializeSystemUser(), InitSync(), InitXLogInsert(), llvm_compile_module(), llvm_create_context(), llvm_session_initialize(), LockAcquireExtended(), logicalrep_launcher_attach_dshmem(), LogicalRepApplyLoop(), LWLockRegisterTranche(), make_icu_collator(), 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(), pgstat_attach_shmem(), pgstat_prep_pending_entry(), pgstat_prep_snapshot(), 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(), SPI_connect_ext(), WalSummarizerMain(), WalWriterMain(), and XLOGShmemInit().

◆ TopTransactionContext