PostgreSQL Source Code git master
Data Structures | Macros | Typedefs | Functions
bump.c File Reference
#include "postgres.h"
#include "lib/ilist.h"
#include "port/pg_bitutils.h"
#include "utils/memdebug.h"
#include "utils/memutils.h"
#include "utils/memutils_memorychunk.h"
#include "utils/memutils_internal.h"
Include dependency graph for bump.c:

Go to the source code of this file.

Data Structures

struct   BumpContext
 
struct   BumpBlock
 

Macros

#define  Bump_BLOCKHDRSZ   MAXALIGN(sizeof(BumpBlock))
 
#define  FIRST_BLOCKHDRSZ
 
#define  Bump_CHUNKHDRSZ   0
 
#define  Bump_CHUNK_FRACTION   8
 
#define  KeeperBlock(set)
 
#define  IsKeeperBlock(set, blk)   (KeeperBlock(set) == (blk))
 
#define  BumpIsValid(set)    ((set) && IsA(set, BumpContext))
 
#define  ExternalChunkGetBlock(chunk)    (BumpBlock *) ((char *) chunk - Bump_BLOCKHDRSZ)
 

Typedefs

typedef struct BumpBlock  BumpBlock
 
typedef struct BumpContext  BumpContext
 

Functions

static void  BumpBlockInit (BumpContext *context, BumpBlock *block, Size blksize)
 
static bool  BumpBlockIsEmpty (BumpBlock *block)
 
static void  BumpBlockMarkEmpty (BumpBlock *block)
 
static Size  BumpBlockFreeBytes (BumpBlock *block)
 
static void  BumpBlockFree (BumpContext *set, BumpBlock *block)
 
MemoryContext  BumpContextCreate (MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
 
void  BumpReset (MemoryContext context)
 
void  BumpDelete (MemoryContext context)
 
static pg_noinline void *  BumpAllocLarge (MemoryContext context, Size size, int flags)
 
static void *  BumpAllocChunkFromBlock (MemoryContext context, BumpBlock *block, Size size, Size chunk_size)
 
static pg_noinline void *  BumpAllocFromNewBlock (MemoryContext context, Size size, int flags, Size chunk_size)
 
void *  BumpAlloc (MemoryContext context, Size size, int flags)
 
void  BumpFree (void *pointer)
 
void *  BumpRealloc (void *pointer, Size size, int flags)
 
 
Size  BumpGetChunkSpace (void *pointer)
 
bool  BumpIsEmpty (MemoryContext context)
 
void  BumpStats (MemoryContext context, MemoryStatsPrintFunc printfunc, void *passthru, MemoryContextCounters *totals, bool print_to_stderr)
 

Macro Definition Documentation

Bump_BLOCKHDRSZ

#define Bump_BLOCKHDRSZ   MAXALIGN(sizeof(BumpBlock))

Definition at line 48 of file bump.c.

Bump_CHUNK_FRACTION

#define Bump_CHUNK_FRACTION   8

Definition at line 59 of file bump.c.

Bump_CHUNKHDRSZ

#define Bump_CHUNKHDRSZ   0

Definition at line 56 of file bump.c.

BumpIsValid

#define BumpIsValid (   set )     ((set) && IsA(set, BumpContext))

Definition at line 102 of file bump.c.

ExternalChunkGetBlock

#define ExternalChunkGetBlock (   chunk )     (BumpBlock *) ((char *) chunk - Bump_BLOCKHDRSZ)

Definition at line 110 of file bump.c.

FIRST_BLOCKHDRSZ

#define FIRST_BLOCKHDRSZ
Value:
(MAXALIGN(sizeof(BumpContext)) + \
Bump_BLOCKHDRSZ)
#define MAXALIGN(LEN)
Definition: c.h:810
Definition: bump.c:69

Definition at line 49 of file bump.c.

IsKeeperBlock

#define IsKeeperBlock (   set,
  blk 
)    (KeeperBlock(set) == (blk))

Definition at line 64 of file bump.c.

KeeperBlock

#define KeeperBlock (   set )
Value:
((BumpBlock *) ((char *) (set) + \
MAXALIGN(sizeof(BumpContext))))
Definition: bump.c:89

