src/backend/utils/mmgr/slab.c
MemoryContext
SlabContextCreate(MemoryContext parent,
				  const char *name,
				  Size blockSize,
				  Size chunkSize)
{
	int			chunksPerBlock;
	Size		fullChunkSize;
	Size		freelistSize;
	Size		headerSize;
	SlabContext *slab;
	int			i;

	/* Assert we padded SlabChunk properly */
	StaticAssertStmt(sizeof(SlabChunk) == MAXALIGN(sizeof(SlabChunk)),
					 "sizeof(SlabChunk) is not maxaligned");
	StaticAssertStmt(offsetof(SlabChunk, slab) + sizeof(MemoryContext) ==
					 sizeof(SlabChunk),
					 "padding calculation in SlabChunk is wrong");

	/* Make sure the linked list node fits inside a freed chunk */
	if (chunkSize < sizeof(int))
		chunkSize = sizeof(int);

	/* chunk, including SLAB header (both addresses nicely aligned) */
	fullChunkSize = sizeof(SlabChunk) + MAXALIGN(chunkSize);

	/* Make sure the block can store at least one chunk. */
	if (blockSize < fullChunkSize + sizeof(SlabBlock))
		elog(ERROR, "block size %zu for slab is too small for %zu chunks",
			 blockSize, chunkSize);

	/* Compute maximum number of chunks per block */
	chunksPerBlock = (blockSize - sizeof(SlabBlock)) / fullChunkSize;

	/* The freelist starts with 0, ends with chunksPerBlock. */
	freelistSize = sizeof(dlist_head) * (chunksPerBlock + 1);

	/*
	 * Allocate the context header.  Unlike aset.c, we never try to combine
	 * this with the first regular block; not worth the extra complication.
	 */

	/* Size of the memory context header */
	headerSize = offsetof(SlabContext, freelist) + freelistSize;

#ifdef MEMORY_CONTEXT_CHECKING

	/*
	 * With memory checking, we need to allocate extra space for the bitmap of
	 * free chunks. The bitmap is an array of bools, so we don't need to worry
	 * about alignment.
	 */
	headerSize += chunksPerBlock * sizeof(bool);
#endif

	slab = (SlabContext *) malloc(headerSize);
	if (slab == NULL)
	{
		MemoryContextStats(TopMemoryContext);
		ereport(ERROR,
				(errcode(ERRCODE_OUT_OF_MEMORY),
				 errmsg("out of memory"),
				 errdetail("Failed while creating memory context \"%s\".",
						   name)));
	}

	/*
	 * Avoid writing code that can fail between here and MemoryContextCreate;
	 * we'd leak the header if we ereport in this stretch.
	 */

	/* Fill in SlabContext-specific header fields */
	slab->chunkSize = chunkSize;
	slab->fullChunkSize = fullChunkSize;
	slab->blockSize = blockSize;
	slab->headerSize = headerSize;
	slab->chunksPerBlock = chunksPerBlock;
	slab->minFreeChunks = 0;
	slab->nblocks = 0;

	/* initialize the freelist slots */
	for (i = 0; i < (slab->chunksPerBlock + 1); i++)
		dlist_init(&slab->freelist[i]);

#ifdef MEMORY_CONTEXT_CHECKING
	/* set the freechunks pointer right after the freelists array */
	slab->freechunks
		= (bool *) slab + offsetof(SlabContext, freelist) + freelistSize;
#endif

	/* Finally, do the type-independent part of context creation */
	MemoryContextCreate((MemoryContext) slab,
						T_SlabContext,
						&SlabMethods,
						parent,
						name);

	return (MemoryContext) slab;
}
/*
 * SlabContextCreate
 *		Create a new Slab context.
 *
 * parent: parent context, or NULL if top-level context
 * name: name of context (must be statically allocated)
 * blockSize: allocation block size
 * chunkSize: allocation chunk size
 *
 * The chunkSize may not exceed:
 *		MAXALIGN_DOWN(SIZE_MAX) - MAXALIGN(sizeof(SlabBlock)) - sizeof(SlabChunk)
 */
SlabContextCreate
Create a new Slab context.

parent context, or NULL if top-level context
name: name of context (must be statically allocated)
blockSize: allocation block size
chunkSize: allocation chunk size


