140266059SGregory Neil Shapiro<html> 240266059SGregory Neil Shapiro<head> 340266059SGregory Neil Shapiro <title>libsm : Resource Pools</title> 440266059SGregory Neil Shapiro</head> 540266059SGregory Neil Shapiro<body> 640266059SGregory Neil Shapiro 740266059SGregory Neil Shapiro<a href="index.html">Back to libsm overview</a> 840266059SGregory Neil Shapiro 940266059SGregory Neil Shapiro<center> 1040266059SGregory Neil Shapiro <h1> libsm : Resource Pools </h1> 11*4313cc83SGregory Neil Shapiro <br> $Id: rpool.html,v 1.4 2000-12-07 17:33:09 dmoen Exp $ 1240266059SGregory Neil Shapiro</center> 1340266059SGregory Neil Shapiro 1440266059SGregory Neil Shapiro<h2> Introduction </h2> 1540266059SGregory Neil Shapiro 1640266059SGregory Neil ShapiroA resource pool is an object that owns a collection of objects 1740266059SGregory Neil Shapirothat can be freed all at once. 1840266059SGregory Neil Shapiro 1940266059SGregory Neil Shapiro<p> 2040266059SGregory Neil ShapiroResource pools simplify storage management. 2140266059SGregory Neil Shapiro 2240266059SGregory Neil Shapiro<p> 2340266059SGregory Neil ShapiroResource pools also speed up memory management. 2440266059SGregory Neil ShapiroFor example, here are some memory allocation statistics from a 2540266059SGregory Neil Shapirorun of <tt>`sendmail -q`</tt> that delivered 3 messages: 2640266059SGregory Neil Shapiro<blockquote><pre> 2740266059SGregory Neil Shapiro 18 1 82 12 87 24 7 42 2 84 2840266059SGregory Neil Shapiro 3046 2 18 13 6 25 89 44 2 88 2940266059SGregory Neil Shapiro 728 3 15 14 2 26 14 48 1 91 3040266059SGregory Neil Shapiro 31 4 9 15 3 27 104 52 3 92 3140266059SGregory Neil Shapiro 103 5 394 16 80 28 8 56 2 96 3240266059SGregory Neil Shapiro 125 6 16 17 1 31 2 60 1 100 3340266059SGregory Neil Shapiro 45 7 14 18 59 32 10 64 9 108 3440266059SGregory Neil Shapiro 130 8 6 19 1 33 6 68 3 135 3540266059SGregory Neil Shapiro 40 9 111 20 7 34 1 72 10 140 3640266059SGregory Neil Shapiro 37 10 7 21 54 36 10 76 3740266059SGregory Neil Shapiro 34 11 4 22 38 40 5 80 3840266059SGregory Neil Shapiro</pre></blockquote> 3940266059SGregory Neil ShapiroThe second number in each pair is the size of a memory block; the first 4040266059SGregory Neil Shapironumber is the number of blocks of that size. We can see that sendmail 4140266059SGregory Neil Shapiroallocates large numbers of 2 byte blocks. These memory blocks can be 4240266059SGregory Neil Shapiroallocated and freed more quickly using resource pools, because: 4340266059SGregory Neil Shapiro<ul> 4440266059SGregory Neil Shapiro<li> 4540266059SGregory Neil Shapiro When you allocate a small block from a resource pool, the rpool 4640266059SGregory Neil Shapiro implementation carves off a chunk of a large preallocated block, 4740266059SGregory Neil Shapiro and hands you a pointer to it. 4840266059SGregory Neil Shapiro<li> 4940266059SGregory Neil Shapiro When you free a resource pool, only a small number of large 5040266059SGregory Neil Shapiro blocks need to be freed. 5140266059SGregory Neil Shapiro</ul> 5240266059SGregory Neil Shapiro 5340266059SGregory Neil Shapiro<h2> Synopsis </h2> 5440266059SGregory Neil Shapiro 5540266059SGregory Neil Shapiro<pre> 5640266059SGregory Neil Shapiro#include <sm/rpool.h> 5740266059SGregory Neil Shapiro 5840266059SGregory Neil Shapirotypedef void (*SM_RPOOL_RFREE_T)(void *rcontext); 5940266059SGregory Neil Shapirotypedef struct sm_rpool SM_RPOOL_T; 6040266059SGregory Neil Shapirotypedef ... SM_RPOOL_ATTACH_T; 6140266059SGregory Neil Shapiro 6240266059SGregory Neil ShapiroSM_RPOOL_T * 6340266059SGregory Neil Shapirosm_rpool_new_x( 6440266059SGregory Neil Shapiro SM_RPOOL_T *parent); 6540266059SGregory Neil Shapiro 6640266059SGregory Neil Shapirovoid 6740266059SGregory Neil Shapirosm_rpool_free( 6840266059SGregory Neil Shapiro SM_RPOOL_T *rpool); 6940266059SGregory Neil Shapiro 7040266059SGregory Neil Shapirovoid * 7140266059SGregory Neil Shapirosm_rpool_malloc_x( 7240266059SGregory Neil Shapiro SM_RPOOL_T *rpool, 7340266059SGregory Neil Shapiro size_t size); 7440266059SGregory Neil Shapiro 7540266059SGregory Neil ShapiroSM_RPOOL_ATTACH_T 7640266059SGregory Neil Shapirosm_rpool_attach_x( 7740266059SGregory Neil Shapiro SM_RPOOL_T *rpool, 7840266059SGregory Neil Shapiro SM_RPOOL_RFREE_T rfree, 7940266059SGregory Neil Shapiro void *rcontext); 8040266059SGregory Neil Shapiro 8140266059SGregory Neil Shapirovoid 8240266059SGregory Neil Shapirosm_rpool_detach( 8340266059SGregory Neil Shapiro SM_RPOOL_ATTACH_T); 8440266059SGregory Neil Shapiro 8540266059SGregory Neil Shapirovoid 8640266059SGregory Neil Shapirosm_rpool_setsizes( 8740266059SGregory Neil Shapiro SM_RPOOL_T *rpool, 8840266059SGregory Neil Shapiro size_t poolsize, 8940266059SGregory Neil Shapiro size_t bigobjectsize); 9040266059SGregory Neil Shapiro</pre> 9140266059SGregory Neil Shapiro 9240266059SGregory Neil Shapiro<h2> Description </h2> 9340266059SGregory Neil Shapiro 9440266059SGregory Neil Shapiro<dl> 9540266059SGregory Neil Shapiro<dt> 9640266059SGregory Neil Shapiro<tt> SM_RPOOL_T *sm_rpool_new_x(SM_RPOOL_T *parent) </tt> 9740266059SGregory Neil Shapiro<dd> 9840266059SGregory Neil Shapiro Create a new resource pool object. 9940266059SGregory Neil Shapiro Raise an exception if there is insufficient heap space. 10040266059SGregory Neil Shapiro Initially, no memory is allocated for memory pools or resource lists. 10140266059SGregory Neil Shapiro <p> 10240266059SGregory Neil Shapiro If parent != NULL then the new rpool will be added as a resource 10340266059SGregory Neil Shapiro to the specified parent rpool, so that when the parent is freed, 10440266059SGregory Neil Shapiro the child is also freed. However, even if a parent is specified, 10540266059SGregory Neil Shapiro you can free the rpool at any time, and it will be automatically 10640266059SGregory Neil Shapiro disconnected from the parent. 10740266059SGregory Neil Shapiro <p> 10840266059SGregory Neil Shapiro<dt> 10940266059SGregory Neil Shapiro<tt> void *sm_rpool_malloc_x(SM_RPOOL_T *rpool, size_t size) </tt> 11040266059SGregory Neil Shapiro<dd> 11140266059SGregory Neil Shapiro Allocate a block of memory from a memory pool owned by the rpool. 11240266059SGregory Neil Shapiro Raise an exception if there is insufficient heap space. 11340266059SGregory Neil Shapiro A series of small allocation requests can be satisfied allocating 11440266059SGregory Neil Shapiro them from the same memory pool, which reduces the number of calls 11540266059SGregory Neil Shapiro to malloc. 11640266059SGregory Neil Shapiro All of the memory allocated by sm_rpool_malloc_x is freed when 11740266059SGregory Neil Shapiro the rpool is freed, and not before then. 11840266059SGregory Neil Shapiro <p> 11940266059SGregory Neil Shapiro<dt> 12040266059SGregory Neil Shapiro<tt> void sm_rpool_setsizes(SM_RPOOL_T *rpool, size_t poolsize, size_t bigobjectsize) </tt> 12140266059SGregory Neil Shapiro<dd> 12240266059SGregory Neil Shapiro Set memory pool parameters. 12340266059SGregory Neil Shapiro You can safely call this function at any time, but an especially 12440266059SGregory Neil Shapiro good time to call it is immediately after creating the rpool, 12540266059SGregory Neil Shapiro before any pooled objects have been allocated using sm_rpool_malloc_x. 12640266059SGregory Neil Shapiro <p> 12740266059SGregory Neil Shapiro <tt>poolsize</tt> is the number of bytes of pool memory 12840266059SGregory Neil Shapiro that will be available in the next pool object to be allocated. 12940266059SGregory Neil Shapiro If you happen to know the total number of bytes of memory that 13040266059SGregory Neil Shapiro you will allocate from an rpool using sm_rpool_malloc_x 13140266059SGregory Neil Shapiro (including alignment padding), then you can pass that value 13240266059SGregory Neil Shapiro as the poolsize, and only a single pool will be allocated 13340266059SGregory Neil Shapiro during the lifetime of the rpool. 13440266059SGregory Neil Shapiro <tt>poolsize</tt> is an optimization, not a hard limit: 13540266059SGregory Neil Shapiro if you allocate more than this number of bytes from the rpool, 13640266059SGregory Neil Shapiro then more than one memory pool may be allocated by the rpool 13740266059SGregory Neil Shapiro to satisfy your requests. 13840266059SGregory Neil Shapiro <p> 13940266059SGregory Neil Shapiro <tt>bigobjectsize</tt> is a value <= <tt>poolsize</tt>. 14040266059SGregory Neil Shapiro It is used when an <tt>sm_rpool_malloc_x</tt> request exceeds 14140266059SGregory Neil Shapiro the number of bytes available in the current pool. 14240266059SGregory Neil Shapiro If the request is > <tt>bigobjectsize</tt> then the request 14340266059SGregory Neil Shapiro will be satisfied by allocating a new block just for this specific 14440266059SGregory Neil Shapiro request, and the current pool is not affected. 14540266059SGregory Neil Shapiro If the request is <= <tt>bigobjectsize</tt> then the current 14640266059SGregory Neil Shapiro pool is closed and a new memory pool is allocated, from which the 14740266059SGregory Neil Shapiro request is satisfied. 14840266059SGregory Neil Shapiro Consequently, no more than <tt>bigobjectsize-1</tt> bytes will 14940266059SGregory Neil Shapiro ever be wasted at the end of a given pool. 15040266059SGregory Neil Shapiro <p> 15140266059SGregory Neil Shapiro If poolsize or bigobjectsize are 0, then suitable default values 15240266059SGregory Neil Shapiro are chosen. 15340266059SGregory Neil Shapiro <p> 15440266059SGregory Neil Shapiro<dt> 15540266059SGregory Neil Shapiro<tt> SM_RPOOL_ATTACH_T sm_rpool_attach_x(SM_RPOOL_T *rpool, SM_RPOOL_RFREE_T rfree, void *rcontext) </tt> 15640266059SGregory Neil Shapiro<dd> 15740266059SGregory Neil Shapiro Attach an object to a resource pool, along with its free function. 15840266059SGregory Neil Shapiro When the rpool is freed, the specified object will also be freed. 15940266059SGregory Neil Shapiro Raise an exception if there is insufficient heap space. 16040266059SGregory Neil Shapiro <p> 16140266059SGregory Neil Shapiro The return value is a magic cookie which, if passed to 16240266059SGregory Neil Shapiro sm_rpool_detach, disconnects the object from the resource pool, 16340266059SGregory Neil Shapiro which prevents the object's free function from being called when 16440266059SGregory Neil Shapiro the rpool is freed. 16540266059SGregory Neil Shapiro <p> 16640266059SGregory Neil Shapiro<dt> 16740266059SGregory Neil Shapiro<tt> void sm_rpool_detach(SM_RPOOL_ATTACH_T a) </tt> 16840266059SGregory Neil Shapiro<dd> 16940266059SGregory Neil Shapiro The argument is a magic cookie returned by <tt>sm_rpool_attach_t</tt>, 17040266059SGregory Neil Shapiro and refers to the object that was attached to an rpool by a specific 17140266059SGregory Neil Shapiro call to <tt>sm_rpool_attach_t</tt>. 17240266059SGregory Neil Shapiro Disconnect the object from the resource pool, 17340266059SGregory Neil Shapiro which prevents the object's free function from being called when 17440266059SGregory Neil Shapiro the rpool is freed. 17540266059SGregory Neil Shapiro <p> 17640266059SGregory Neil Shapiro<dt> 17740266059SGregory Neil Shapiro<tt> void sm_rpool_free(SM_RPOOL_T *rpool) </tt> 17840266059SGregory Neil Shapiro<dd> 17940266059SGregory Neil Shapiro Free an rpool object. 18040266059SGregory Neil Shapiro All memory allocated using sm_rpool_malloc_x 18140266059SGregory Neil Shapiro and all objects attached using sm_rpool_attach_x 18240266059SGregory Neil Shapiro are freed at this time. 18340266059SGregory Neil Shapiro If the rpool has a parent rpool, it is detached from its parent. 18440266059SGregory Neil Shapiro</dl> 18540266059SGregory Neil Shapiro 18640266059SGregory Neil Shapiro</body> 18740266059SGregory Neil Shapiro</html> 188