Definition at line 62 of file bump.c.

Typedef Documentation

BumpBlock

typedef struct BumpBlock BumpBlock

Definition at line 66 of file bump.c.

BumpContext

typedef struct BumpContext BumpContext

Function Documentation

BumpAlloc()

void * BumpAlloc ( MemoryContext  context,
Size  size,
int  flags 
)

Definition at line 517 of file bump.c.

518{
519 BumpContext *set = (BumpContext *) context;
520 BumpBlock *block;
521 Size chunk_size;
522 Size required_size;
523
524 Assert(BumpIsValid(set));
525
526#ifdef MEMORY_CONTEXT_CHECKING
527 /* ensure there's always space for the sentinel byte */
528 chunk_size = MAXALIGN(size + 1);
529#else
530 chunk_size = MAXALIGN(size);
531#endif
532
533 /*
534 * If requested size exceeds maximum for chunks we hand the request off to
535 * BumpAllocLarge().
536 */
537 if (chunk_size > set->allocChunkLimit)
538 return BumpAllocLarge(context, size, flags);
539
540 required_size = chunk_size + Bump_CHUNKHDRSZ;
541
542 /*
543 * Not an oversized chunk. We try to first make use of the latest block,
544 * but if there's not enough space in it we must allocate a new block.
545 */
546 block = dlist_container(BumpBlock, node, dlist_head_node(&set->blocks));
547
548 if (BumpBlockFreeBytes(block) < required_size)
549 return BumpAllocFromNewBlock(context, size, flags, chunk_size);
550
551 /* The current block has space, so just allocate chunk there. */
552 return BumpAllocChunkFromBlock(context, block, size, chunk_size);
553}
#define Bump_CHUNKHDRSZ
Definition: bump.c:56
static pg_noinline void * BumpAllocLarge(MemoryContext context, Size size, int flags)
Definition: bump.c:313
#define BumpIsValid(set)
Definition: bump.c:102
static pg_noinline void * BumpAllocFromNewBlock(MemoryContext context, Size size, int flags, Size chunk_size)
Definition: bump.c:453
static void * BumpAllocChunkFromBlock(MemoryContext context, BumpBlock *block, Size size, Size chunk_size)
Definition: bump.c:394
static Size BumpBlockFreeBytes(BumpBlock *block)
Definition: bump.c:611
size_t Size
Definition: c.h:610
Assert(PointerIsAligned(start, uint64))
static dlist_node * dlist_head_node(dlist_head *head)
Definition: ilist.h:565
#define dlist_container(type, membername, ptr)
Definition: ilist.h:593
dlist_head blocks
Definition: bump.c:78
uint32 allocChunkLimit
Definition: bump.c:76

References BumpContext::allocChunkLimit, Assert(), BumpContext::blocks, Bump_CHUNKHDRSZ, BumpAllocChunkFromBlock(), BumpAllocFromNewBlock(), BumpAllocLarge(), BumpBlockFreeBytes(), BumpIsValid, dlist_container, dlist_head_node(), and MAXALIGN.

BumpAllocChunkFromBlock()

static void * BumpAllocChunkFromBlock ( MemoryContext  context,
BumpBlockblock,
Size  size,
Size  chunk_size 
)
inlinestatic

Definition at line 394 of file bump.c.