SlabContextCreate Create a new Slab context . parent context or NULL if top - level context name : name of context ( must be statically allocated ) blockSize : allocation block size chunkSize : allocation chunk size
MemoryContext
SlabContextCreate(MemoryContext parent,
				  const char *name,
				  Size blockSize,
				  Size chunkSize)
{
	int			chunksPerBlock;
	Size		fullChunkSize;
	Size		freelistSize;
	Size		headerSize;
	SlabContext *slab;
	int			i;
	StaticAssertStmt(sizeof(SlabChunk) == MAXALIGN(sizeof(SlabChunk)),
					 "sizeof(SlabChunk) is not maxaligned");
	StaticAssertStmt(offsetof(SlabChunk, slab) + sizeof(MemoryContext) ==
					 sizeof(SlabChunk),
					 "padding calculation in SlabChunk is wrong");
	if (chunkSize < sizeof(int))
		chunkSize = sizeof(int);
	fullChunkSize = sizeof(SlabChunk) + MAXALIGN(chunkSize);
	if (blockSize < fullChunkSize + sizeof(SlabBlock))
		elog(ERROR, "block size %zu for slab is too small for %zu chunks",
			 blockSize, chunkSize);
	chunksPerBlock = (blockSize - sizeof(SlabBlock)) / fullChunkSize;
	freelistSize = sizeof(dlist_head) * (chunksPerBlock + 1);
	headerSize = offsetof(SlabContext, freelist) + freelistSize;
#ifdef MEMORY_CONTEXT_CHECKING
	headerSize += chunksPerBlock * sizeof(bool);
#endif
	slab = (SlabContext *) malloc(headerSize);
	if (slab == NULL)
	{
		MemoryContextStats(TopMemoryContext);
		ereport(ERROR,
				(errcode(ERRCODE_OUT_OF_MEMORY),
				 errmsg("out of memory"),
				 errdetail("Failed while creating memory context \"%s\".",
						   name)));
	}
	slab->chunkSize = chunkSize;
	slab->fullChunkSize = fullChunkSize;
	slab->blockSize = blockSize;
	slab->headerSize = headerSize;
	slab->chunksPerBlock = chunksPerBlock;
	slab->minFreeChunks = 0;
	slab->nblocks = 0;
	for (i = 0; i < (slab->chunksPerBlock + 1); i++)
		dlist_init(&slab->freelist[i]);
#ifdef MEMORY_CONTEXT_CHECKING
	slab->freechunks
		= (bool *) slab + offsetof(SlabContext, freelist) + freelistSize;
#endif
	MemoryContextCreate((MemoryContext) slab,
						T_SlabContext,
						&SlabMethods,
						parent,
						name);
	return (MemoryContext) slab;
}
MemoryContext SlabContextCreate ( MemoryContext parent , const char * name , Size blockSize , Size chunkSize ) { int chunksPerBlock ; Size fullChunkSize ; Size freelistSize ; Size headerSize ; SlabContext * slab ; int i ; StaticAssertStmt ( sizeof ( SlabChunk ) == MAXALIGN ( sizeof ( SlabChunk ) ) , " " ) ; StaticAssertStmt ( offsetof ( SlabChunk , slab ) + sizeof ( MemoryContext ) == sizeof ( SlabChunk ) , " " ) ; if ( chunkSize < sizeof ( int ) ) chunkSize = sizeof ( int ) ; fullChunkSize = sizeof ( SlabChunk ) + MAXALIGN ( chunkSize ) ; if ( blockSize < fullChunkSize + sizeof ( SlabBlock ) ) elog ( ERROR , " " , blockSize , chunkSize ) ; chunksPerBlock = ( blockSize - sizeof ( SlabBlock ) ) / fullChunkSize ; freelistSize = sizeof ( dlist_head ) * ( chunksPerBlock + 1 ) ; headerSize = offsetof ( SlabContext , freelist ) + freelistSize ; #ifdef MEMORY_CONTEXT_CHECKING headerSize += chunksPerBlock * sizeof ( bool ) ; #endif slab = ( SlabContext * ) malloc ( headerSize ) ; if ( slab == NULL ) { MemoryContextStats ( TopMemoryContext ) ; ereport ( ERROR , ( errcode ( ERRCODE_OUT_OF_MEMORY ) , errmsg ( " " ) , errdetail ( " \" \" " , name ) ) ) ; } slab -> chunkSize = chunkSize ; slab -> fullChunkSize = fullChunkSize ; slab -> blockSize = blockSize ; slab -> headerSize = headerSize ; slab -> chunksPerBlock = chunksPerBlock ; slab -> minFreeChunks = 0 ; slab -> nblocks = 0 ; for ( i = 0 ; i < ( slab -> chunksPerBlock + 1 ) ; i ++ ) dlist_init ( & slab -> freelist [ i ] ) ; #ifdef MEMORY_CONTEXT_CHECKING slab -> freechunks = ( bool * ) slab + offsetof ( SlabContext , freelist ) + freelistSize ; #endif MemoryContextCreate ( ( MemoryContext ) slab , T_SlabContext , & SlabMethods , parent , name ) ; return ( MemoryContext ) slab ; }
SlabContextCreate
              Create a new Slab context.
SlabContextCreate Create a new Slab context .
/* Assert we padded SlabChunk properly */ /* Make sure the linked list node fits inside a freed chunk */ /* chunk, including SLAB header (both addresses nicely aligned) */ /* Make sure the block can store at least one chunk. */ /* Compute maximum number of chunks per block */ /* The freelist starts with 0, ends with chunksPerBlock. */ /*
	 * Allocate the context header.  Unlike aset.c, we never try to combine
	 * this with the first regular block; not worth the extra complication.
	 */ /* Size of the memory context header */ /*
	 * With memory checking, we need to allocate extra space for the bitmap of
	 * free chunks. The bitmap is an array of bools, so we don't need to worry
	 * about alignment.
	 */ /*
	 * Avoid writing code that can fail between here and MemoryContextCreate;
	 * we'd leak the header if we ereport in this stretch.
	 */ /* Fill in SlabContext-specific header fields */ /* initialize the freelist slots */ /* set the freechunks pointer right after the freelists array */ /* Finally, do the type-independent part of context creation */