[DAPL2] sync with WinOF 2.1 branch
[mirror/winof/.git] / inc / complib / cl_pool.h
1 /*\r
2  * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
3  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. \r
4  *\r
5  * This software is available to you under the OpenIB.org BSD license\r
6  * below:\r
7  *\r
8  *     Redistribution and use in source and binary forms, with or\r
9  *     without modification, are permitted provided that the following\r
10  *     conditions are met:\r
11  *\r
12  *      - Redistributions of source code must retain the above\r
13  *        copyright notice, this list of conditions and the following\r
14  *        disclaimer.\r
15  *\r
16  *      - Redistributions in binary form must reproduce the above\r
17  *        copyright notice, this list of conditions and the following\r
18  *        disclaimer in the documentation and/or other materials\r
19  *        provided with the distribution.\r
20  *\r
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
22  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
23  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
24  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
25  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
26  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
27  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
28  * SOFTWARE.\r
29  *\r
30  * $Id$\r
31  */\r
32 \r
33 \r
34 /*\r
35  * Abstract:\r
36  *      Declaration of the pool.\r
37  *      The pool manages a pool of objects.\r
38  *      The pool can grow to meet demand, limited only by system memory.\r
39  *\r
40  * Environment:\r
41  *      All\r
42  */\r
43 \r
44 \r
45 #ifndef _CL_POOL_H_\r
46 #define _CL_POOL_H_\r
47 \r
48 \r
49 #include <complib/cl_qcomppool.h>\r
50 \r
51 \r
52 /****h* Component Library/Pool\r
53 * NAME\r
54 *       Pool\r
55 *\r
56 * DESCRIPTION\r
57 *       The pool provides a self-contained and self-sustaining pool\r
58 *       of user defined objects.\r
59 *\r
60 *       To aid in object oriented design, the pool provides the user\r
61 *       the ability to specify callbacks that are invoked for each object for\r
62 *       construction, initialization, and destruction. Constructor and destructor\r
63 *       callback functions may not fail.\r
64 *\r
65 *       A pool does not return memory to the system as the user returns\r
66 *       objects to the pool. The only method of returning memory to the system is\r
67 *       to destroy the pool.\r
68 *\r
69 *       The Pool functions operate on a cl_pool_t structure which should be treated\r
70 *       as opaque and should be manipulated only through the provided functions.\r
71 *\r
72 * SEE ALSO\r
73 *       Structures:\r
74 *               cl_pool_t\r
75 *\r
76 *       Callbacks:\r
77 *               cl_pfn_pool_init_t, cl_pfn_pool_dtor_t\r
78 *\r
79 *       Initialization/Destruction:\r
80 *               cl_pool_construct, cl_pool_init, cl_pool_destroy\r
81 *\r
82 *       Manipulation:\r
83 *               cl_pool_get, cl_pool_put, cl_pool_grow\r
84 *\r
85 *       Attributes:\r
86 *               cl_is_pool_inited, cl_pool_count\r
87 *********/\r
88 \r
89 \r
90 /****d* Component Library: Pool/cl_pfn_pool_init_t\r
91 * NAME\r
92 *       cl_pfn_pool_init_t\r
93 *\r
94 * DESCRIPTION\r
95 *       The cl_pfn_pool_init_t function type defines the prototype for\r
96 *       functions used as initializers for objects being allocated by a\r
97 *       pool.\r
98 *\r
99 * SYNOPSIS\r
100 */\r
101 typedef cl_status_t\r
102 (CL_API *cl_pfn_pool_init_t)(\r
103         IN      void* const                     p_object,\r
104         IN      void*                           context );\r
105 /*\r
106 * PARAMETERS\r
107 *       p_object\r
108 *               [in] Pointer to an object to initialize.\r
109 *\r
110 *       context\r
111 *               [in] Context provided in a call to cl_pool_init.\r
112 *\r
113 * RETURN VALUES\r
114 *       Return CL_SUCCESS to indicates that initialization of the object\r
115 *       was successful and initialization of further objects may continue.\r
116 *\r
117 *       Other cl_status_t values will be returned by cl_pool_init\r
118 *       and cl_pool_grow.\r
119 *\r
120 * NOTES\r
121 *       This function type is provided as function prototype reference for\r
122 *       the function provided by the user as an optional parameter to the\r
123 *       cl_pool_init function.\r
124 *\r
125 *       The initializer is invoked once per allocated object, allowing the user\r
126 *       to trap initialization failures. Returning a status other than CL_SUCCESS\r
127 *       aborts a grow operation, initiated either through cl_pool_init or\r
128 *       cl_pool_grow, and causes the initiating function to fail.\r
129 *       Any non-CL_SUCCESS status will be returned by the function that initiated\r
130 *       the grow operation.\r
131 *\r
132 * SEE ALSO\r
133 *       Pool, cl_pool_init, cl_pool_grow\r
134 *********/\r
135 \r
136 \r
137 /****d* Component Library: Pool/cl_pfn_pool_dtor_t\r
138 * NAME\r
139 *       cl_pfn_pool_dtor_t\r
140 *\r
141 * DESCRIPTION\r
142 *       The cl_pfn_pool_dtor_t function type defines the prototype for\r
143 *       functions used as destructor for objects being deallocated by a\r
144 *       pool.\r
145 *\r
146 * SYNOPSIS\r
147 */\r
148 typedef void\r
149 (CL_API *cl_pfn_pool_dtor_t)(\r
150         IN      void* const                     p_object,\r
151         IN      void*                           context );\r
152 /*\r
153 * PARAMETERS\r
154 *       p_object\r
155 *               [in] Pointer to an object to destruct.\r
156 *\r
157 *       context\r
158 *               [in] Context provided in the call to cl_pool_init.\r
159 *\r
160 * RETURN VALUE\r
161 *       This function does not return a value.\r
162 *\r
163 * NOTES\r
164 *       This function type is provided as function prototype reference for\r
165 *       the function provided by the user as an optional parameter to the\r
166 *       cl_pool_init function.\r
167 *\r
168 *       The destructor is invoked once per allocated object, allowing the user\r
169 *       to perform any necessary cleanup. Users should not attempt to deallocate\r
170 *       the memory for the object, as the pool manages object\r
171 *       allocation and deallocation.\r
172 *\r
173 * SEE ALSO\r
174 *       Pool, cl_pool_init\r
175 *********/\r
176 \r
177 \r
178 /****s* Component Library: Pool/cl_pool_t\r
179 * NAME\r
180 *       cl_pool_t\r
181 *\r
182 * DESCRIPTION\r
183 *       pool structure.\r
184 *\r
185 *       The cl_pool_t structure should be treated as opaque and should be\r
186 *       manipulated only through the provided functions.\r
187 *\r
188 * SYNOPSIS\r
189 */\r
190 typedef struct _cl_pool\r
191 {\r
192         cl_qcpool_t                             qcpool;\r
193         cl_pfn_pool_init_t              pfn_init;\r
194         cl_pfn_pool_dtor_t              pfn_dtor;\r
195         const void                              *context;\r
196 \r
197 } cl_pool_t;\r
198 /*\r
199 * FIELDS\r
200 *       qcpool\r
201 *               Quick composite pool that manages all objects.\r
202 *\r
203 *       pfn_init\r
204 *               Pointer to the user's initializer callback, used by the pool\r
205 *               to translate the quick composite pool's initializer callback to\r
206 *               a pool initializer callback.\r
207 *\r
208 *       pfn_dtor\r
209 *               Pointer to the user's destructor callback, used by the pool\r
210 *               to translate the quick composite pool's destructor callback to\r
211 *               a pool destructor callback.\r
212 *\r
213 *       context\r
214 *               User's provided context for callback functions, used by the pool\r
215 *               to when invoking callbacks.\r
216 *\r
217 * SEE ALSO\r
218 *       Pool\r
219 *********/\r
220 \r
221 \r
222 #ifdef __cplusplus\r
223 extern "C"\r
224 {\r
225 #endif  /* __cplusplus */\r
226 \r
227 \r
228 /****f* Component Library: Pool/cl_pool_construct\r
229 * NAME\r
230 *       cl_pool_construct\r
231 *\r
232 * DESCRIPTION\r
233 *       The cl_pool_construct function constructs a pool.\r
234 *\r
235 * SYNOPSIS\r
236 */\r
237 CL_EXPORT void CL_API\r
238 cl_pool_construct(\r
239         IN      cl_pool_t* const        p_pool );\r
240 /*\r
241 * PARAMETERS\r
242 *       p_pool\r
243 *               [in] Pointer to a cl_pool_t structure whose state to initialize.\r
244 *\r
245 * RETURN VALUE\r
246 *       This function does not return a value.\r
247 *\r
248 * NOTES\r
249 *       Allows calling cl_pool_init, cl_pool_destroy, and cl_is_pool_inited.\r
250 *\r
251 *       Calling cl_pool_construct is a prerequisite to calling any other\r
252 *       pool function except cl_pool_init.\r
253 *\r
254 * SEE ALSO\r
255 *       Pool, cl_pool_init, cl_pool_destroy, cl_is_pool_inited\r
256 *********/\r
257 \r
258 \r
259 /****f* Component Library: Pool/cl_is_pool_inited\r
260 * NAME\r
261 *       cl_is_pool_inited\r
262 *\r
263 * DESCRIPTION\r
264 *       The cl_is_pool_inited function returns whether a pool was successfully\r
265 *       initialized.\r
266 *\r
267 * SYNOPSIS\r
268 */\r
269 CL_INLINE uint32_t CL_API\r
270 cl_is_pool_inited(\r
271         IN      const cl_pool_t* const  p_pool )\r
272 {\r
273         /* CL_ASSERT that a non-null pointer is provided. */\r
274         CL_ASSERT( p_pool );\r
275         return( cl_is_qcpool_inited( &p_pool->qcpool ) );\r
276 }\r
277 /*\r
278 * PARAMETERS\r
279 *       p_pool\r
280 *               [in] Pointer to a cl_pool_t structure whose initialization state\r
281 *               to check.\r
282 *\r
283 * RETURN VALUES\r
284 *       TRUE if the pool was initialized successfully.\r
285 *\r
286 *       FALSE otherwise.\r
287 *\r
288 * NOTES\r
289 *       Allows checking the state of a pool to determine if invoking member\r
290 *       functions is appropriate.\r
291 *\r
292 * SEE ALSO\r
293 *       Pool\r
294 *********/\r
295 \r
296 \r
297 /****f* Component Library: Pool/cl_pool_init\r
298 * NAME\r
299 *       cl_pool_init\r
300 *\r
301 * DESCRIPTION\r
302 *       The cl_pool_init function initializes a pool for use.\r
303 *\r
304 * SYNOPSIS\r
305 */\r
306 CL_EXPORT cl_status_t CL_API\r
307 cl_pool_init(\r
308         IN      cl_pool_t* const                p_pool,\r
309         IN      const size_t                    min_count,\r
310         IN      const size_t                    max_count,\r
311         IN      const size_t                    grow_size,\r
312         IN      const size_t                    object_size,\r
313         IN      cl_pfn_pool_init_t              pfn_initializer OPTIONAL,\r
314         IN      cl_pfn_pool_dtor_t              pfn_destructor OPTIONAL,\r
315         IN      const void* const               context );\r
316 /*\r
317 * PARAMETERS\r
318 *       p_pool\r
319 *               [in] Pointer to a cl_pool_t structure to initialize.\r
320 *\r
321 *       min_count\r
322 *               [in] Minimum number of objects that the pool should support. All\r
323 *               necessary allocations to allow storing the minimum number of items\r
324 *               are performed at initialization time, and all necessary callbacks\r
325 *               invoked.\r
326 *\r
327 *       max_count\r
328 *               [in] Maximum number of objects to which the pool is allowed to grow.\r
329 *               A value of zero specifies no maximum.\r
330 *\r
331 *       grow_size\r
332 *               [in] Number of objects to allocate when incrementally growing the pool.\r
333 *               A value of zero disables automatic growth.\r
334 *\r
335 *       object_size\r
336 *               [in] Size, in bytes, of each object.\r
337 *\r
338 *       pfn_initializer\r
339 *               [in] Initialization callback to invoke for every new object when\r
340 *               growing the pool. This parameter is optional and may be NULL.\r
341 *               See the cl_pfn_pool_init_t function type declaration for details\r
342 *               about the callback function.\r
343 *\r
344 *       pfn_destructor\r
345 *               [in] Destructor callback to invoke for every object before memory for\r
346 *               that object is freed. This parameter is optional and may be NULL.\r
347 *               See the cl_pfn_pool_dtor_t function type declaration for details\r
348 *               about the callback function.\r
349 *\r
350 *       context\r
351 *               [in] Value to pass to the callback functions to provide context.\r
352 *\r
353 * RETURN VALUES\r
354 *       CL_SUCCESS if the pool was initialized successfully.\r
355 *\r
356 *       CL_INSUFFICIENT_MEMORY if there was not enough memory to initialize the\r
357 *       pool.\r
358 *\r
359 *       CL_INVALID_SETTING if a the maximum size is non-zero and less than the\r
360 *       minimum size.\r
361 *\r
362 *       Other cl_status_t value returned by optional initialization callback function\r
363 *       specified by the pfn_initializer parameter.\r
364 *\r
365 * NOTES\r
366 *       cl_pool_init initializes, and if necessary, grows the pool to\r
367 *       the capacity desired.\r
368 *\r
369 * SEE ALSO\r
370 *       Pool, cl_pool_construct, cl_pool_destroy,\r
371 *       cl_pool_get, cl_pool_put, cl_pool_grow,\r
372 *       cl_pool_count, cl_pfn_pool_init_t, cl_pfn_pool_dtor_t\r
373 *********/\r
374 \r
375 \r
376 /****f* Component Library: Pool/cl_pool_destroy\r
377 * NAME\r
378 *       cl_pool_destroy\r
379 *\r
380 * DESCRIPTION\r
381 *       The cl_pool_destroy function destroys a pool.\r
382 *\r
383 * SYNOPSIS\r
384 */\r
385 CL_INLINE void CL_API\r
386 cl_pool_destroy(\r
387         IN      cl_pool_t* const        p_pool )\r
388 {\r
389         CL_ASSERT( p_pool );\r
390         cl_qcpool_destroy( &p_pool->qcpool );\r
391 }\r
392 /*\r
393 * PARAMETERS\r
394 *       p_pool\r
395 *               [in] Pointer to a cl_pool_t structure to destroy.\r
396 *\r
397 * RETURN VALUE\r
398 *       This function does not return a value.\r
399 *\r
400 * NOTES\r
401 *       All memory allocated for objects is freed. The destructor callback,\r
402 *       if any, will be invoked for every allocated object. Further operations\r
403 *       on the pool should not be attempted after cl_pool_destroy\r
404 *       is invoked.\r
405 *\r
406 *       This function should only be called after a call to\r
407 *       cl_pool_construct or cl_pool_init.\r
408 *\r
409 *       In a debug build, cl_pool_destroy asserts that all objects are in\r
410 *       the pool.\r
411 *\r
412 * SEE ALSO\r
413 *       Pool, cl_pool_construct, cl_pool_init\r
414 *********/\r
415 \r
416 \r
417 /****f* Component Library: Pool/cl_pool_count\r
418 * NAME\r
419 *       cl_pool_count\r
420 *\r
421 * DESCRIPTION\r
422 *       The cl_pool_count function returns the number of available objects\r
423 *       in a pool.\r
424 *\r
425 * SYNOPSIS\r
426 */\r
427 CL_INLINE size_t CL_API\r
428 cl_pool_count(\r
429         IN      cl_pool_t* const        p_pool )\r
430 {\r
431         CL_ASSERT( p_pool );\r
432         return( cl_qcpool_count( &p_pool->qcpool ) );\r
433 }\r
434 /*\r
435 * PARAMETERS\r
436 *       p_pool\r
437 *               [in] Pointer to a cl_pool_t structure for which the number of\r
438 *               available objects is requested.\r
439 *\r
440 * RETURN VALUE\r
441 *       Returns the number of objects available in the specified pool.\r
442 *\r
443 * SEE ALSO\r
444 *       Pool\r
445 *********/\r
446 \r
447 \r
448 /****f* Component Library: Pool/cl_pool_get\r
449 * NAME\r
450 *       cl_pool_get\r
451 *\r
452 * DESCRIPTION\r
453 *       The cl_pool_get function retrieves an object from a pool.\r
454 *\r
455 * SYNOPSIS\r
456 */\r
457 CL_INLINE void* CL_API\r
458 cl_pool_get(\r
459         IN      cl_pool_t* const        p_pool )\r
460 {\r
461         cl_pool_obj_t   *p_pool_obj;\r
462 \r
463         CL_ASSERT( p_pool );\r
464 \r
465         p_pool_obj = (cl_pool_obj_t*)cl_qcpool_get( &p_pool->qcpool );\r
466         if( !p_pool_obj )\r
467                 return( NULL );\r
468 \r
469         CL_ASSERT( p_pool_obj->list_obj.p_object );\r
470         return( (void*)p_pool_obj->list_obj.p_object );\r
471 }\r
472 /*\r
473 * PARAMETERS\r
474 *       p_pool\r
475 *               [in] Pointer to a cl_pool_t structure from which to retrieve\r
476 *               an object.\r
477 *\r
478 * RETURN VALUES\r
479 *       Returns a pointer to an object.\r
480 *\r
481 *       Returns NULL if the pool is empty and can not be grown automatically.\r
482 *\r
483 * NOTES\r
484 *       cl_pool_get returns the object at the head of the pool. If the pool is\r
485 *       empty, it is automatically grown to accommodate this request unless the\r
486 *       grow_size parameter passed to the cl_pool_init function was zero.\r
487 *\r
488 * SEE ALSO\r
489 *       Pool, cl_pool_get_tail, cl_pool_put, cl_pool_grow, cl_pool_count\r
490 *********/\r
491 \r
492 \r
493 /****f* Component Library: Pool/cl_pool_put\r
494 * NAME\r
495 *       cl_pool_put\r
496 *\r
497 * DESCRIPTION\r
498 *       The cl_pool_put function returns an object to a pool.\r
499 *\r
500 * SYNOPSIS\r
501 */\r
502 CL_INLINE void CL_API\r
503 cl_pool_put(\r
504         IN      cl_pool_t* const        p_pool,\r
505         IN      void* const                     p_object )\r
506 {\r
507         cl_pool_obj_t   *p_pool_obj;\r
508 \r
509         CL_ASSERT( p_pool );\r
510         CL_ASSERT( p_object );\r
511 \r
512         /* Calculate the offset to the list object representing this object. */\r
513         p_pool_obj = (cl_pool_obj_t*)\r
514                 (((uint8_t*)p_object) - sizeof(cl_pool_obj_t));\r
515 \r
516         /* good sanity check */\r
517         CL_ASSERT( p_pool_obj->list_obj.p_object == p_object );\r
518 \r
519         cl_qcpool_put( &p_pool->qcpool, (cl_pool_item_t*)p_pool_obj );\r
520 }\r
521 /*\r
522 * PARAMETERS\r
523 *       p_pool\r
524 *               [in] Pointer to a cl_pool_t structure to which to return\r
525 *               an object.\r
526 *\r
527 *       p_object\r
528 *               [in] Pointer to an object to return to the pool.\r
529 *\r
530 * RETURN VALUE\r
531 *       This function does not return a value.\r
532 *\r
533 * NOTES\r
534 *       cl_pool_put places the returned object at the head of the pool.\r
535 *\r
536 *       The object specified by the p_object parameter must have been\r
537 *       retrieved from the pool by a previous call to cl_pool_get.\r
538 *\r
539 * SEE ALSO\r
540 *       Pool, cl_pool_put_tail, cl_pool_get\r
541 *********/\r
542 \r
543 \r
544 /****f* Component Library: Pool/cl_pool_grow\r
545 * NAME\r
546 *       cl_pool_grow\r
547 *\r
548 * DESCRIPTION\r
549 *       The cl_pool_grow function grows a pool by\r
550 *       the specified number of objects.\r
551 *\r
552 * SYNOPSIS\r
553 */\r
554 CL_INLINE cl_status_t CL_API\r
555 cl_pool_grow(\r
556         IN      cl_pool_t* const        p_pool,\r
557         IN      const size_t            obj_count )\r
558 {\r
559         CL_ASSERT( p_pool );\r
560         return( cl_qcpool_grow( &p_pool->qcpool, obj_count ) );\r
561 }\r
562 /*\r
563 * PARAMETERS\r
564 *       p_pool\r
565 *               [in] Pointer to a cl_pool_t structure whose capacity to grow.\r
566 *\r
567 *       obj_count\r
568 *               [in] Number of objects by which to grow the pool.\r
569 *\r
570 * RETURN VALUES\r
571 *       CL_SUCCESS if the pool grew successfully.\r
572 *\r
573 *       CL_INSUFFICIENT_MEMORY if there was not enough memory to grow the\r
574 *       pool.\r
575 *\r
576 *       cl_status_t value returned by optional initialization callback function\r
577 *       specified by the pfn_initializer parameter passed to the\r
578 *       cl_pool_init function.\r
579 *\r
580 * NOTES\r
581 *       It is not necessary to call cl_pool_grow if the pool is\r
582 *       configured to grow automatically.\r
583 *\r
584 * SEE ALSO\r
585 *       Pool\r
586 *********/\r
587 \r
588 \r
589 #ifdef __cplusplus\r
590 }       /* extern "C" */\r
591 #endif  /* __cplusplus */\r
592 \r
593 \r
594 #endif  /* _CL_POOL_H_ */\r