xref: /freebsd/contrib/sendmail/libsm/rpool.html (revision ee7b0571c2c18bdec848ed2044223cc88db29bd8)
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 &lt;sm/rpool.h&gt;
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 &lt;= <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 &gt; <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 &lt;= <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