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:795
#define Max(x, y)
Definition: c.h:982
#define MemSetAligned(start, val, len)
Definition: c.h:1034
#define StaticAssertDecl(condition, errmessage)
Definition: c.h:920
#define StaticAssertStmt(condition, errmessage)
Definition: c.h:922
size_t Size
Definition: c.h:589
int errdetail(const char *fmt,...)
Definition: elog.c:1202
int errcode(int sqlerrcode)
Definition: elog.c:858
int errmsg(const char *fmt,...)
Definition: elog.c:1069
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
const char * name
Definition: encode.c:571
#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:957
MemoryContext TopMemoryContext
Definition: mcxt.c:141
void MemoryContextStats(MemoryContext context)
Definition: mcxt.c:683
#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, 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 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:988
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:347
@ 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, StaticAssertDecl, and TopMemoryContext.

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

◆ GetMemoryChunkContext()

MemoryContext GetMemoryChunkContext ( void *  pointer)

Definition at line 600 of file mcxt.c.

601 {
602  return MCXT_METHOD(pointer, get_chunk_context) (pointer);
603 }
#define MCXT_METHOD(pointer, method)
Definition: mcxt.c:173

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

1167 {
1168  InterruptPending = true;
1169  LogMemoryContextPending = true;
1170  /* latch will be set by procsignal_sigusr1_handler */
1171 }
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 587 of file mcxt.c.

588 {
589  Assert(MemoryContextIsValid(context));
590 
591  context->allowInCritSection = allow;
592 }
#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 387 of file mcxt.c.

388 {
389  Assert(MemoryContextIsValid(context));
390  /* We had better not be deleting TopMemoryContext ... */
391  Assert(context != TopMemoryContext);
392  /* And not CurrentMemoryContext, either */
393  Assert(context != CurrentMemoryContext);
394 
395  /* save a function call in common case where there are no children */
396  if (context->firstchild != NULL)
398 
399  /*
400  * It's not entirely clear whether 'tis better to do this before or after
401  * delinking the context; but an error in a callback will likely result in
402  * leaking the whole context (if it's not a root context) if we do it
403  * after, so let's do it before.
404  */
406 
407  /*
408  * We delink the context from its parent before deleting it, so that if
409  * there's an error we won't have deleted/busted contexts still attached
410  * to the context tree. Better a leak than a crash.
411  */
412  MemoryContextSetParent(context, NULL);
413 
414  /*
415  * Also reset the context's ident pointer, in case it points into the
416  * context. This would only matter if someone tries to get stats on the
417  * (already unlinked) context, which is unlikely, but let's be safe.
418  */
419  context->ident = NULL;
420 
421  context->methods->delete_context(context);
422 
423  VALGRIND_DESTROY_MEMPOOL(context);
424 }
static void MemoryContextCallResetCallbacks(MemoryContext context)
Definition: mcxt.c:478
void MemoryContextSetParent(MemoryContext context, MemoryContext new_parent)
Definition: mcxt.c:530
void MemoryContextDeleteChildren(MemoryContext context)
Definition: mcxt.c:432
MemoryContext CurrentMemoryContext
Definition: mcxt.c:135
#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(), 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(), 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(), 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(), 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 432 of file mcxt.c.

433 {
434  Assert(MemoryContextIsValid(context));
435 
436  /*
437  * MemoryContextDelete will delink the child from me, so just iterate as
438  * long as there is a child.
439  */
440  while (context->firstchild != NULL)
442 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:387

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

625 {
626  Assert(MemoryContextIsValid(context));
627 
628  return context->parent;
629 }
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 270 of file mcxt.c.

271 {
272  Assert(TopMemoryContext == NULL);
273 
274  /*
275  * First, initialize TopMemoryContext, which is the parent of all others.
276  */
278  "TopMemoryContext",
280 
281  /*
282  * Not having any other place to point CurrentMemoryContext, make it point
283  * to TopMemoryContext. Caller should change this soon!
284  */
286 
287  /*
288  * Initialize ErrorContext as an AllocSetContext with slow growth rate ---
289  * we don't really expect much to be allocated in it. More to the point,
290  * require it to contain at least 8K at all times. This is the only case
291  * where retained memory in a context is *essential* --- we want to be
292  * sure ErrorContext still has some memory even if we've run out
293  * elsewhere! Also, allow allocations in ErrorContext within a critical
294  * section. Otherwise a PANIC will cause an assertion failure in the error
295  * reporting code, before printing out the real cause of the failure.
296  *
297  * This should be the last step in this function, as elog.c assumes memory
298  * management works once ErrorContext is non-null.
299  */
301  "ErrorContext",
302  8 * 1024,
303  8 * 1024,
304  8 * 1024);
306 }
MemoryContext ErrorContext
Definition: mcxt.c:142
void MemoryContextAllowInCriticalSection(MemoryContext context, bool allow)
Definition: mcxt.c:587
#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 636 of file mcxt.c.

