diff options
author | Jeff Davis <jdavis@postgresql.org> | 2020-03-18 15:39:14 -0700 |
---|---|---|
committer | Jeff Davis <jdavis@postgresql.org> | 2020-03-18 15:39:14 -0700 |
commit | e00912e11a9ec2d29274ed8a6465e81385906dc2 (patch) | |
tree | 3a8cfa1201e76fe7e6129a86243abef6ca386c64 /src/backend/utils/mmgr/generation.c | |
parent | 487e9861d0cf83e9100ad0d0369147db3ef4ea73 (diff) | |
download | postgresql-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.c | 25 |
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 */ |