| 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" mLib |
| 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> |