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