396{
397#ifdef MEMORY_CONTEXT_CHECKING
398 MemoryChunk *chunk;
399#else
400 void *ptr;
401#endif
402
403 /* validate we've been given a block with enough free space */
404 Assert(block != NULL);
405 Assert((block->endptr - block->freeptr) >= Bump_CHUNKHDRSZ + chunk_size);
406
407#ifdef MEMORY_CONTEXT_CHECKING
408 chunk = (MemoryChunk *) block->freeptr;
409#else
410 ptr = (void *) block->freeptr;
411#endif
412
413 /* point the freeptr beyond this chunk */
414 block->freeptr += (Bump_CHUNKHDRSZ + chunk_size);
415 Assert(block->freeptr <= block->endptr);
416
417#ifdef MEMORY_CONTEXT_CHECKING
418 /* Prepare to initialize the chunk header. */
420
421 MemoryChunkSetHdrMask(chunk, block, chunk_size, MCTX_BUMP_ID);
422 chunk->requested_size = size;
423 /* set mark to catch clobber of "unused" space */
424 Assert(size < chunk_size);
425 set_sentinel(MemoryChunkGetPointer(chunk), size);
426
427#ifdef RANDOMIZE_ALLOCATED_MEMORY
428 /* fill the allocated space with junk */
429 randomize_mem((char *) MemoryChunkGetPointer(chunk), size);
430#endif
431
432 /* Ensure any padding bytes are marked NOACCESS. */
434 chunk_size - size);
435
436 /* Disallow access to the chunk header. */
438
439 return MemoryChunkGetPointer(chunk);
440#else
441 return ptr;
442#endif /* MEMORY_CONTEXT_CHECKING */
443}
#define VALGRIND_MAKE_MEM_NOACCESS(addr, size)
Definition: memdebug.h:27
#define VALGRIND_MAKE_MEM_UNDEFINED(addr, size)
Definition: memdebug.h:28
@ MCTX_BUMP_ID
#define MemoryChunkGetPointer(c)
static void MemoryChunkSetHdrMask(MemoryChunk *chunk, void *block, Size value, MemoryContextMethodID methodid)
char * endptr
Definition: bump.c:95
char * freeptr
Definition: bump.c:94

References Assert(), Bump_CHUNKHDRSZ, BumpBlock::endptr, BumpBlock::freeptr, MCTX_BUMP_ID, MemoryChunkGetPointer, MemoryChunkSetHdrMask(), VALGRIND_MAKE_MEM_NOACCESS, and VALGRIND_MAKE_MEM_UNDEFINED.

Referenced by BumpAlloc(), and BumpAllocFromNewBlock().

BumpAllocFromNewBlock()

static pg_noinline void * BumpAllocFromNewBlock ( MemoryContext  context,
Size  size,
int  flags,
Size  chunk_size 
)
static

Definition at line 453 of file bump.c.

455{
456 BumpContext *set = (BumpContext *) context;
457 BumpBlock *block;
458 Size blksize;
459 Size required_size;
460
461 /*
462 * The first such block has size initBlockSize, and we double the space in
463 * each succeeding block, but not more than maxBlockSize.
464 */
465 blksize = set->nextBlockSize;
466 set->nextBlockSize <<= 1;
467 if (set->nextBlockSize > set->maxBlockSize)
468 set->nextBlockSize = set->maxBlockSize;
469
470 /* we'll need space for the chunk, chunk hdr and block hdr */
471 required_size = chunk_size + Bump_CHUNKHDRSZ + Bump_BLOCKHDRSZ;
472 /* round the size up to the next power of 2 */
473 if (blksize < required_size)
474 blksize = pg_nextpower2_size_t(required_size);
475
476 block = (BumpBlock *) malloc(blksize);
477
478 if (block == NULL)
479 return MemoryContextAllocationFailure(context, size, flags);
480
481 /* Make a vchunk covering the new block's header */
483
484 context->mem_allocated += blksize;
485
486 /* initialize the new block */
487 BumpBlockInit(set, block, blksize);
488
489 /* add it to the doubly-linked list of blocks */
490 dlist_push_head(&set->blocks, &block->node);
491
492 return BumpAllocChunkFromBlock(context, block, size, chunk_size);
493}
static void BumpBlockInit(BumpContext *context, BumpBlock *block, Size blksize)
Definition: bump.c:561
#define Bump_BLOCKHDRSZ
Definition: bump.c:48
#define malloc(a)
Definition: header.h:50
static void dlist_push_head(dlist_head *head, dlist_node *node)
Definition: ilist.h:347
void * MemoryContextAllocationFailure(MemoryContext context, Size size, int flags)
Definition: mcxt.c:1195
#define VALGRIND_MEMPOOL_ALLOC(context, addr, size)
Definition: memdebug.h:29
#define pg_nextpower2_size_t
Definition: pg_bitutils.h:441
dlist_node node
Definition: bump.c:90
uint32 maxBlockSize
Definition: bump.c:74
uint32 nextBlockSize
Definition: bump.c:75
Size mem_allocated
Definition: memnodes.h:125

