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 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:495
#define MAXALIGN(LEN)
Definition: c.h:800
#define Max(x, y)
Definition: c.h:987
#define MemSetAligned(start, val, len)
Definition: c.h:1039
#define StaticAssertDecl(condition, errmessage)
Definition: c.h:925
#define StaticAssertStmt(condition, errmessage)
Definition: c.h:927
size_t Size
Definition: c.h:594
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
#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:973
MemoryContext TopMemoryContext
Definition: mcxt.c:141
void MemoryContextStats(MemoryContext context)
Definition: mcxt.c:699
#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:92
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 157 of file generation.c.

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

617 {
618  return MCXT_METHOD(pointer, get_chunk_context) (pointer);
619 }
#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 1182 of file mcxt.c.

1183 {
1184  InterruptPending = true;
1185  LogMemoryContextPending = true;
1186  /* latch will be set by procsignal_sigusr1_handler */
1187 }
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 603 of file mcxt.c.

604 {
605  Assert(MemoryContextIsValid(context));
606 
607  context->allowInCritSection = allow;
608 }
#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 403 of file mcxt.c.

404 {
405  Assert(MemoryContextIsValid(context));
406  /* We had better not be deleting TopMemoryContext ... */
407  Assert(context != TopMemoryContext);
408  /* And not CurrentMemoryContext, either */
409  Assert(context != CurrentMemoryContext);
410 
411  /* save a function call in common case where there are no children */
412  if (context->firstchild != NULL)
414 
415  /*
416  * It's not entirely clear whether 'tis better to do this before or after
417  * delinking the context; but an error in a callback will likely result in
418  * leaking the whole context (if it's not a root context) if we do it
419  * after, so let's do it before.
420  */
422 
423  /*
424  * We delink the context from its parent before deleting it, so that if
425  * there's an error we won't have deleted/busted contexts still attached
426  * to the context tree. Better a leak than a crash.
427  */
428  MemoryContextSetParent(context, NULL);
429 
430  /*
431  * Also reset the context's ident pointer, in case it points into the
432  * context. This would only matter if someone tries to get stats on the
433  * (already unlinked) context, which is unlikely, but let's be safe.
434  */
435  context->ident = NULL;
436 
437  context->methods->delete_context(context);
438 
439  VALGRIND_DESTROY_MEMPOOL(context);
440 }
static void MemoryContextCallResetCallbacks(MemoryContext context)
Definition: mcxt.c:494
void MemoryContextSetParent(MemoryContext context, MemoryContext new_parent)
Definition: mcxt.c:546
void MemoryContextDeleteChildren(MemoryContext context)
Definition: mcxt.c:448
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(), autovacuum_do_vac_analyze(), 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_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(), 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(), StartChildProcess(), statext_dependencies_build(), strlist_to_textarray(), test_pattern(), tokenize_auth_file(), tuplesort_end(), union_tuples(), and validateForeignKeyConstraint().

◆ MemoryContextDeleteChildren()

void MemoryContextDeleteChildren ( MemoryContext  context)

Definition at line 448 of file mcxt.c.

