diff options
Diffstat (limited to 'contrib/sendmail/libsm/rpool.html')
-rw-r--r-- | contrib/sendmail/libsm/rpool.html | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/contrib/sendmail/libsm/rpool.html b/contrib/sendmail/libsm/rpool.html new file mode 100644 index 0000000..f796bc0 --- /dev/null +++ b/contrib/sendmail/libsm/rpool.html @@ -0,0 +1,187 @@ +<html> +<head> + <title>libsm : Resource Pools</title> +</head> +<body> + +<a href="index.html">Back to libsm overview</a> + +<center> + <h1> libsm : Resource Pools </h1> + <br> $Id: rpool.html,v 1.4 2000/12/07 17:33:09 dmoen Exp $ +</center> + +<h2> Introduction </h2> + +A resource pool is an object that owns a collection of objects +that can be freed all at once. + +<p> +Resource pools simplify storage management. + +<p> +Resource pools also speed up memory management. +For example, here are some memory allocation statistics from a +run of <tt>`sendmail -q`</tt> that delivered 3 messages: +<blockquote><pre> + 18 1 82 12 87 24 7 42 2 84 + 3046 2 18 13 6 25 89 44 2 88 + 728 3 15 14 2 26 14 48 1 91 + 31 4 9 15 3 27 104 52 3 92 + 103 5 394 16 80 28 8 56 2 96 + 125 6 16 17 1 31 2 60 1 100 + 45 7 14 18 59 32 10 64 9 108 + 130 8 6 19 1 33 6 68 3 135 + 40 9 111 20 7 34 1 72 10 140 + 37 10 7 21 54 36 10 76 + 34 11 4 22 38 40 5 80 +</pre></blockquote> +The second number in each pair is the size of a memory block; the first +number is the number of blocks of that size. We can see that sendmail +allocates large numbers of 2 byte blocks. These memory blocks can be +allocated and freed more quickly using resource pools, because: +<ul> +<li> + When you allocate a small block from a resource pool, the rpool + implementation carves off a chunk of a large preallocated block, + and hands you a pointer to it. +<li> + When you free a resource pool, only a small number of large + blocks need to be freed. +</ul> + +<h2> Synopsis </h2> + +<pre> +#include <sm/rpool.h> + +typedef void (*SM_RPOOL_RFREE_T)(void *rcontext); +typedef struct sm_rpool SM_RPOOL_T; +typedef ... SM_RPOOL_ATTACH_T; + +SM_RPOOL_T * +sm_rpool_new_x( + SM_RPOOL_T *parent); + +void +sm_rpool_free( + SM_RPOOL_T *rpool); + +void * +sm_rpool_malloc_x( + SM_RPOOL_T *rpool, + size_t size); + +SM_RPOOL_ATTACH_T +sm_rpool_attach_x( + SM_RPOOL_T *rpool, + SM_RPOOL_RFREE_T rfree, + void *rcontext); + +void +sm_rpool_detach( + SM_RPOOL_ATTACH_T); + +void +sm_rpool_setsizes( + SM_RPOOL_T *rpool, + size_t poolsize, + size_t bigobjectsize); +</pre> + +<h2> Description </h2> + +<dl> +<dt> +<tt> SM_RPOOL_T *sm_rpool_new_x(SM_RPOOL_T *parent) </tt> +<dd> + Create a new resource pool object. + Raise an exception if there is insufficient heap space. + Initially, no memory is allocated for memory pools or resource lists. + <p> + If parent != NULL then the new rpool will be added as a resource + to the specified parent rpool, so that when the parent is freed, + the child is also freed. However, even if a parent is specified, + you can free the rpool at any time, and it will be automatically + disconnected from the parent. + <p> +<dt> +<tt> void *sm_rpool_malloc_x(SM_RPOOL_T *rpool, size_t size) </tt> +<dd> + Allocate a block of memory from a memory pool owned by the rpool. + Raise an exception if there is insufficient heap space. + A series of small allocation requests can be satisfied allocating + them from the same memory pool, which reduces the number of calls + to malloc. + All of the memory allocated by sm_rpool_malloc_x is freed when + the rpool is freed, and not before then. + <p> +<dt> +<tt> void sm_rpool_setsizes(SM_RPOOL_T *rpool, size_t poolsize, size_t bigobjectsize) </tt> +<dd> + Set memory pool parameters. + You can safely call this function at any time, but an especially + good time to call it is immediately after creating the rpool, + before any pooled objects have been allocated using sm_rpool_malloc_x. + <p> + <tt>poolsize</tt> is the number of bytes of pool memory + that will be available in the next pool object to be allocated. + If you happen to know the total number of bytes of memory that + you will allocate from an rpool using sm_rpool_malloc_x + (including alignment padding), then you can pass that value + as the poolsize, and only a single pool will be allocated + during the lifetime of the rpool. + <tt>poolsize</tt> is an optimization, not a hard limit: + if you allocate more than this number of bytes from the rpool, + then more than one memory pool may be allocated by the rpool + to satisfy your requests. + <p> + <tt>bigobjectsize</tt> is a value <= <tt>poolsize</tt>. + It is used when an <tt>sm_rpool_malloc_x</tt> request exceeds + the number of bytes available in the current pool. + If the request is > <tt>bigobjectsize</tt> then the request + will be satisfied by allocating a new block just for this specific + request, and the current pool is not affected. + If the request is <= <tt>bigobjectsize</tt> then the current + pool is closed and a new memory pool is allocated, from which the + request is satisfied. + Consequently, no more than <tt>bigobjectsize-1</tt> bytes will + ever be wasted at the end of a given pool. + <p> + If poolsize or bigobjectsize are 0, then suitable default values + are chosen. + <p> +<dt> +<tt> SM_RPOOL_ATTACH_T sm_rpool_attach_x(SM_RPOOL_T *rpool, SM_RPOOL_RFREE_T rfree, void *rcontext) </tt> +<dd> + Attach an object to a resource pool, along with its free function. + When the rpool is freed, the specified object will also be freed. + Raise an exception if there is insufficient heap space. + <p> + The return value is a magic cookie which, if passed to + sm_rpool_detach, disconnects the object from the resource pool, + which prevents the object's free function from being called when + the rpool is freed. + <p> +<dt> +<tt> void sm_rpool_detach(SM_RPOOL_ATTACH_T a) </tt> +<dd> + The argument is a magic cookie returned by <tt>sm_rpool_attach_t</tt>, + and refers to the object that was attached to an rpool by a specific + call to <tt>sm_rpool_attach_t</tt>. + Disconnect the object from the resource pool, + which prevents the object's free function from being called when + the rpool is freed. + <p> +<dt> +<tt> void sm_rpool_free(SM_RPOOL_T *rpool) </tt> +<dd> + Free an rpool object. + All memory allocated using sm_rpool_malloc_x + and all objects attached using sm_rpool_attach_x + are freed at this time. + If the rpool has a parent rpool, it is detached from its parent. +</dl> + +</body> +</html> |