References BumpContext::blocks, Bump_BLOCKHDRSZ, Bump_CHUNKHDRSZ, BumpAllocChunkFromBlock(), BumpBlockInit(), dlist_push_head(), malloc, BumpContext::maxBlockSize, MemoryContextData::mem_allocated, MemoryContextAllocationFailure(), BumpContext::nextBlockSize, BumpBlock::node, pg_nextpower2_size_t, and VALGRIND_MEMPOOL_ALLOC.

Referenced by BumpAlloc().

BumpAllocLarge()

static pg_noinline void * BumpAllocLarge ( MemoryContext  context,
Size  size,
int  flags 
)
static

Definition at line 313 of file bump.c.

314{
315 BumpContext *set = (BumpContext *) context;
316 BumpBlock *block;
317#ifdef MEMORY_CONTEXT_CHECKING
318 MemoryChunk *chunk;
319#endif
320 Size chunk_size;
321 Size required_size;
322 Size blksize;
323
324 /* validate 'size' is within the limits for the given 'flags' */
325 MemoryContextCheckSize(context, size, flags);
326
327#ifdef MEMORY_CONTEXT_CHECKING
328 /* ensure there's always space for the sentinel byte */
329 chunk_size = MAXALIGN(size + 1);
330#else
331 chunk_size = MAXALIGN(size);
332#endif
333
334 required_size = chunk_size + Bump_CHUNKHDRSZ;
335 blksize = required_size + Bump_BLOCKHDRSZ;
336
337 block = (BumpBlock *) malloc(blksize);
338 if (block == NULL)
339 return MemoryContextAllocationFailure(context, size, flags);
340
341 /* Make a vchunk covering the new block's header */
343
344 context->mem_allocated += blksize;
345
346 /* the block is completely full */
347 block->freeptr = block->endptr = ((char *) block) + blksize;
348
349#ifdef MEMORY_CONTEXT_CHECKING
350 /* block with a single (used) chunk */
351 block->context = set;
352
353 chunk = (MemoryChunk *) (((char *) block) + Bump_BLOCKHDRSZ);
354
355 /* mark the MemoryChunk as externally managed */
357
358 chunk->requested_size = size;
359 /* set mark to catch clobber of "unused" space */
360 Assert(size < chunk_size);
361 set_sentinel(MemoryChunkGetPointer(chunk), size);
362#endif
363#ifdef RANDOMIZE_ALLOCATED_MEMORY
364 /* fill the allocated space with junk */
365 randomize_mem((char *) MemoryChunkGetPointer(chunk), size);
366#endif
367
368 /*
369 * Add the block to the tail of allocated blocks list. The current block
370 * is left at the head of the list as it may still have space for
371 * non-large allocations.
372 */
373 dlist_push_tail(&set->blocks, &block->node);
374
375#ifdef MEMORY_CONTEXT_CHECKING
376 /* Ensure any padding bytes are marked NOACCESS. */
378 chunk_size - size);
379
380 /* Disallow access to the chunk header. */
382
383 return MemoryChunkGetPointer(chunk);
384#else
385 return (void *) (((char *) block) + Bump_BLOCKHDRSZ);
386#endif
387}
static void dlist_push_tail(dlist_head *head, dlist_node *node)
Definition: ilist.h:364
static void MemoryContextCheckSize(MemoryContext context, Size size, int flags)
static void MemoryChunkSetHdrMaskExternal(MemoryChunk *chunk, MemoryContextMethodID methodid)

References Assert(), BumpContext::blocks, Bump_BLOCKHDRSZ, Bump_CHUNKHDRSZ, dlist_push_tail(), BumpBlock::endptr, BumpBlock::freeptr, malloc, MAXALIGN, MCTX_BUMP_ID, MemoryContextData::mem_allocated, MemoryChunkGetPointer, MemoryChunkSetHdrMaskExternal(), MemoryContextAllocationFailure(), MemoryContextCheckSize(), BumpBlock::node, VALGRIND_MAKE_MEM_NOACCESS, and VALGRIND_MEMPOOL_ALLOC.

Referenced by BumpAlloc().

BumpBlockFree()

