MemoryContext
GenerationContextCreate(MemoryContext parent,constchar*name,
Size blockSize){
GenerationContext *set;...
set =(GenerationContext *)malloc(MAXALIGN(sizeof(GenerationContext)));.../* Fill in GenerationContext-specific header fields */
set->blockSize = blockSize;
set->block =NULL;dlist_init(&set->blocks);/* Finally, do the type-independent part of context creation */MemoryContextCreate((MemoryContext) set,
T_GenerationContext,&GenerationMethods,
parent,
name);return(MemoryContext) set;}
分配空间
分配空间大小大于block/8
计算需要分配空间
分配空间
初始化空间
将空间放入循环双向链表
if(chunk_size > set->blockSize /8){
Size blksize = chunk_size + Generation_BLOCKHDRSZ + Generation_CHUNKHDRSZ;
block =(GenerationBlock *)malloc(blksize);if(block ==NULL)returnNULL;
context->mem_allocated += blksize;/* block with a single (used) chunk */
block->blksize = blksize;
block->nchunks =1;
block->nfree =0;/* the block is completely full */
block->freeptr = block->endptr =((char*) block)+ blksize;
chunk =(GenerationChunk *)(((char*) block)+ Generation_BLOCKHDRSZ);
chunk->block = block;
chunk->context = set;
chunk->size = chunk_size;.../* add the block to the list of allocated blocks */dlist_push_head(&set->blocks,&block->node);...returnGenerationChunkGetPointer(chunk);}
分配空间小于等于block/8
block为空或block剩余空间不足,则创建新的block
/*
* Not an over-sized chunk. Is there enough space in the current block? If
* not, allocate a new "regular" block.
*/
block = set->block;if((block ==NULL)||(block->endptr - block->freeptr)< Generation_CHUNKHDRSZ + chunk_size){
Size blksize = set->blockSize;
block =(GenerationBlock *)malloc(blksize);if(block ==NULL)returnNULL;
context->mem_allocated += blksize;
block->blksize = blksize;
block->nchunks =0;
block->nfree =0;
block->freeptr =((char*) block)+ Generation_BLOCKHDRSZ;
block->endptr =((char*) block)+ blksize;.../* add it to the doubly-linked list of blocks */dlist_push_head(&set->blocks,&block->node);/* and also use it as the current allocation block */
set->block = block;}
/* If there are still allocated chunks in the block, we're done. */if(block->nfree < block->nchunks)return;/*
* The block is empty, so let's get rid of it. First remove it from the
* list of blocks, then return it to malloc().
*/dlist_delete(&block->node);/* Also make sure the block is not marked as the current block. */if(set->block == block)
set->block =NULL;
context->mem_allocated -= block->blksize;free(block);
销毁GenerationContext
遍历blocks,删除节点,释放节点空间
释放context
staticvoidGenerationReset(MemoryContext context){
GenerationContext *set =(GenerationContext *) context;
dlist_mutable_iter miter;...dlist_foreach_modify(miter,&set->blocks){
GenerationBlock *block =dlist_container(GenerationBlock, node, miter.cur);dlist_delete(miter.cur);
context->mem_allocated -= block->blksize;...free(block);}
set->block =NULL;...}/*
* GenerationDelete
* Free all memory which is allocated in the given context.
*/staticvoidGenerationDelete(MemoryContext context){/* Reset to release all the GenerationBlocks */GenerationReset(context);/* And free the context header */free(context);}