637 {
638  Assert(MemoryContextIsValid(context));
639 
640  /*
641  * For now, we consider a memory context nonempty if it has any children;
642  * perhaps this should be changed later.
643  */
644  if (context->firstchild != NULL)
645  return false;
646  /* Otherwise use the type-specific inquiry */
647  return context->methods->is_empty(context);
648 }
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 655 of file mcxt.c.

656 {
657  Size total = context->mem_allocated;
658 
659  Assert(MemoryContextIsValid(context));
660 
661  if (recurse)
662  {
663  MemoryContext child;
664 
665  for (child = context->firstchild;
666  child != NULL;
667  child = child->nextchild)
668  total += MemoryContextMemAllocated(child, true);
669  }
670 
671  return total;
672 }
Size MemoryContextMemAllocated(MemoryContext context, bool recurse)
Definition: mcxt.c:655
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 314 of file mcxt.c.

315 {
316  Assert(MemoryContextIsValid(context));
317 
318  /* save a function call in common case where there are no children */
319  if (context->firstchild != NULL)
321 
322  /* save a function call if no pallocs since startup or last reset */
323  if (!context->isReset)
324  MemoryContextResetOnly(context);
325 }
void MemoryContextResetOnly(MemoryContext context)
Definition: mcxt.c:333

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

Referenced by _bt_preprocess_array_keys(), AfterTriggerExecute(), 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(), GetWALRecordsInfo(), GetXLogSummaryStats(), gin_redo(), ginBuildCallback(), 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(), keyGetItem(), libpqrcv_processTuples(), LogicalParallelApplyLoop(), LogicalRepApplyLoop(), lookup_ts_dictionary_cache(), make_tuple_from_result_row(), 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(), printtup(), process_ordered_aggregate_single(), ReScanExprContext(), resetSpGistScanOpaque(), scanPendingInsert(), sepgsql_avc_reset(), spg_redo(), spginsert(), spgistBuildCallback(), spgWalk(), startScanKey(), statext_dependencies_build(), storeRow(), stream_stop_internal(), tfuncFetchRows(), tfuncLoadRows(), tuplesort_free(), and validateForeignKeyConstraint().

◆ MemoryContextResetChildren()

void MemoryContextResetChildren ( MemoryContext  context)

Definition at line 364 of file mcxt.c.

365 {
366  MemoryContext child;
367 
368  Assert(MemoryContextIsValid(context));
369 
370  for (child = context->firstchild; child != NULL; child = child->nextchild)
371  {
373  MemoryContextResetOnly(child);
374  }
375 }
void MemoryContextResetChildren(MemoryContext context)
Definition: mcxt.c:364

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

◆ MemoryContextResetOnly()

void MemoryContextResetOnly ( MemoryContext  context)

Definition at line 333 of file mcxt.c.

334 {
335  Assert(MemoryContextIsValid(context));
336 
337  /* Nothing to do if no pallocs since startup or last reset */
338  if (!context->isReset)
339  {
341 
342  /*
343  * If context->ident points into the context's memory, it will become
344  * a dangling pointer. We could prevent that by setting it to NULL
345  * here, but that would break valid coding patterns that keep the
346  * ident elsewhere, e.g. in a parent context. So for now we assume
347  * the programmer got it right.
348  */
349 
350  context->methods->reset(context);
351  context->isReset = true;
352  VALGRIND_DESTROY_MEMPOOL(context);
353  VALGRIND_CREATE_MEMPOOL(context, 0, false);
354  }
355 }
#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 530 of file mcxt.c.