static void BumpBlockFree ( BumpContextset,
BumpBlockblock 
)
inlinestatic

Definition at line 621 of file bump.c.

622{
623 /* Make sure nobody tries to free the keeper block */
624 Assert(!IsKeeperBlock(set, block));
625
626 /* release the block from the list of blocks */
627 dlist_delete(&block->node);
628
629 ((MemoryContext) set)->mem_allocated -= ((char *) block->endptr - (char *) block);
630
631#ifdef CLOBBER_FREED_MEMORY
632 wipe_mem(block, ((char *) block->endptr - (char *) block));
633#endif
634
635 /* As in aset.c, free block-header vchunks explicitly */
636 VALGRIND_MEMPOOL_FREE(set, block);
637
638 free(block);
639}
#define IsKeeperBlock(set, blk)
Definition: bump.c:64
#define free(a)
Definition: header.h:65
static void dlist_delete(dlist_node *node)
Definition: ilist.h:405
#define VALGRIND_MEMPOOL_FREE(context, addr)
Definition: memdebug.h:30
struct MemoryContextData * MemoryContext
Definition: palloc.h:36

References Assert(), dlist_delete(), BumpBlock::endptr, free, IsKeeperBlock, BumpBlock::node, and VALGRIND_MEMPOOL_FREE.

Referenced by BumpReset().

BumpBlockFreeBytes()

static Size BumpBlockFreeBytes ( BumpBlockblock )
inlinestatic

Definition at line 611 of file bump.c.

612{
613 return (block->endptr - block->freeptr);
614}

References BumpBlock::endptr, and BumpBlock::freeptr.

Referenced by BumpAlloc().

BumpBlockInit()

static void BumpBlockInit ( BumpContextcontext,
BumpBlockblock,
Size  blksize 
)
inlinestatic

Definition at line 561 of file bump.c.

562{
563#ifdef MEMORY_CONTEXT_CHECKING
564 block->context = context;
565#endif
566 block->freeptr = ((char *) block) + Bump_BLOCKHDRSZ;
567 block->endptr = ((char *) block) + blksize;
568
569 /* Mark unallocated space NOACCESS. */
571}

References Bump_BLOCKHDRSZ, BumpBlock::endptr, BumpBlock::freeptr, and VALGRIND_MAKE_MEM_NOACCESS.

Referenced by BumpAllocFromNewBlock(), and BumpContextCreate().

BumpBlockIsEmpty()

static bool BumpBlockIsEmpty ( BumpBlockblock )
inlinestatic

Definition at line 578 of file bump.c.

579{
580 /* it's empty if the freeptr has not moved */
581 return (block->freeptr == ((char *) block + Bump_BLOCKHDRSZ));
582}

References Bump_BLOCKHDRSZ, and BumpBlock::freeptr.

Referenced by BumpIsEmpty().

BumpBlockMarkEmpty()

static void BumpBlockMarkEmpty ( BumpBlockblock )
inlinestatic

Definition at line 589 of file bump.c.

590{
591#if defined(USE_VALGRIND) || defined(CLOBBER_FREED_MEMORY)
592 char *datastart = ((char *) block) + Bump_BLOCKHDRSZ;
593#endif
594
595#ifdef CLOBBER_FREED_MEMORY
596 wipe_mem(datastart, block->freeptr - datastart);
597#else
598 /* wipe_mem() would have done this */
599 VALGRIND_MAKE_MEM_NOACCESS(datastart, block->freeptr - datastart);
600#endif
601
602 /* Reset the block, but don't return it to malloc */
603 block->freeptr = ((char *) block) + Bump_BLOCKHDRSZ;
604}

References Bump_BLOCKHDRSZ, BumpBlock::freeptr, and VALGRIND_MAKE_MEM_NOACCESS.

Referenced by BumpReset().

BumpContextCreate()

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

Definition at line 133 of file bump.c.

