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