xref: /freebsd/contrib/sendmail/libsm/rpool.html (revision 4436b51dff5736e74da464946049ea6899a88938)
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.4 2000-12-07 17:33:09 dmoen 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 &lt;sm/rpool.h&gt;
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 &lt;= <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 &gt; <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 &lt;= <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