135{
136 Size firstBlockSize;
137 Size allocSize;
138 BumpContext *set;
139 BumpBlock *block;
140
141 /* ensure MemoryChunk's size is properly maxaligned */
143 "sizeof(MemoryChunk) is not maxaligned");
144
145 /*
146 * First, validate allocation parameters. Asserts seem sufficient because
147 * nobody varies their parameters at runtime. We somewhat arbitrarily
148 * enforce a minimum 1K block size. We restrict the maximum block size to
149 * MEMORYCHUNK_MAX_BLOCKOFFSET as MemoryChunks are limited to this in
150 * regards to addressing the offset between the chunk and the block that
151 * the chunk is stored on. We would be unable to store the offset between
152 * the chunk and block for any chunks that were beyond
153 * MEMORYCHUNK_MAX_BLOCKOFFSET bytes into the block if the block was to be
154 * larger than this.
155 */
156 Assert(initBlockSize == MAXALIGN(initBlockSize) &&
157 initBlockSize >= 1024);
158 Assert(maxBlockSize == MAXALIGN(maxBlockSize) &&
159 maxBlockSize >= initBlockSize &&
160 AllocHugeSizeIsValid(maxBlockSize)); /* must be safe to double */
161 Assert(minContextSize == 0 ||
162 (minContextSize == MAXALIGN(minContextSize) &&
163 minContextSize >= 1024 &&
164 minContextSize <= maxBlockSize));
165 Assert(maxBlockSize <= MEMORYCHUNK_MAX_BLOCKOFFSET);
166
167 /* Determine size of initial block */
168 allocSize = MAXALIGN(sizeof(BumpContext)) + Bump_BLOCKHDRSZ +
170 if (minContextSize != 0)
171 allocSize = Max(allocSize, minContextSize);
172 else
173 allocSize = Max(allocSize, initBlockSize);
174
175 /*
176 * Allocate the initial block. Unlike other bump.c blocks, it starts with
177 * the context header and its block header follows that.
178 */
179 set = (BumpContext *) malloc(allocSize);
180 if (set == NULL)
181 {
184 (errcode(ERRCODE_OUT_OF_MEMORY),
185 errmsg("out of memory"),
186 errdetail("Failed while creating memory context \"%s\".",
187 name)));
188 }
189
190 /*
191 * Avoid writing code that can fail between here and MemoryContextCreate;
192 * we'd leak the header and initial block if we ereport in this stretch.
193 */
194
195 /* See comments about Valgrind interactions in aset.c */
196 VALGRIND_CREATE_MEMPOOL(set, 0, false);
197 /* This vchunk covers the BumpContext and the keeper block header */
199
200 dlist_init(&set->blocks);
201
202 /* Fill in the initial block's block header */
203 block = KeeperBlock(set);
204 /* determine the block size and initialize it */
205 firstBlockSize = allocSize - MAXALIGN(sizeof(BumpContext));
206 BumpBlockInit(set, block, firstBlockSize);
207
208 /* add it to the doubly-linked list of blocks */
209 dlist_push_head(&set->blocks, &block->node);
210
211 /*
212 * Fill in BumpContext-specific header fields. The Asserts above should
213 * ensure that these all fit inside a uint32.
214 */
215 set->initBlockSize = (uint32) initBlockSize;
216 set->maxBlockSize = (uint32) maxBlockSize;
217 set->nextBlockSize = (uint32) initBlockSize;
218
219 /*
220 * Compute the allocation chunk size limit for this context.
221 *
222 * Limit the maximum size a non-dedicated chunk can be so that we can fit
223 * at least Bump_CHUNK_FRACTION of chunks this big onto the maximum sized
224 * block. We must further limit this value so that it's no more than
225 * MEMORYCHUNK_MAX_VALUE. We're unable to have non-external chunks larger
226 * than that value as we store the chunk size in the MemoryChunk 'value'
227 * field in the call to MemoryChunkSetHdrMask().
228 */
229 set->allocChunkLimit = Min(maxBlockSize, MEMORYCHUNK_MAX_VALUE);
230 while ((Size) (set->allocChunkLimit + Bump_CHUNKHDRSZ) >
231 (Size) ((Size) (maxBlockSize - Bump_BLOCKHDRSZ) / Bump_CHUNK_FRACTION))
232 set->allocChunkLimit >>= 1;
233
234 /* Finally, do the type-independent part of context creation */
235 MemoryContextCreate((MemoryContext) set, T_BumpContext, MCTX_BUMP_ID,
236 parent, name);
237
238 ((MemoryContext) set)->mem_allocated = allocSize;
239
240 return (MemoryContext) set;
241}
#define Bump_CHUNK_FRACTION
Definition: bump.c:59
#define KeeperBlock(set)
Definition: bump.c:62
#define FIRST_BLOCKHDRSZ
Definition: bump.c:49
#define Min(x, y)
Definition: c.h:1003
#define Max(x, y)
Definition: c.h:997
uint32_t uint32
Definition: c.h:538
#define StaticAssertDecl(condition, errmessage)
Definition: c.h:935
int errdetail(const char *fmt,...)
Definition: elog.c:1207
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:150
static void dlist_init(dlist_head *head)
Definition: ilist.h:314
void MemoryContextCreate(MemoryContext node, NodeTag tag, MemoryContextMethodID method_id, MemoryContext parent, const char *name)
Definition: mcxt.c:1146
MemoryContext TopMemoryContext
Definition: mcxt.c:166
void MemoryContextStats(MemoryContext context)
Definition: mcxt.c:860
#define VALGRIND_CREATE_MEMPOOL(context, redzones, zeroed)
Definition: memdebug.h:24
#define AllocHugeSizeIsValid(size)
Definition: memutils.h:49
#define MEMORYCHUNK_MAX_BLOCKOFFSET
#define MEMORYCHUNK_MAX_VALUE
uint32 initBlockSize
Definition: bump.c:73
const char * name

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

