From 9787c8a89b4df0e13946ea3e63025c4d9f5900aa Mon Sep 17 00:00:00 2001 Message-Id: <9787c8a89b4df0e13946ea3e63025c4d9f5900aa.1715430596.git.mdw@distorted.org.uk> From: Mark Wooding Date: Sun, 16 Jul 2000 18:20:54 +0000 Subject: [PATCH] Document the `pool' interface. Organization: Straylight/Edgeware From: mdw --- man/mLib.3 | 16 +++++- man/pool.3 | 165 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 man/pool.3 diff --git a/man/mLib.3 b/man/mLib.3 index cb5ee4a..fc10096 100644 --- a/man/mLib.3 +++ b/man/mLib.3 @@ -39,6 +39,12 @@ module, and stands alone. It's used mainly by the memory allocation modules to raise exceptions when there's no more memory to be had. .SS "Memory allocation" The +.BR arena (3) +module provides an abstraction of memory allocation. By writing +appropriate arena implementations, a client program can control where +and how memory is allocated for various structures. +.PP +The .BR alloc (3) module provides simple veneers onto traditional memory allocation functions like @@ -50,7 +56,9 @@ and doesn't actually depend on .B strdup being defined in the library) which raise exceptions when there's not -enough memory left. +enough memory left. These work through the +.B arena +layer, so that the caller can control memory allocation. .PP The .BR sub (3) @@ -64,6 +72,12 @@ The .B track module (not yet documented) is a simple memory allocation tracker. It can be handy when trying to fix memory leaks. +.PP +The +.BR pool (3) +module maintains resource pools which can manage memory and other +resources, all of the resources held in a pool being destroyed along +with the pool itself. .SS "String handling" The .BR str (3) diff --git a/man/pool.3 b/man/pool.3 new file mode 100644 index 0000000..182215a --- /dev/null +++ b/man/pool.3 @@ -0,0 +1,165 @@ +.\" -*-nroff-*- +.de VS +.sp 1 +.RS +.nf +.ft B +.. +.de VE +.ft R +.fi +.RE +.sp 1 +.. +.TH pool 3 "7 July 2000" mLib +.SH "NAME" +pool \- resource pool management +.\" @pool_alloc +.\" @pool_strdup +.\" @pool_create +.\" @pool_destroy +.\" @pool_sub +.\" @pool_add +.\" @POOL_ADD +.\" @pool_fopen +.\" @pool_fclose +.\" @pool_subarena +.SH "SYNOPSIS" +.nf +.B "#include " + +.BI "pool *pool_create(arena *" a ); +.BI "pool *pool_sub(pool *" p ); +.BI "void pool_destroy(pool *" p ); +.BI "void pool_add(pool *" p ", pool_resource *" r , +.BI " void (*" dfn ")(pool_resource *" r )); +.BI "void *pool_alloc(pool *" p ", size_t " sz ); +.BI "char *pool_strdup(pool *" p ", const char *" s ); +.BI "pool_file *pool_fopen(pool *" p ", const char *" file ", const char *" how ); +.BI "int pool_fclose(pool_file *" pf ); +.BI "subarena *pool_subarena(pool *" p ); + +.BI "void POOL_ADD(pool *" p ", pool_resource *" r , +.BI " void (*" dfn ")(pool_resource *" r )); +.fi +.SH "DESCRIPTION" +.SS "Overview" +A +.I "resource pool" +is a collection of resources (e.g., memory, files) which may be disposed +of simultaneously. +.PP +A pool may be a +.IR "root pool" , +in which case it stands on its own, or it may be a +.IR "subpool" +of another pool (which may in turn either be a root pool or a subpool of +another). +.PP +Pools manage memory efficiently. Memory is allocated in large chunks +from an +.BR arena (3), +and given out as necessary to callers. There is no way of freeing +memory dynamically; instead, the memory allocated by a pool is freed +when the pool is destroyed. While allocation is rapid, there is waste +because the allocator has to ensure that blocks are properly aligned. +Since pools offer an arena interface, it is possible to build a +.BR subarena (3) +over them. This also enables memory in the subarena to be reclaimed +when the pool is destroyed. +.PP +Other resources (e.g., file handles) may be added to the pool. The pool +will automatically release any resources it has when it's destroyed. +Attaching resources to an appropriate pool can therefore be a useful way +of avoiding memory leaks. +.SS "Creating and destroying pools" +A new root pool is created using +.BR pool_create , +passing it an arena from which it can allocate large memory blocks. +.PP +A subpool is created by calling +.BR pool_sub , +naming the parent pool. +.PP +Pools are destroyed by passing them to +.BR pool_destroy . +Root pools are completely destroyed, since the memory containing the +pool structure is allocated from the pool itself. Subpools, on the +other hand, are allocated from a parent pool, and may be reused after +being `destroyed'. +.SS "Memory allocation" +Memory is allocated from a pool by calling +.BR pool_alloc , +passing it the pool and the size of memory requested. There is an +interface for copying strings, +.BR pool_strdup , +since this is a common operation. Note that there is no +.BR pool_free : +if this is important, either use the pool's arena +.B p->pa +directly or create a subpool. +.PP +A pool provides an +.BR arena (3) +interface, +.BR p->a , +which can be passed to other components to cause them to use the pool +for memory allocation. +.SS "Other resources" +Pool resources have a header of type +.B pool_resource +with the structure: +.VS +typedef struct pool_resource { + struct pool_resource *next; + void (*destroy)(struct pool_resource */*r*/); +} pool_resource; +.VE +Resources are added to the pool by passing a pointer to the pool, the +resource block and a destruction function to +.BR pool_add . +.PP +If your resource is freed before the pool is destroyed, manually zero +the +.B destroy +field in the resource header to let the pool manager know not to free +the resource again. +.PP +It's usual to allocate the resource structures from the pool's arena so +that they're automatically freed when the pool is destroyed. +.PP +A +.BR subarena (3) +may be created for a particular pool by calling +.BR pool_subarena . +The subarena and its contents will be freed automatically when the pool +is destroyed. +.PP +Files may be opened and registered with a pool by +.BR pool_fopen : +the +.I pool +argument specifies which pool, and the +.I file +and +.I how +arguments are passed to the standard +.BR fopen (3) +function. The return value is a pointer to a +.B pool_file +structure, containing a member +.B fp +which is the actual file handle. Don't call +.B fclose +directly on the file handle: instead pass the whole structure to +.B pool_fclose +which will ensure that it doesn't get closed twice by accident. It's +advisable to close files by hand, to prevent the process from running +out; it's just not a disaster if you forget by accident. +.SH "SEE ALSO" +.BR alloc (3), +.BR arena (3), +.BR mLib (3), +.BR subarena (3). +.SH AUTHOR +Mark Wooding, -- [mdw]