chiark / gitweb /
@@@ man wip
[mLib] / mem / pool.3
1 .\" -*-nroff-*-
2 .de VS
3 .sp 1
4 .RS
5 .nf
6 .ft B
7 ..
8 .de VE
9 .ft R
10 .fi
11 .RE
12 .sp 1
13 ..
14 .TH pool 3 "7 July 2000" "Straylight/Edgeware" "mLib utilities library"
15 .SH "NAME"
16 pool \- resource pool management
17 .\" @pool_alloc
18 .\" @pool_strdup
19 .\" @pool_init
20 .\" @pool_create
21 .\" @pool_destroy
22 .\" @pool_sub
23 .\" @pool_add
24 .\" @POOL_ADD
25 .\" @pool_fopen
26 .\" @pool_fclose
27 .\" @pool_subarena
28 .SH "SYNOPSIS"
29 .nf
30 .B "#include <mLib/pool.h>"
31
32 .B "typedef struct { ...\& } pool;"
33
34 .ta 2n
35 .B "typedef struct {"
36 .B "    pool_resource *next;"
37 .BI "   void (*destroy)(pool_resource *" r );
38 .B "} pool_resource;"
39
40 .B "typedef struct {"
41 .B "    FILE *fp;"
42 .B "    ..."
43 .B "} pool_file;"
44
45 .BI "void pool_init(pool *" p ", arena *" a );
46 .BI "pool *pool_create(arena *" a );
47 .BI "pool *pool_sub(pool *" p );
48 .BI "void pool_destroy(pool *" p );
49 .ta \w'\fBvoid pool_add('u
50 .BI "void pool_add(pool *" p ", pool_resource *" r ,
51 .BI "   void (*" dfn ")(pool_resource *" r ));
52 .BI "void *pool_alloc(pool *" p ", size_t " sz );
53 .BI "char *pool_strdup(pool *" p ", const char *" s );
54 .BI "pool_file *pool_fopen(pool *" p ", const char *" file ", const char *" how );
55 .BI "int pool_fclose(pool_file *" pf );
56 .BI "subarena *pool_subarena(pool *" p );
57
58 .ta \w'\fBvoid POOL_ADD('u
59 .BI "void POOL_ADD(pool *" p ", pool_resource *" r ,
60 .BI "   void (*" dfn ")(pool_resource *" r ));
61 .fi
62 .SH "DESCRIPTION"
63 .SS "Overview"
64 A
65 .I "resource pool"
66 is a collection of resources (e.g., memory, files) which may be disposed
67 of simultaneously.
68 .PP
69 A pool may be a
70 .IR "root pool" ,
71 in which case it stands on its own, or it may be a
72 .IR "subpool"
73 of another pool (which may in turn either be a root pool or a subpool of
74 another).
75 .PP
76 Pools manage memory efficiently.  Memory is allocated in large chunks
77 from an
78 .BR arena (3),
79 and given out as necessary to callers.  There is no way of freeing
80 memory dynamically; instead, the memory allocated by a pool is freed
81 when the pool is destroyed.  While allocation is rapid, there is waste
82 because the allocator has to ensure that blocks are properly aligned.
83 Since pools offer an arena interface, it is possible to build a
84 .BR subarena (3)
85 over them.  This also enables memory in the subarena to be reclaimed
86 when the pool is destroyed.
87 .PP
88 Other resources (e.g., file handles) may be added to the pool.  The pool
89 will automatically release any resources it has when it's destroyed.
90 Attaching resources to an appropriate pool can therefore be a useful way
91 of avoiding memory leaks.
92 .SS "Creating and destroying pools"
93 A new root pool is created using
94 .BR pool_create ,
95 passing it an arena from which it can allocate large memory blocks.
96 Alternatively, you can allocate a
97 .B pool
98 structure from somewhere and initialize it by passing its address and an
99 arena to
100 .BR pool_init .
101 .PP
102 A subpool is created by calling
103 .BR pool_sub ,
104 naming the parent pool.
105 .PP
106 Pools are destroyed by passing them to
107 .BR pool_destroy .
108 Pools created by
109 .B pool_create
110 are completely destroyed, since the memory containing the pool structure
111 is allocated from the pool itself.  Subpools and pools allocated by the
112 caller and initialized by
113 .BR pool_init ,
114 on the other hand, are
115 allocated from a parent pool, and may be reused after being `destroyed'.
116 .SS "Memory allocation"
117 Memory is allocated from a pool by calling
118 .BR pool_alloc ,
119 passing it the pool and the size of memory requested.  There is an
120 interface for copying strings,
121 .BR pool_strdup ,
122 since this is a common operation.  Note that there is no
123 .BR pool_free :
124 if this is important, either use the pool's arena
125 .B p->pa
126 directly or create a subpool.
127 .PP
128 A pool provides an
129 .BR arena (3)
130 interface,
131 .BR p->a ,
132 which can be passed to other components to cause them to use the pool
133 for memory allocation.
134 .SS "Other resources"
135 Pool resources have a header of type
136 .B pool_resource
137 with the structure shown in the synopsis.  Resources are added to the
138 pool by passing a pointer to the pool, the resource block and a
139 destruction function to
140 .BR pool_add .
141 .PP
142 If your resource is freed before the pool is destroyed, manually zero
143 the
144 .B destroy
145 field in the resource header to let the pool manager know not to free
146 the resource again.
147 .PP
148 It's usual to allocate the resource structures from the pool's arena so
149 that they're automatically freed when the pool is destroyed.
150 .PP
151 A
152 .BR subarena (3)
153 may be created for a particular pool by calling
154 .BR pool_subarena .
155 The subarena and its contents will be freed automatically when the pool
156 is destroyed.
157 .PP
158 Files may be opened and registered with a pool by
159 .BR pool_fopen :
160 the
161 .I pool
162 argument specifies which pool, and the
163 .I file
164 and
165 .I how
166 arguments are passed to the standard
167 .BR fopen (3)
168 function.  The return value is a pointer to a
169 .B pool_file
170 structure, containing a member
171 .B fp
172 which is the actual file handle.  Don't call
173 .B fclose
174 directly on the file handle: instead pass the whole structure to
175 .B pool_fclose
176 which will ensure that it doesn't get closed twice by accident.  It's
177 advisable to close files by hand, to prevent the process from running
178 out; it's just not a disaster if you forget by accident.
179 .SH "SEE ALSO"
180 .BR alloc (3),
181 .BR arena (3),
182 .BR mLib (3),
183 .BR subarena (3).
184 .SH AUTHOR
185 Mark Wooding, <mdw@distorted.org.uk>