Referenced by hash_create_memory(), TidStoreCreateLocal(), and tuplesort_begin_batch().

BumpDelete()

void BumpDelete ( MemoryContext  context )

Definition at line 294 of file bump.c.

295{
296 /* Reset to release all releasable BumpBlocks */
297 BumpReset(context);
298
299 /* Destroy the vpool -- see notes in aset.c */
301
302 /* And free the context header and keeper block */
303 free(context);
304}
void BumpReset(MemoryContext context)
Definition: bump.c:251
#define VALGRIND_DESTROY_MEMPOOL(context)
Definition: memdebug.h:25

References BumpReset(), free, and VALGRIND_DESTROY_MEMPOOL.

BumpFree()

void BumpFree ( void *  pointer )

Definition at line 646 of file bump.c.

647{
648 elog(ERROR, "%s is not supported by the bump memory allocator", "pfree");
649}
#define elog(elevel,...)
Definition: elog.h:226

References elog, and ERROR.

BumpGetChunkContext()

MemoryContext BumpGetChunkContext ( void *  pointer )

Definition at line 667 of file bump.c.

668{
669 elog(ERROR, "%s is not supported by the bump memory allocator", "GetMemoryChunkContext");
670 return NULL; /* keep compiler quiet */
671}

References elog, and ERROR.

BumpGetChunkSpace()

Size BumpGetChunkSpace ( void *  pointer )

Definition at line 678 of file bump.c.

679{
680 elog(ERROR, "%s is not supported by the bump memory allocator", "GetMemoryChunkSpace");
681 return 0; /* keep compiler quiet */
682}

References elog, and ERROR.

BumpIsEmpty()

bool BumpIsEmpty ( MemoryContext  context )

Definition at line 689 of file bump.c.

690{
691 BumpContext *set = (BumpContext *) context;
692 dlist_iter iter;
693
694 Assert(BumpIsValid(set));
695
696 dlist_foreach(iter, &set->blocks)
697 {
698 BumpBlock *block = dlist_container(BumpBlock, node, iter.cur);
699
700 if (!BumpBlockIsEmpty(block))
701 return false;
702 }
703
704 return true;
705}
static bool BumpBlockIsEmpty(BumpBlock *block)
Definition: bump.c:578
#define dlist_foreach(iter, lhead)
Definition: ilist.h:623
Definition: ilist.h:178
dlist_node * cur
Definition: ilist.h:179

References Assert(), BumpContext::blocks, BumpBlockIsEmpty(), BumpIsValid, dlist_iter::cur, dlist_container, and dlist_foreach.

BumpRealloc()

void * BumpRealloc ( void *  pointer,
Size  size,
int  flags 
)

Definition at line 656 of file bump.c.