449 {
450  Assert(MemoryContextIsValid(context));
451 
452  /*
453  * MemoryContextDelete will delink the child from me, so just iterate as
454  * long as there is a child.
455  */
456  while (context->firstchild != NULL)
458 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:403

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

641 {
642  Assert(MemoryContextIsValid(context));
643 
644  return context->parent;
645 }
MemoryContext parent
Definition: memnodes.h:89

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

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

◆ MemoryContextInit()

void MemoryContextInit ( void  )

Definition at line 286 of file mcxt.c.

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

653 {
654  Assert(MemoryContextIsValid(context));
655 
656  /*
657  * For now, we consider a memory context nonempty if it has any children;
658  * perhaps this should be changed later.
659  */
660  if (context->firstchild != NULL)
661  return false;
662  /* Otherwise use the type-specific inquiry */
663  return context->methods->is_empty(context);
664 }
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 671 of file mcxt.c.

672 {
673  Size total = context->mem_allocated;
674 
675  Assert(MemoryContextIsValid(context));
676 
677  if (recurse)
678  {
679  MemoryContext child;
680 
681  for (child = context->firstchild;
682  child != NULL;
683  child = child->nextchild)
684  total += MemoryContextMemAllocated(child, true);
685  }
686 
687  return total;
688 }
Size MemoryContextMemAllocated(MemoryContext context, bool recurse)
Definition: mcxt.c:671
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 330 of file mcxt.c.

331 {
332  Assert(MemoryContextIsValid(context));
333 
334  /* save a function call in common case where there are no children */
335  if (context->firstchild != NULL)
337 
338  /* save a function call if no pallocs since startup or last reset */
339  if (!context->isReset)
340  MemoryContextResetOnly(context);
341 }
void MemoryContextResetOnly(MemoryContext context)
Definition: mcxt.c:349

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

381 {
382  MemoryContext child;
383 
384  Assert(MemoryContextIsValid(context));
385 
386  for (child = context->firstchild; child != NULL; child = child->nextchild)
387  {
389  MemoryContextResetOnly(child);
390  }
391 }
void MemoryContextResetChildren(MemoryContext context)
Definition: mcxt.c:380

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

◆ MemoryContextResetOnly()

void MemoryContextResetOnly ( MemoryContext  context)

Definition at line 349 of file mcxt.c.

350 {
351  Assert(MemoryContextIsValid(context));
352 
353  /* Nothing to do if no pallocs since startup or last reset */
354  if (!context->isReset)
355  {
357 
358  /*
359  * If context->ident points into the context's memory, it will become
360  * a dangling pointer. We could prevent that by setting it to NULL
361  * here, but that would break valid coding patterns that keep the
362  * ident elsewhere, e.g. in a parent context. So for now we assume
363  * the programmer got it right.
364  */
365 
366  context->methods->reset(context);
367  context->isReset = true;
368  VALGRIND_DESTROY_MEMPOOL(context);
369  VALGRIND_CREATE_MEMPOOL(context, 0, false);
370  }
371 }
#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()

◆ MemoryContextSetParent()

void MemoryContextSetParent ( MemoryContext  context,
MemoryContext  new_parent 
)

Definition at line 546 of file mcxt.c.

547 {
548  Assert(MemoryContextIsValid(context));
549  Assert(context != new_parent);
550 
551  /* Fast path if it's got correct parent already */
552  if (new_parent == context->parent)
553  return;
554 
555  /* Delink from existing parent, if any */
556  if (context->parent)
557  {
558  MemoryContext parent = context->parent;
559 
560  if (context->prevchild != NULL)
561  context->prevchild->nextchild = context->nextchild;
562  else
563  {
564  Assert(parent->firstchild == context);
565  parent->firstchild = context->nextchild;
566  }
567 
568  if (context->nextchild != NULL)
569  context->nextchild->prevchild = context->prevchild;
570  }
571 
572  /* And relink */
573  if (new_parent)
574  {
575  Assert(MemoryContextIsValid(new_parent));
576  context->parent = new_parent;
577  context->prevchild = NULL;
578  context->nextchild = new_parent->firstchild;
579  if (new_parent->firstchild != NULL)
580  new_parent->firstchild->prevchild = context;
581  new_parent->firstchild = context;
582  }
583  else
584  {
585  context->parent = NULL;
586  context->prevchild = NULL;
587  context->nextchild = NULL;
588  }
589 }
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(), RE_compile_and_cache(), RelationBuildPartitionDesc(), RelationBuildPartitionKey(), RelationBuildRowSecurity(), RelationClearRelation(), RevalidateCachedQuery(), SaveCachedPlan(), SPI_keepplan(), and TransferExpandedObject().

◆ MemoryContextStats()

void MemoryContextStats ( MemoryContext  context)

Definition at line 699 of file mcxt.c.

700 {
701  /* A hard-wired limit on the number of children is usually good enough */
702  MemoryContextStatsDetail(context, 100, true);
703 }
void MemoryContextStatsDetail(MemoryContext context, int max_children, bool print_to_stderr)
Definition: mcxt.c:714

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

716 {
717  MemoryContextCounters grand_totals;
718 
719  memset(&grand_totals, 0, sizeof(grand_totals));
720 
721  MemoryContextStatsInternal(context, 0, true, max_children, &grand_totals, print_to_stderr);
722 
723  if (print_to_stderr)
724  fprintf(stderr,
725  "Grand total: %zu bytes in %zu blocks; %zu free (%zu chunks); %zu used\n",
726  grand_totals.totalspace, grand_totals.nblocks,
727  grand_totals.freespace, grand_totals.freechunks,
728  grand_totals.totalspace - grand_totals.freespace);
729  else
730 
731  /*
732  * Use LOG_SERVER_ONLY to prevent the memory contexts from being sent
733  * to the connected client.
734  *
735  * We don't buffer the information about all memory contexts in a
736  * backend into StringInfo and log it as one message. That would
737  * require the buffer to be enlarged, risking an OOM as there could be
738  * a large number of memory contexts in a backend. Instead, we log
739  * one message per memory context.
740  */
742  (errhidestmt(true),
743  errhidecontext(true),
744  errmsg_internal("Grand total: %zu bytes in %zu blocks; %zu free (%zu chunks); %zu used",
745  grand_totals.totalspace, grand_totals.nblocks,
746  grand_totals.freespace, grand_totals.freechunks,
747  grand_totals.totalspace - grand_totals.freespace)));
748 }
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:758
#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 1199 of file mcxt.c.

1200 {
1201  LogMemoryContextPending = false;
1202 
1203  /*
1204  * Use LOG_SERVER_ONLY to prevent this message from being sent to the
1205  * connected client.
1206  */
1208  (errhidestmt(true),
1209  errhidecontext(true),
1210  errmsg("logging memory contexts of PID %d", MyProcPid)));
1211 
1212  /*
1213  * When a backend process is consuming huge memory, logging all its memory
1214  * contexts might overrun available disk space. To prevent this, we limit
1215  * the number of child contexts to log per parent to 100.
1216  *
1217  * As with MemoryContextStats(), we suppose that practical cases where the
1218  * dump gets long will typically be huge numbers of siblings under the
1219  * same parent context; while the additional debugging value from seeing
1220  * details about individual siblings beyond 100 will not be large.
1221  */
1223 }
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 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
#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 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(), getmissingattr(), GetSessionDsmHandle(), HandleParallelApplyMessages(), HandleParallelMessages(), hash_create(), init_missing_cache(), init_string_reloption(), InitDeadLockChecking(), initialize_reloptions(), initialize_target_list(), InitializeClientEncoding(), InitializeLatchWaitSet(), 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(), 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(), 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(), px_find_cipher(), px_find_digest(), RE_compile_and_cache(), 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