aboutsummaryrefslogtreecommitdiff
path: root/man/man3/pool.3
diff options
context:
space:
mode:
Diffstat (limited to 'man/man3/pool.3')
-rw-r--r--man/man3/pool.3329
1 files changed, 329 insertions, 0 deletions
diff --git a/man/man3/pool.3 b/man/man3/pool.3
new file mode 100644
index 00000000..0c9a8d49
--- /dev/null
+++ b/man/man3/pool.3
@@ -0,0 +1,329 @@
+.TH POOL 3
+.SH NAME
+poolalloc, poolfree, poolmsize, poolrealloc, poolcompact, poolcheck, poolblockcheck,
+pooldump \- general memory management routines
+.SH SYNOPSIS
+.B #include <u.h>
+.PP
+.B #include <libc.h>
+.PP
+.B #include <pool.h>
+.PP
+.B
+void* poolalloc(Pool* pool, ulong size)
+.PP
+.B
+void poolfree(Pool* pool, void* ptr)
+.PP
+.B
+ulong poolmsize(Pool* pool, void* ptr)
+.PP
+.B
+void* poolrealloc(Pool* pool, void* ptr, ulong size)
+.PP
+.B
+void poolcompact(Pool* pool)
+.PP
+.B
+void poolcheck(Pool *pool)
+.PP
+.B
+void poolblockcheck(Pool *pool, void *ptr)
+.PP
+.B
+void pooldump(Pool *pool);
+.SH DESCRIPTION
+These routines provide a general memory management facility.
+Memory is retrieved from a coarser allocator (e.g.
+.I sbrk
+or the kernel's
+.IR xalloc )
+and then allocated to callers.
+The routines are locked and thus may safely be used in
+multiprocess programs.
+.PP
+.I Poolalloc
+attempts 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 Poolfree
+returns an allocated block to the pool.
+It is an error to free a block more than once or to free a
+pointer not returned by
+.IR poolalloc .
+The call
+.B "poolfree(nil)
+is legal and is a no-op.
+.I Poolrealloc
+attempts to resize to
+.B nsize
+bytes the block associated with
+.BR ptr ,
+which must have been previously returned by
+.I poolalloc
+or
+.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 ptr
+to access the block.
+If the request cannot be satisfied,
+.I poolrealloc
+returns nil, and the old pointer remains valid.
+.PP
+When blocks are allocated, there is often some extra space left at the end
+that would usually go unused.
+.IR Poolmsize
+grows the block to encompass this extra space and returns the new size.
+.PP
+The
+.I poolblockcheck
+and
+.I poolcheck
+routines validate a single allocated block or the entire pool, respectively.
+They call
+.B panic
+(see below)
+if corruption is detected.
+.I Pooldump
+prints a summary line for every block in the
+pool, using the
+.B print
+function (see below).
+.PP
+The
+.B Pool
+structure itself provides much of the setup interface.
+.IP
+.EX
+.ta \w'\fL 'u +\w'\fLulong 'u +\w'\fLlastcompact; 'u
+typedef 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 'u
+enum { /* 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
+.PP
+The pool obtains arenas of memory to manage by calling the the given
+.B alloc
+routine.
+The total number of requested bytes will not exceed
+.BR maxsize .
+Each allocation request will be for at least
+.B minarena
+bytes.
+.PP
+When a new arena is allocated, the pool routines try to
+merge it with the surrounding arenas, in an attempt to combat fragmentation.
+If
+.B merge
+is non-nil, it is called with the addresses of two blocks from
+.B alloc
+that the pool routines suspect might be adjacent.
+If they are not mergeable,
+.B merge
+must return zero.
+If they are mergeable,
+.B merge
+should merge them into one block in its own bookkeeping
+and return non-zero.
+.PP
+To ease fragmentation and make
+block reuse easier, the sizes requested of the pool routines are rounded up to a multiple of
+.B quantum
+before
+the carrying out requests.
+If, after rounding, the block size is still less than
+.B minblock
+bytes,
+.B minblock
+will be used as the block size.
+.PP
+.I Poolcompact
+defragments the pool, moving blocks in order to aggregate
+the free space.
+Each time it moves a block, it notifies the
+.B move
+routine that the contents have moved.
+At the time that
+.B move
+is called, the contents have already moved,
+so
+.B from
+should never be dereferenced.
+If no
+.B move
+routine is supplied (i.e. it is nil), then calling
+.I poolcompact
+is a no-op.
+.PP
+When the pool routines need to allocate a new arena but cannot,
+either because
+.B alloc
+has returned nil or because doing so would use more than
+.B maxsize
+bytes,
+.I poolcompact
+is called once to defragment the memory
+and the request is retried.
+.PP
+.I Pools
+are protected by the pool routines calling
+.B lock
+(when non-nil)
+before modifying the pool, and
+calling
+.B unlock
+when finished.
+.PP
+When internal corruption is detected,
+.B panic
+is called with a
+.IR print (2)
+style argument that specifies what happened.
+It is assumed that
+.B panic
+never returns.
+When the pool routines wish to convey a message
+to the caller (usually because logging is turned on; see below),
+.B print
+is called, also with a
+.IR print (2)
+style argument.
+.PP
+.B Flags
+is a bit vector that tweaks the behavior of the pool routines
+in various ways.
+Most are useful for debugging in one way or another.
+When
+.B POOL_ANTAGONISM
+is set,
+.I poolalloc
+fills blocks with non-zero garbage before releasing them to the user,
+and
+.I poolfree
+fills 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'ed
+with a constant.
+The pointer value is the pointer to the beginning of the allocated block
+and 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 poolalloc
+returns a block starting at
+.BR 0x00012345 ,
+each word of the block will contain the value
+.BR 0xF90012345 .
+Recognizing these numbers in memory-related crashes can
+help diagnose things like double-frees or dangling pointers.
+.PP
+Setting
+.B POOL_PARANOIA
+causes the allocator to walk the entire pool whenever locking or unlocking itself,
+looking for corruption.
+This slows runtime by a few orders of magnitude
+when many blocks are in use.
+If
+.B POOL_VERBOSITY
+is set,
+the entire pool structure is printed
+(via
+.BR print )
+each time the pool is locked or unlocked.
+.B POOL_DEBUGGING
+enables internal
+debugging output,
+whose format is unspecified and volatile.
+It should not be used by most programs.
+When
+.B POOL_LOGGING
+is set, a single line is printed via
+.B print
+at the beginning and end of each pool call.
+If
+.B logstack
+is 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.)
+.PP
+The 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, they
+will notice when that block is next used in a call to
+.I poolrealloc
+or
+.I free
+(or at the next entry into the allocator, when
+.B POOL_PARANOIA
+is set),
+and
+.B panic
+will be called.
+Since forgetting to allocate space for the
+terminating 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 print
+will be called with a notification, but
+.B panic
+will not be.
+.PP
+When
+.B POOL_NOREUSE
+is set,
+.B poolfree
+fills the passed block with garbage rather than
+return 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.c
+is a complete example.