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 2003-04-08 15:11:42 zacheiss Exp $ |
---|
12 | </center> |
---|
13 | |
---|
14 | <h2> Introduction </h2> |
---|
15 | |
---|
16 | A resource pool is an object that owns a collection of objects |
---|
17 | that can be freed all at once. |
---|
18 | |
---|
19 | <p> |
---|
20 | Resource pools simplify storage management. |
---|
21 | |
---|
22 | <p> |
---|
23 | Resource pools also speed up memory management. |
---|
24 | For example, here are some memory allocation statistics from a |
---|
25 | run 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> |
---|
39 | The second number in each pair is the size of a memory block; the first |
---|
40 | number is the number of blocks of that size. We can see that sendmail |
---|
41 | allocates large numbers of 2 byte blocks. These memory blocks can be |
---|
42 | allocated 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 | |
---|
58 | typedef void (*SM_RPOOL_RFREE_T)(void *rcontext); |
---|
59 | typedef struct sm_rpool SM_RPOOL_T; |
---|
60 | typedef ... SM_RPOOL_ATTACH_T; |
---|
61 | |
---|
62 | SM_RPOOL_T * |
---|
63 | sm_rpool_new_x( |
---|
64 | SM_RPOOL_T *parent); |
---|
65 | |
---|
66 | void |
---|
67 | sm_rpool_free( |
---|
68 | SM_RPOOL_T *rpool); |
---|
69 | |
---|
70 | void * |
---|
71 | sm_rpool_malloc_x( |
---|
72 | SM_RPOOL_T *rpool, |
---|
73 | size_t size); |
---|
74 | |
---|
75 | SM_RPOOL_ATTACH_T |
---|
76 | sm_rpool_attach_x( |
---|
77 | SM_RPOOL_T *rpool, |
---|
78 | SM_RPOOL_RFREE_T rfree, |
---|
79 | void *rcontext); |
---|
80 | |
---|
81 | void |
---|
82 | sm_rpool_detach( |
---|
83 | SM_RPOOL_ATTACH_T); |
---|
84 | |
---|
85 | void |
---|
86 | sm_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> |
---|