aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/mmgr/aset.c44
-rw-r--r--src/backend/utils/mmgr/generation.c42
-rw-r--r--src/backend/utils/mmgr/slab.c22
3 files changed, 60 insertions, 48 deletions
diff --git a/src/backend/utils/mmgr/aset.c b/src/backend/utils/mmgr/aset.c
index 0bbbf93672e..c3affaf5a8a 100644
--- a/src/backend/utils/mmgr/aset.c
+++ b/src/backend/utils/mmgr/aset.c
@@ -156,11 +156,10 @@ typedef struct AllocSetContext
AllocBlock blocks; /* head of list of blocks in this set */
MemoryChunk *freelist[ALLOCSET_NUM_FREELISTS]; /* free chunk lists */
/* Allocation parameters for this context: */
- Size initBlockSize; /* initial block size */
- Size maxBlockSize; /* maximum block size */
- Size nextBlockSize; /* next block size to allocate */
- Size allocChunkLimit; /* effective chunk size limit */
- AllocBlock keeper; /* keep this block over resets */
+ uint32 initBlockSize; /* initial block size */
+ uint32 maxBlockSize; /* maximum block size */
+ uint32 nextBlockSize; /* next block size to allocate */
+ uint32 allocChunkLimit; /* effective chunk size limit */
/* freelist this context could be put in, or -1 if not a candidate: */
int freeListIndex; /* index in context_freelists[], or -1 */
} AllocSetContext;
@@ -241,6 +240,13 @@ typedef struct AllocBlockData
*/
#define MAX_FREE_CONTEXTS 100 /* arbitrary limit on freelist length */
+/* Obtain the keeper block for an allocation set */
+#define KeeperBlock(set) \
+ ((AllocBlock) (((char *) set) + MAXALIGN(sizeof(AllocSetContext))))
+
+/* Check if the block is the keeper block of the given allocation set */
+#define IsKeeperBlock(set, block) ((block) == (KeeperBlock(set)))
+
typedef struct AllocSetFreeList
{
int num_free; /* current list length */
@@ -417,7 +423,7 @@ AllocSetContextCreateInternal(MemoryContext parent,
name);
((MemoryContext) set)->mem_allocated =
- set->keeper->endptr - ((char *) set);
+ KeeperBlock(set)->endptr - ((char *) set);
return (MemoryContext) set;
}
@@ -453,7 +459,7 @@ AllocSetContextCreateInternal(MemoryContext parent,
*/
/* Fill in the initial block's block header */
- block = (AllocBlock) (((char *) set) + MAXALIGN(sizeof(AllocSetContext)));
+ block = KeeperBlock(set);
block->aset = set;
block->freeptr = ((char *) block) + ALLOC_BLOCKHDRSZ;
block->endptr = ((char *) set) + firstBlockSize;
@@ -465,15 +471,13 @@ AllocSetContextCreateInternal(MemoryContext parent,
/* Remember block as part of block list */
set->blocks = block;
- /* Mark block as not to be released at reset time */
- set->keeper = block;
/* Finish filling in aset-specific parts of the context header */
MemSetAligned(set->freelist, 0, sizeof(set->freelist));
- set->initBlockSize = initBlockSize;
- set->maxBlockSize = maxBlockSize;
- set->nextBlockSize = initBlockSize;
+ set->initBlockSize = (uint32) initBlockSize;
+ set->maxBlockSize = (uint32) maxBlockSize;
+ set->nextBlockSize = (uint32) initBlockSize;
set->freeListIndex = freeListIndex;
/*
@@ -544,7 +548,7 @@ AllocSetReset(MemoryContext context)
#endif
/* Remember keeper block size for Assert below */
- keepersize = set->keeper->endptr - ((char *) set);
+ keepersize = KeeperBlock(set)->endptr - ((char *) set);
/* Clear chunk freelists */
MemSetAligned(set->freelist, 0, sizeof(set->freelist));
@@ -552,13 +556,13 @@ AllocSetReset(MemoryContext context)
block = set->blocks;
/* New blocks list will be just the keeper block */
- set->blocks = set->keeper;
+ set->blocks = KeeperBlock(set);
while (block != NULL)
{
AllocBlock next = block->next;
- if (block == set->keeper)
+ if (IsKeeperBlock(set, block))
{
/* Reset the block, but don't return it to malloc */
char *datastart = ((char *) block) + ALLOC_BLOCKHDRSZ;
@@ -614,7 +618,7 @@ AllocSetDelete(MemoryContext context)
#endif
/* Remember keeper block size for Assert below */
- keepersize = set->keeper->endptr - ((char *) set);
+ keepersize = KeeperBlock(set)->endptr - ((char *) set);
/*
* If the context is a candidate for a freelist, put it into that freelist
@@ -663,14 +667,14 @@ AllocSetDelete(MemoryContext context)
{
AllocBlock next = block->next;
- if (block != set->keeper)
+ if (!IsKeeperBlock(set, block))
context->mem_allocated -= block->endptr - ((char *) block);
#ifdef CLOBBER_FREED_MEMORY
wipe_mem(block, block->freeptr - ((char *) block));
#endif
- if (block != set->keeper)
+ if (!IsKeeperBlock(set, block))
free(block);
block = next;
@@ -1547,7 +1551,7 @@ AllocSetCheck(MemoryContext context)
long nchunks = 0;
bool has_external_chunk = false;
- if (set->keeper == block)
+ if (IsKeeperBlock(set, block))
total_allocated += block->endptr - ((char *) set);
else
total_allocated += block->endptr - ((char *) block);
@@ -1557,7 +1561,7 @@ AllocSetCheck(MemoryContext context)
*/
if (!blk_used)
{
- if (set->keeper != block)
+ if (!IsKeeperBlock(set, block))
elog(WARNING, "problem in alloc set %s: empty block %p",
name, block);
}
diff --git a/src/backend/utils/mmgr/generation.c b/src/backend/utils/mmgr/generation.c
index 4fb8663cd6b..92401ccf738 100644
--- a/src/backend/utils/mmgr/generation.c
+++ b/src/backend/utils/mmgr/generation.c
@@ -61,17 +61,16 @@ typedef struct GenerationContext
MemoryContextData header; /* Standard memory-context fields */
/* Generational context parameters */
- Size initBlockSize; /* initial block size */
- Size maxBlockSize; /* maximum block size */
- Size nextBlockSize; /* next block size to allocate */
- Size allocChunkLimit; /* effective chunk size limit */
+ uint32 initBlockSize; /* initial block size */
+ uint32 maxBlockSize; /* maximum block size */
+ uint32 nextBlockSize; /* next block size to allocate */
+ uint32 allocChunkLimit; /* effective chunk size limit */
GenerationBlock *block; /* current (most recently allocated) block, or
* NULL if we've just freed the most recent
* block */
GenerationBlock *freeblock; /* pointer to a block that's being recycled,
* or NULL if there's no such block. */
- GenerationBlock *keeper; /* keep this block over resets */
dlist_head blocks; /* list of blocks */
} GenerationContext;
@@ -120,6 +119,14 @@ struct GenerationBlock
#define ExternalChunkGetBlock(chunk) \
(GenerationBlock *) ((char *) chunk - Generation_BLOCKHDRSZ)
+/* Obtain the keeper block for a generation context */
+#define KeeperBlock(set) \
+ ((GenerationBlock *) (((char *) set) + \
+ MAXALIGN(sizeof(GenerationContext))))
+
+/* Check if the block is the keeper block of the given generation context */
+#define IsKeeperBlock(set, block) ((block) == (KeeperBlock(set)))
+
/* Inlined helper functions */
static inline void GenerationBlockInit(GenerationContext *context,
GenerationBlock *block,
@@ -214,7 +221,7 @@ GenerationContextCreate(MemoryContext parent,
dlist_init(&set->blocks);
/* Fill in the initial block's block header */
- block = (GenerationBlock *) (((char *) set) + MAXALIGN(sizeof(GenerationContext)));
+ block = KeeperBlock(set);
/* determine the block size and initialize it */
firstBlockSize = allocSize - MAXALIGN(sizeof(GenerationContext));
GenerationBlockInit(set, block, firstBlockSize);
@@ -228,13 +235,10 @@ GenerationContextCreate(MemoryContext parent,
/* No free block, yet */
set->freeblock = NULL;
- /* Mark block as not to be released at reset time */
- set->keeper = block;
-
/* Fill in GenerationContext-specific header fields */
- set->initBlockSize = initBlockSize;
- set->maxBlockSize = maxBlockSize;
- set->nextBlockSize = initBlockSize;
+ set->initBlockSize = (uint32) initBlockSize;
+ set->maxBlockSize = (uint32) maxBlockSize;
+ set->nextBlockSize = (uint32) initBlockSize;
/*
* Compute the allocation chunk size limit for this context.
@@ -294,14 +298,14 @@ GenerationReset(MemoryContext context)
{
GenerationBlock *block = dlist_container(GenerationBlock, node, miter.cur);
- if (block == set->keeper)
+ if (IsKeeperBlock(set, block))
GenerationBlockMarkEmpty(block);
else
GenerationBlockFree(set, block);
}
/* set it so new allocations to make use of the keeper block */
- set->block = set->keeper;
+ set->block = KeeperBlock(set);
/* Reset block size allocation sequence, too */
set->nextBlockSize = set->initBlockSize;
@@ -440,10 +444,10 @@ GenerationAlloc(MemoryContext context, Size size)
*/
set->freeblock = NULL;
}
- else if (GenerationBlockIsEmpty(set->keeper) &&
- GenerationBlockFreeBytes(set->keeper) >= required_size)
+ else if (GenerationBlockIsEmpty(KeeperBlock(set)) &&
+ GenerationBlockFreeBytes(KeeperBlock(set)) >= required_size)
{
- block = set->keeper;
+ block = KeeperBlock(set);
}
else
{
@@ -594,7 +598,7 @@ static inline void
GenerationBlockFree(GenerationContext *set, GenerationBlock *block)
{
/* Make sure nobody tries to free the keeper block */
- Assert(block != set->keeper);
+ Assert(!IsKeeperBlock(set, block));
/* We shouldn't be freeing the freeblock either */
Assert(block != set->freeblock);
@@ -691,7 +695,7 @@ GenerationFree(void *pointer)
set = block->context;
/* Don't try to free the keeper block, just mark it empty */
- if (block == set->keeper)
+ if (IsKeeperBlock(set, block))
{
GenerationBlockMarkEmpty(block);
return;
diff --git a/src/backend/utils/mmgr/slab.c b/src/backend/utils/mmgr/slab.c
index 718dd2ba03c..40c1d401c4c 100644
--- a/src/backend/utils/mmgr/slab.c
+++ b/src/backend/utils/mmgr/slab.c
@@ -104,9 +104,9 @@ typedef struct SlabContext
{
MemoryContextData header; /* Standard memory-context fields */
/* Allocation parameters for this context: */
- Size chunkSize; /* the requested (non-aligned) chunk size */
- Size fullChunkSize; /* chunk size with chunk header and alignment */
- Size blockSize; /* the size to make each block of chunks */
+ uint32 chunkSize; /* the requested (non-aligned) chunk size */
+ uint32 fullChunkSize; /* chunk size with chunk header and alignment */
+ uint32 blockSize; /* the size to make each block of chunks */
int32 chunksPerBlock; /* number of chunks that fit in 1 block */
int32 curBlocklistIndex; /* index into the blocklist[] element
* containing the fullest, blocks */
@@ -314,7 +314,9 @@ SlabGetNextFreeChunk(SlabContext *slab, SlabBlock *block)
* blockSize: allocation block size
* chunkSize: allocation chunk size
*
- * The MAXALIGN(chunkSize) may not exceed MEMORYCHUNK_MAX_VALUE
+ * The Slab_CHUNKHDRSZ + MAXALIGN(chunkSize + 1) may not exceed
+ * MEMORYCHUNK_MAX_VALUE.
+ * 'blockSize' may not exceed MEMORYCHUNK_MAX_BLOCKOFFSET.
*/
MemoryContext
SlabContextCreate(MemoryContext parent,
@@ -330,7 +332,7 @@ SlabContextCreate(MemoryContext parent,
/* ensure MemoryChunk's size is properly maxaligned */
StaticAssertDecl(Slab_CHUNKHDRSZ == MAXALIGN(Slab_CHUNKHDRSZ),
"sizeof(MemoryChunk) is not maxaligned");
- Assert(MAXALIGN(chunkSize) <= MEMORYCHUNK_MAX_VALUE);
+ Assert(blockSize <= MEMORYCHUNK_MAX_BLOCKOFFSET);
/*
* Ensure there's enough space to store the pointer to the next free chunk
@@ -347,6 +349,8 @@ SlabContextCreate(MemoryContext parent,
fullChunkSize = Slab_CHUNKHDRSZ + MAXALIGN(chunkSize);
#endif
+ Assert(fullChunkSize <= MEMORYCHUNK_MAX_VALUE);
+
/* compute the number of chunks that will fit on each block */
chunksPerBlock = (blockSize - Slab_BLOCKHDRSZ) / fullChunkSize;
@@ -374,9 +378,9 @@ SlabContextCreate(MemoryContext parent,
*/
/* Fill in SlabContext-specific header fields */
- slab->chunkSize = chunkSize;
- slab->fullChunkSize = fullChunkSize;
- slab->blockSize = blockSize;
+ slab->chunkSize = (uint32) chunkSize;
+ slab->fullChunkSize = (uint32) fullChunkSize;
+ slab->blockSize = (uint32) blockSize;
slab->chunksPerBlock = chunksPerBlock;
slab->curBlocklistIndex = 0;
@@ -506,7 +510,7 @@ SlabAlloc(MemoryContext context, Size size)
/* make sure we only allow correct request size */
if (unlikely(size != slab->chunkSize))
- elog(ERROR, "unexpected alloc chunk size %zu (expected %zu)",
+ elog(ERROR, "unexpected alloc chunk size %zu (expected %u)",
size, slab->chunkSize);
/*