531 {
532  Assert(MemoryContextIsValid(context));
533  Assert(context != new_parent);
534 
535  /* Fast path if it's got correct parent already */
536  if (new_parent == context->parent)
537  return;
538 
539  /* Delink from existing parent, if any */
540  if (context->parent)
541  {
542  MemoryContext parent = context->parent;
543 
544  if (context->prevchild != NULL)
545  context->prevchild->nextchild = context->nextchild;
546  else
547  {
548  Assert(parent->firstchild == context);
549  parent->firstchild = context->nextchild;
550  }
551 
552  if (context->nextchild != NULL)
553  context->nextchild->prevchild = context->prevchild;
554  }
555 
556  /* And relink */
557  if (new_parent)
558  {
559  Assert(MemoryContextIsValid(new_parent));
560  context->parent = new_parent;
561  context->prevchild = NULL;
562  context->nextchild = new_parent->firstchild;
563  if (new_parent->firstchild != NULL)
564  new_parent->firstchild->prevchild = context;
565  new_parent->firstchild = context;
566  }
567  else
568  {
569  context->parent = NULL;
570  context->prevchild = NULL;
571  context->nextchild = NULL;
572  }
573 }
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 683 of file mcxt.c.

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

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

700 {
701  MemoryContextCounters grand_totals;
702 
703  memset(&grand_totals, 0, sizeof(grand_totals));
704 
705  MemoryContextStatsInternal(context, 0, true, max_children, &grand_totals, print_to_stderr);
706 
707  if (print_to_stderr)
708  fprintf(stderr,
709  "Grand total: %zu bytes in %zu blocks; %zu free (%zu chunks); %zu used\n",
710  grand_totals.totalspace, grand_totals.nblocks,
711  grand_totals.freespace, grand_totals.freechunks,
712  grand_totals.totalspace - grand_totals.freespace);
713  else
714 
715  /*
716  * Use LOG_SERVER_ONLY to prevent the memory contexts from being sent
717  * to the connected client.
718  *
719  * We don't buffer the information about all memory contexts in a
720  * backend into StringInfo and log it as one message. That would
721  * require the buffer to be enlarged, risking an OOM as there could
722  * be a large number of memory contexts in a backend. Instead, we
723  * log one message per memory context.
724  */
726  (errhidestmt(true),
727  errhidecontext(true),
728  errmsg_internal("Grand total: %zu bytes in %zu blocks; %zu free (%zu chunks); %zu used",
729  grand_totals.totalspace, grand_totals.nblocks,
730  grand_totals.freespace, grand_totals.freechunks,
731  grand_totals.totalspace - grand_totals.freespace)));
732 }
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1156
int errhidestmt(bool hide_stmt)
Definition: elog.c:1410
int errhidecontext(bool hide_ctx)
Definition: elog.c:1429
#define LOG_SERVER_ONLY
Definition: elog.h:32
static void MemoryContextStatsInternal(MemoryContext context, int level, bool print, int max_children, MemoryContextCounters *totals, bool print_to_stderr)
Definition: mcxt.c:742
#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 1183 of file mcxt.c.

1184 {
1185  LogMemoryContextPending = false;
1186 
1187  /*
1188  * Use LOG_SERVER_ONLY to prevent this message from being sent to the
1189  * connected client.
1190  */
1192  (errhidestmt(true),
1193  errhidecontext(true),
1194  errmsg("logging memory contexts of PID %d", MyProcPid)));
1195 
1196  /*
1197  * When a backend process is consuming huge memory, logging all its memory
1198  * contexts might overrun available disk space. To prevent this, we limit
1199  * the number of child contexts to log per parent to 100.
1200  *
1201  * As with MemoryContextStats(), we suppose that practical cases where the
1202  * dump gets long will typically be huge numbers of siblings under the
1203  * same parent context; while the additional debugging value from seeing
1204  * details about individual siblings beyond 100 will not be large.
1205  */
1207 }
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 320 of file slab.c.

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

Referenced by _PG_init(), add_reloption(), allocate_reloption(), AllocateAttribute(), AllocSetContextCreateInternal(), ApplyLauncherMain(), AtAbort_Memory(), AtCleanup_Memory(), AtCommit_Memory(), AtStart_Memory(), AttachSession(), AutoVacLauncherMain(), BackendRun(), BackgroundWriterMain(), BaseBackupAddTarget(), basic_archive_startup(), 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(), HandleParallelApplyMessages(), HandleParallelMessages(), hash_create(), init_string_reloption(), InitDeadLockChecking(), initialize_reloptions(), initialize_target_list(), InitializeApplyWorker(), InitializeClientEncoding(), InitializeLatchWaitSet(), 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(), 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