356 lines · 8.4 KB · Text
RawDownload
.TH POOL 2.SH NAMEpoolalloc, poolallocalign, poolfree, poolmsize, poolrealloc, poolcompact, poolcheck, poolblockcheck,pooldump \- general memory management routines.SH SYNOPSIS.B #include <u.h>.br.B #include <libc.h>.br.B #include <pool.h>.PP.Bvoid*	poolalloc(Pool* pool, ulong size).PP.Bvoid*	poolallocalign(Pool *pool, ulong size, .br.B                ulong align, long offset, ulong span).PP.Bvoid	poolfree(Pool* pool, void* ptr).PP.Bulong	poolmsize(Pool* pool, void* ptr).PP.Bvoid*	poolrealloc(Pool* pool, void* ptr, ulong size).PP.Bvoid	poolcompact(Pool* pool).PP.Bvoid	poolcheck(Pool *pool).PP.Bvoid	poolblockcheck(Pool *pool, void *ptr).PP.Bvoid	pooldump(Pool *pool);.SH DESCRIPTIONThese routines provide a general memory management facility.Memory is retrieved from a coarser allocator (e.g. .I sbrkor the kernel's .IR xalloc )and then allocated to callers.The routines are locked and thus may safely be used inmultiprocess programs..PP.I Poolallocattempts to allocate a block of size.BR size ;it returns a pointer to the block when successful and nil otherwise.The call.B "poolalloc(0)returns a non-nil pointer..I Poolfreereturns an allocated block to the pool.It is an error to free a block more than once or to free apointer not returned by.IR poolalloc .The call.B "poolfree(nil)is legal and is a no-op..PP.I Poolallocalignattempts to allocate a block of size.B sizewith the given alignment constraints.If.I alignis non-zero,the returned pointer is aligned to be equal to.I offsetmodulo.IR align .If.I spanis non-zero,the.I nbyte block allocated will not span a.IR span -byteboundary..PP.I Poolreallocattempts to resize to.B nsizebytes the block associated with.BR ptr ,which must have been previously returned by.I poolallocor .IR poolrealloc .If the block's size can be adjusted, a (possibly different) pointer to the new block is returned.The contents up to the lesser of the old and new sizes are unchanged.After a successful call to.IR poolrealloc ,the return value should be used rather than.B ptrto access the block.If the request cannot be satisfied, .I poolreallocreturns nil, and the old pointer remains valid..PPWhen blocks are allocated, there is often some extra space left at the endthat would usually go unused..IR Poolmsizegrows the block to encompass this extra space and returns the new size..PPThe .I poolblockcheckand.I poolcheckroutines validate a single allocated block or the entire pool, respectively.They call .B panic(see below)if corruption is detected..I Pooldumpprints a summary line for every block in thepool, using the.B printfunction (see below)..PPThe.B Poolstructure itself provides much of the setup interface..IP.EX.ta \w'\fL    'u +\w'\fLulong 'u +\w'\fLlastcompact;  'utypedef struct Pool Pool;struct Pool {	char*	name;	ulong	maxsize;	/* of entire Pool */	ulong	cursize;	/* of Pool */	ulong	curfree;	/* total free bytes in Pool */	ulong	curalloc;	/* total allocated bytes in Pool */	ulong	minarena;	/* smallest size of new arena */	ulong	quantum;	/* allocated blocks should be multiple of */	ulong	minblock;	/* smallest newly allocated block */	int	flags;	int	nfree;	/* number of calls to free */	int	lastcompact;	/* nfree at time of last poolcompact */	void*	(*alloc)(ulong);	int	(*merge)(void*, void*);	void	(*move)(void* from, void* to);	void	(*lock)(Pool*);	void	(*unlock)(Pool*);	void	(*print)(Pool*, char*, ...);	void	(*panic)(Pool*, char*, ...);	void	(*logstack)(Pool*);	void*	private;};.ta \w'\fL    'u +\w'POOL_ANTAGONISM 'uenum {  /* flags */	POOL_ANTAGONISM	= 1<<0,	POOL_PARANOIA	= 1<<1,	POOL_VERBOSITY	= 1<<2,	POOL_DEBUGGING	= 1<<3,	POOL_LOGGING	= 1<<4,	POOL_TOLERANCE	= 1<<5,	POOL_NOREUSE	= 1<<6,};.EE.PPThe pool obtains arenas of memory to manage by calling the the given.B allocroutine.The total number of requested bytes will not exceed .BR maxsize .Each allocation request will be for at least.B minarenabytes..PPWhen a new arena is allocated, the pool routines try tomerge it with the surrounding arenas, in an attempt to combat fragmentation.If .B mergeis non-nil, it is called with the addresses of two blocks from.B allocthat the pool routines suspect might be adjacent.If they are not mergeable, .B mergemust return zero.If they are mergeable, .B mergeshould merge them into one block in its own bookkeepingand return non-zero..PPTo ease fragmentation and make block reuse easier, the sizes requested of the pool routines are rounded up to a multiple of.B quantumbefore the carrying out requests.If, after rounding, the block size is still less than.B minblockbytes, .B minblockwill be used as the block size..PP.I Poolcompactdefragments the pool, moving blocks in order to aggregatethe free space.Each time it moves a block, it notifies the.B moveroutine that the contents have moved.At the time that.B moveis called, the contents have already moved,so .B fromshould never be dereferenced.If no.B moveroutine is supplied (i.e. it is nil), then calling.I poolcompactis a no-op..PPWhen the pool routines need to allocate a new arena but cannot,either because.B allochas returned nil or because doing so would use more than.B maxsizebytes,.I poolcompactis called once to defragment the memoryand the request is retried..PP.I Poolsare protected by the pool routines calling.B lock(when non-nil)before modifying the pool, andcalling.B unlockwhen finished..PPWhen internal corruption is detected,.B panicis called with a .IR print (2)style argument that specifies what happened.It is assumed that .B panicnever returns.When the pool routines wish to convey a messageto the caller (usually because logging is turned on; see below),.B printis called, also with a .IR print (2)style argument..PP.B Flagsis a bit vector that tweaks the behavior of the pool routinesin various ways.Most are useful for debugging in one way or another.When.B POOL_ANTAGONISMis set,.I poolallocfills blocks with non-zero garbage before releasing them to the user,and.I poolfreefills the blocks on receipt.This tickles both user programs and the innards of the allocator.Specifically, each 32-bit word of the memory is marked with a pointer value exclusive-or'edwith a constant.The pointer value is the pointer to the beginning of the allocated blockand the constant varies in order to distinguish different markings.Freed blocks use the constant .BR 0xF7000000 ,newly allocated blocks.BR 0xF9000000 ,and newly created unallocated blocks.BR 0xF1000000 .For example, if .B POOL_ANTAGONISM is set and.I poolallocreturns a block starting at .BR 0x00012345 ,each word of the block will contain the value.BR 0xF90012345 .Recognizing these numbers in memory-related crashes canhelp diagnose things like double-frees or dangling pointers..PPSetting.B POOL_PARANOIAcauses the allocator to walk the entire pool whenever locking or unlocking itself,looking for corruption.This slows runtime by a few orders of magnitudewhen many blocks are in use.If .B POOL_VERBOSITYis set, the entire pool structure is printed(via .BR print )each time the pool is locked or unlocked..B POOL_DEBUGGINGenables internaldebugging output,whose format is unspecified and volatile.It should not be used by most programs.When.B POOL_LOGGINGis set, a single line is printed via .B printat the beginning and end of each pool call.If .B logstackis not nil, it will be called as well.This provides a mechanism for external programs to search for leaks.(See .IR leak (1)for one such program.).PPThe pool routines are strict about the amount of space callers use.If even a single byte is written past the end of the allotted space of a block, theywill notice when that block is next used in a call to.I poolreallocor .I free(or at the next entry into the allocator, when.B POOL_PARANOIAis set),and.B panicwill be called.Since forgetting to allocate space for theterminating NUL on strings is such a common error,if.B POOL_TOLERANCE is set and a single NUL is found written past the end of a block,.B printwill be called with a notification, but.B panicwill not be..PPWhen.B POOL_NOREUSEis set,.B poolfreefills the passed block with garbage rather thanreturn it to the free pool..SH SOURCE.B /sys/src/libc/port/pool.c.SH SEE ALSO.IR malloc (2),.IR brk (2).PP.B /sys/src/libc/port/malloc.cis a complete example.