1<html> 2<head> 3 <title>libsm : Resource Pools</title> 4</head> 5<body> 6 7<a href="index.html">Back to libsm overview</a> 8 9<center> 10 <h1> libsm : Resource Pools </h1> 11 <br> $Id: rpool.html,v 1.1.1.1 2002/02/17 21:56:43 gshapiro Exp $ 12</center> 13 14<h2> Introduction </h2> 15 16A resource pool is an object that owns a collection of objects 17that can be freed all at once. 18 19<p> 20Resource pools simplify storage management. 21 22<p> 23Resource pools also speed up memory management. 24For example, here are some memory allocation statistics from a 25run of <tt>`sendmail -q`</tt> that delivered 3 messages: 26<blockquote><pre> 27 18 1 82 12 87 24 7 42 2 84 28 3046 2 18 13 6 25 89 44 2 88 29 728 3 15 14 2 26 14 48 1 91 30 31 4 9 15 3 27 104 52 3 92 31 103 5 394 16 80 28 8 56 2 96 32 125 6 16 17 1 31 2 60 1 100 33 45 7 14 18 59 32 10 64 9 108 34 130 8 6 19 1 33 6 68 3 135 35 40 9 111 20 7 34 1 72 10 140 36 37 10 7 21 54 36 10 76 37 34 11 4 22 38 40 5 80 38</pre></blockquote> 39The second number in each pair is the size of a memory block; the first 40number is the number of blocks of that size. We can see that sendmail 41allocates large numbers of 2 byte blocks. These memory blocks can be 42allocated and freed more quickly using resource pools, because: 43<ul> 44<li> 45 When you allocate a small block from a resource pool, the rpool 46 implementation carves off a chunk of a large preallocated block, 47 and hands you a pointer to it. 48<li> 49 When you free a resource pool, only a small number of large 50 blocks need to be freed. 51</ul> 52 53<h2> Synopsis </h2> 54 55<pre> 56#include <sm/rpool.h> 57 58typedef void (*SM_RPOOL_RFREE_T)(void *rcontext); 59typedef struct sm_rpool SM_RPOOL_T; 60typedef ... SM_RPOOL_ATTACH_T; 61 62SM_RPOOL_T * 63sm_rpool_new_x( 64 SM_RPOOL_T *parent); 65 66void 67sm_rpool_free( 68 SM_RPOOL_T *rpool); 69 70void * 71sm_rpool_malloc_x( 72 SM_RPOOL_T *rpool, 73 size_t size); 74 75SM_RPOOL_ATTACH_T 76sm_rpool_attach_x( 77 SM_RPOOL_T *rpool, 78 SM_RPOOL_RFREE_T rfree, 79 void *rcontext); 80 81void 82sm_rpool_detach( 83 SM_RPOOL_ATTACH_T); 84 85void 86sm_rpool_setsizes( 87 SM_RPOOL_T *rpool, 88 size_t poolsize, 89 size_t bigobjectsize); 90</pre> 91 92<h2> Description </h2> 93 94<dl> 95<dt> 96<tt> SM_RPOOL_T *sm_rpool_new_x(SM_RPOOL_T *parent) </tt> 97<dd> 98 Create a new resource pool object. 99 Raise an exception if there is insufficient heap space. 100 Initially, no memory is allocated for memory pools or resource lists. 101 <p> 102 If parent != NULL then the new rpool will be added as a resource 103 to the specified parent rpool, so that when the parent is freed, 104 the child is also freed. However, even if a parent is specified, 105 you can free the rpool at any time, and it will be automatically 106 disconnected from the parent. 107 <p> 108<dt> 109<tt> void *sm_rpool_malloc_x(SM_RPOOL_T *rpool, size_t size) </tt> 110<dd> 111 Allocate a block of memory from a memory pool owned by the rpool. 112 Raise an exception if there is insufficient heap space. 113 A series of small allocation requests can be satisfied allocating 114 them from the same memory pool, which reduces the number of calls 115 to malloc. 116 All of the memory allocated by sm_rpool_malloc_x is freed when 117 the rpool is freed, and not before then. 118 <p> 119<dt> 120<tt> void sm_rpool_setsizes(SM_RPOOL_T *rpool, size_t poolsize, size_t bigobjectsize) </tt> 121<dd> 122 Set memory pool parameters. 123 You can safely call this function at any time, but an especially 124 good time to call it is immediately after creating the rpool, 125 before any pooled objects have been allocated using sm_rpool_malloc_x. 126 <p> 127 <tt>poolsize</tt> is the number of bytes of pool memory 128 that will be available in the next pool object to be allocated. 129 If you happen to know the total number of bytes of memory that 130 you will allocate from an rpool using sm_rpool_malloc_x 131 (including alignment padding), then you can pass that value 132 as the poolsize, and only a single pool will be allocated 133 during the lifetime of the rpool. 134 <tt>poolsize</tt> is an optimization, not a hard limit: 135 if you allocate more than this number of bytes from the rpool, 136 then more than one memory pool may be allocated by the rpool 137 to satisfy your requests. 138 <p> 139 <tt>bigobjectsize</tt> is a value <= <tt>poolsize</tt>. 140 It is used when an <tt>sm_rpool_malloc_x</tt> request exceeds 141 the number of bytes available in the current pool. 142 If the request is > <tt>bigobjectsize</tt> then the request 143 will be satisfied by allocating a new block just for this specific 144 request, and the current pool is not affected. 145 If the request is <= <tt>bigobjectsize</tt> then the current 146 pool is closed and a new memory pool is allocated, from which the 147 request is satisfied. 148 Consequently, no more than <tt>bigobjectsize-1</tt> bytes will 149 ever be wasted at the end of a given pool. 150 <p> 151 If poolsize or bigobjectsize are 0, then suitable default values 152 are chosen. 153 <p> 154<dt> 155<tt> SM_RPOOL_ATTACH_T sm_rpool_attach_x(SM_RPOOL_T *rpool, SM_RPOOL_RFREE_T rfree, void *rcontext) </tt> 156<dd> 157 Attach an object to a resource pool, along with its free function. 158 When the rpool is freed, the specified object will also be freed. 159 Raise an exception if there is insufficient heap space. 160 <p> 161 The return value is a magic cookie which, if passed to 162 sm_rpool_detach, disconnects the object from the resource pool, 163 which prevents the object's free function from being called when 164 the rpool is freed. 165 <p> 166<dt> 167<tt> void sm_rpool_detach(SM_RPOOL_ATTACH_T a) </tt> 168<dd> 169 The argument is a magic cookie returned by <tt>sm_rpool_attach_t</tt>, 170 and refers to the object that was attached to an rpool by a specific 171 call to <tt>sm_rpool_attach_t</tt>. 172 Disconnect the object from the resource pool, 173 which prevents the object's free function from being called when 174 the rpool is freed. 175 <p> 176<dt> 177<tt> void sm_rpool_free(SM_RPOOL_T *rpool) </tt> 178<dd> 179 Free an rpool object. 180 All memory allocated using sm_rpool_malloc_x 181 and all objects attached using sm_rpool_attach_x 182 are freed at this time. 183 If the rpool has a parent rpool, it is detached from its parent. 184</dl> 185 186</body> 187</html> 188