657{
658 elog(ERROR, "%s is not supported by the bump memory allocator", "realloc");
659 return NULL; /* keep compiler quiet */
660}

References elog, and ERROR.

BumpReset()

void BumpReset ( MemoryContext  context )

Definition at line 251 of file bump.c.

252{
253 BumpContext *set = (BumpContext *) context;
254 dlist_mutable_iter miter;
255
256 Assert(BumpIsValid(set));
257
258#ifdef MEMORY_CONTEXT_CHECKING
259 /* Check for corruption and leaks before freeing */
260 BumpCheck(context);
261#endif
262
263 dlist_foreach_modify(miter, &set->blocks)
264 {
265 BumpBlock *block = dlist_container(BumpBlock, node, miter.cur);
266
267 if (IsKeeperBlock(set, block))
268 BumpBlockMarkEmpty(block);
269 else
270 BumpBlockFree(set, block);
271 }
272
273 /*
274 * Instruct Valgrind to throw away all the vchunks associated with this
275 * context, except for the one covering the BumpContext and keeper-block
276 * header. This gets rid of the vchunks for whatever user data is getting
277 * discarded by the context reset.
278 */
280
281 /* Reset block size allocation sequence, too */
282 set->nextBlockSize = set->initBlockSize;
283
284 /* Ensure there is only 1 item in the dlist */
287}
static void BumpBlockFree(BumpContext *set, BumpBlock *block)
Definition: bump.c:621
static void BumpBlockMarkEmpty(BumpBlock *block)
Definition: bump.c:589
static bool dlist_has_next(const dlist_head *head, const dlist_node *node)
Definition: ilist.h:503
#define dlist_foreach_modify(iter, lhead)
Definition: ilist.h:640
static bool dlist_is_empty(const dlist_head *head)
Definition: ilist.h:336
#define VALGRIND_MEMPOOL_TRIM(context, addr, size)
Definition: memdebug.h:32
dlist_node * cur
Definition: ilist.h:200

References Assert(), BumpContext::blocks, BumpBlockFree(), BumpBlockMarkEmpty(), BumpIsValid, dlist_mutable_iter::cur, dlist_container, dlist_foreach_modify, dlist_has_next(), dlist_head_node(), dlist_is_empty(), FIRST_BLOCKHDRSZ, BumpContext::initBlockSize, IsKeeperBlock, BumpContext::nextBlockSize, and VALGRIND_MEMPOOL_TRIM.

Referenced by BumpDelete().

BumpStats()

void BumpStats ( MemoryContext  context,
MemoryStatsPrintFunc  printfunc,
void *  passthru,
MemoryContextCounterstotals,
bool  print_to_stderr 
)

Definition at line 717 of file bump.c.

719{
720 BumpContext *set = (BumpContext *) context;
721 Size nblocks = 0;
722 Size totalspace = 0;
723 Size freespace = 0;
724 dlist_iter iter;
725
726 Assert(BumpIsValid(set));
727
728 dlist_foreach(iter, &set->blocks)
729 {
730 BumpBlock *block = dlist_container(BumpBlock, node, iter.cur);
731
732 nblocks++;
733 totalspace += (block->endptr - (char *) block);
734 freespace += (block->endptr - block->freeptr);
735 }
736
737 if (printfunc)
738 {
739 char stats_string[200];
740
741 snprintf(stats_string, sizeof(stats_string),
742 "%zu total in %zu blocks; %zu free; %zu used",
743 totalspace, nblocks, freespace, totalspace - freespace);
744 printfunc(context, passthru, stats_string, print_to_stderr);
745 }
746
747 if (totals)
748 {
749 totals->nblocks += nblocks;
750 totals->totalspace += totalspace;
751 totals->freespace += freespace;
752 }
753}
#define snprintf
Definition: port.h:239

References Assert(), BumpContext::blocks, BumpIsValid, dlist_iter::cur, dlist_container, dlist_foreach, BumpBlock::endptr, BumpBlock::freeptr, MemoryContextCounters::freespace, MemoryContextCounters::nblocks, snprintf, and MemoryContextCounters::totalspace.

AltStyle によって変換されたページ (->オリジナル) /