aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/mmgr/generation.c
diff options
context:
space:
mode:
authorJeff Davis <jdavis@postgresql.org>2020-03-18 15:39:14 -0700
committerJeff Davis <jdavis@postgresql.org>2020-03-18 15:39:14 -0700
commite00912e11a9ec2d29274ed8a6465e81385906dc2 (patch)
tree3a8cfa1201e76fe7e6129a86243abef6ca386c64 /src/backend/utils/mmgr/generation.c
parent487e9861d0cf83e9100ad0d0369147db3ef4ea73 (diff)
downloadpostgresql-e00912e11a9ec2d29274ed8a6465e81385906dc2.tar.gz
postgresql-e00912e11a9ec2d29274ed8a6465e81385906dc2.zip
Specialize MemoryContextMemAllocated().
An AllocSet doubles the size of allocated blocks (up to maxBlockSize), which means that the current block can represent half of the total allocated space for the memory context. But the free space in the current block may never have been touched, so don't count the untouched memory as allocated for the purposes of MemoryContextMemAllocated(). Discussion: https://postgr.es/m/ec63d70b668818255486a83ffadc3aec492c1f57.camel@j-davis.com
Diffstat (limited to 'src/backend/utils/mmgr/generation.c')
-rw-r--r--src/backend/utils/mmgr/generation.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/src/backend/utils/mmgr/generation.c b/src/backend/utils/mmgr/generation.c
index 56651d06931..f0ef540a7c5 100644
--- a/src/backend/utils/mmgr/generation.c
+++ b/src/backend/utils/mmgr/generation.c
@@ -61,6 +61,7 @@ typedef struct GenerationContext
/* Generational context parameters */
Size blockSize; /* standard block size */
+ Size memAllocated; /* track memory allocated for this context */
GenerationBlock *block; /* current (most recently allocated) block */
dlist_head blocks; /* list of blocks */
@@ -152,6 +153,7 @@ static void *GenerationRealloc(MemoryContext context, void *pointer, Size size);
static void GenerationReset(MemoryContext context);
static void GenerationDelete(MemoryContext context);
static Size GenerationGetChunkSpace(MemoryContext context, void *pointer);
+static Size GenerationMemAllocated(MemoryContext context);
static bool GenerationIsEmpty(MemoryContext context);
static void GenerationStats(MemoryContext context,
MemoryStatsPrintFunc printfunc, void *passthru,
@@ -171,6 +173,7 @@ static const MemoryContextMethods GenerationMethods = {
GenerationReset,
GenerationDelete,
GenerationGetChunkSpace,
+ GenerationMemAllocated,
GenerationIsEmpty,
GenerationStats
#ifdef MEMORY_CONTEXT_CHECKING
@@ -258,6 +261,7 @@ GenerationContextCreate(MemoryContext parent,
/* Fill in GenerationContext-specific header fields */
set->blockSize = blockSize;
+ set->memAllocated = 0;
set->block = NULL;
dlist_init(&set->blocks);
@@ -297,7 +301,7 @@ GenerationReset(MemoryContext context)
dlist_delete(miter.cur);
- context->mem_allocated -= block->blksize;
+ set->memAllocated -= block->blksize;
#ifdef CLOBBER_FREED_MEMORY
wipe_mem(block, block->blksize);
@@ -354,7 +358,7 @@ GenerationAlloc(MemoryContext context, Size size)
if (block == NULL)
return NULL;
- context->mem_allocated += blksize;
+ set->memAllocated += blksize;
/* block with a single (used) chunk */
block->blksize = blksize;
@@ -411,7 +415,7 @@ GenerationAlloc(MemoryContext context, Size size)
if (block == NULL)
return NULL;
- context->mem_allocated += blksize;
+ set->memAllocated += blksize;
block->blksize = blksize;
block->nchunks = 0;
@@ -528,7 +532,7 @@ GenerationFree(MemoryContext context, void *pointer)
if (set->block == block)
set->block = NULL;
- context->mem_allocated -= block->blksize;
+ set->memAllocated -= block->blksize;
free(block);
}
@@ -667,6 +671,17 @@ GenerationGetChunkSpace(MemoryContext context, void *pointer)
}
/*
+ * All memory currently allocated for this context (including fragmentation
+ * and freed chunks).
+ */
+static Size
+GenerationMemAllocated(MemoryContext context)
+{
+ GenerationContext *set = (GenerationContext *) context;
+ return set->memAllocated;
+}
+
+/*
* GenerationIsEmpty
* Is a GenerationContext empty of any allocated space?
*/
@@ -844,7 +859,7 @@ GenerationCheck(MemoryContext context)
name, nfree, block, block->nfree);
}
- Assert(total_allocated == context->mem_allocated);
+ Assert(total_allocated == gen->memAllocated);
}
#endif /* MEMORY_CONTEXT_CHECKING */