[DAPL2] sync with WinOF 2.1 branch
[mirror/winof/.git] / inc / complib / cl_comppool.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 composite pool.\r
37  *      The composite pool managers a pool of composite objects.  A composite object is an object\r
38  *      that is made of multiple sub objects.\r
39  *      The pool can grow to meet demand, limited only by system memory.\r
40  *\r
41  * Environment:\r
42  *      All\r
43  */\r
44 \r
45 \r
46 #ifndef _CL_COMP_POOL_H_\r
47 #define _CL_COMP_POOL_H_\r
48 \r
49 \r
50 #include <complib/cl_qcomppool.h>\r
51 \r
52 \r
53 /****h* Component Library/Composite Pool\r
54 * NAME\r
55 *       Composite Pool\r
56 *\r
57 * DESCRIPTION\r
58 *       The Composite Pool provides a self-contained and self-sustaining pool of\r
59 *       user defined composite objects.\r
60 *\r
61 *       A composite object is an object that is composed of one or more\r
62 *       sub-objects, each of which needs to be treated separately for\r
63 *       initialization. Objects can be retrieved from the pool as long as there\r
64 *       is memory in the system.\r
65 *\r
66 *       To aid in object oriented design, the composite pool provides the user\r
67 *       the ability to specify callbacks that are invoked for each object for\r
68 *       construction, initialization, and destruction. Constructor and destructor\r
69 *       callback functions may not fail.\r
70 *\r
71 *       A composite pool does not return memory to the system as the user returns\r
72 *       objects to the pool. The only method of returning memory to the system is\r
73 *       to destroy the pool.\r
74 *\r
75 *       The composite pool functions operates on a cl_cpool_t structure which\r
76 *       should be treated as opaque and should be manipulated only through the\r
77 *       provided functions.\r
78 *\r
79 * SEE ALSO\r
80 *       Structures:\r
81 *               cl_cpool_t\r
82 *\r
83 *       Callbacks:\r
84 *               cl_pfn_cpool_init_t, cl_pfn_cpool_dtor_t\r
85 *\r
86 *       Initialization/Destruction:\r
87 *               cl_cpool_construct, cl_cpool_init, cl_cpool_destroy\r
88 *\r
89 *       Manipulation:\r
90 *               cl_cpool_get, cl_cpool_put, cl_cpool_grow\r
91 *\r
92 *       Attributes:\r
93 *               cl_is_cpool_inited, cl_cpool_count\r
94 *********/\r
95 \r
96 \r
97 /****d* Component Library: Composite Pool/cl_pfn_cpool_init_t\r
98 * NAME\r
99 *       cl_pfn_cpool_init_t\r
100 *\r
101 * DESCRIPTION\r
102 *       The cl_pfn_cpool_init_t function type defines the prototype for\r
103 *       functions used as initializers for objects being allocated by a\r
104 *       composite pool.\r
105 *\r
106 * SYNOPSIS\r
107 */\r
108 typedef cl_status_t\r
109 (CL_API *cl_pfn_cpool_init_t)(\r
110         IN      void** const            p_comp_array,\r
111         IN      const uint32_t          num_components,\r
112         IN      void*                           context );\r
113 /*\r
114 * PARAMETERS\r
115 *       p_object\r
116 *               [in] Pointer to an object to initialize.\r
117 *\r
118 *       context\r
119 *               [in] Context provided in a call to cl_cpool_init.\r
120 *\r
121 * RETURN VALUES\r
122 *       Return CL_SUCCESS to indicates that initialization of the object\r
123 *       was successful and that initialization of further objects may continue.\r
124 *\r
125 *       Other cl_status_t values will be returned by cl_cpool_init\r
126 *       and cl_cpool_grow.\r
127 *\r
128 * NOTES\r
129 *       This function type is provided as function prototype reference for\r
130 *       the function provided by the user as an optional parameter to the\r
131 *       cl_cpool_init function.\r
132 *\r
133 *       The initializer is invoked once per allocated object, allowing the user\r
134 *       to chain components to form a composite object and perform any necessary\r
135 *       initialization.  Returning a status other than CL_SUCCESS aborts a grow\r
136 *       operation, initiated either through cl_cpool_init or cl_cpool_grow, and\r
137 *       causes the initiating function to fail.  Any non-CL_SUCCESS status will\r
138 *       be returned by the function that initiated the grow operation.\r
139 *\r
140 *       All memory for the requested number of components is pre-allocated.\r
141 *\r
142 *       When later performing a cl_cpool_get call, the return value is a pointer\r
143 *       to the first component.\r
144 *\r
145 * SEE ALSO\r
146 *       Composite Pool, cl_cpool_init, cl_cpool_grow\r
147 *********/\r
148 \r
149 \r
150 /****d* Component Library: Composite Pool/cl_pfn_cpool_dtor_t\r
151 * NAME\r
152 *       cl_pfn_cpool_dtor_t\r
153 *\r
154 * DESCRIPTION\r
155 *       The cl_pfn_cpool_dtor_t function type defines the prototype for\r
156 *       functions used as destructor for objects being deallocated by a\r
157 *       composite pool.\r
158 *\r
159 * SYNOPSIS\r
160 */\r
161 typedef void\r
162 (CL_API *cl_pfn_cpool_dtor_t)(\r
163         IN      void* const                     p_object,\r
164         IN      void*                           context );\r
165 /*\r
166 * PARAMETERS\r
167 *       p_object\r
168 *               [in] Pointer to an object to destruct.\r
169 *\r
170 *       context\r
171 *               [in] Context provided in the call to cl_cpool_init.\r
172 *\r
173 * RETURN VALUE\r
174 *       This function does not return a value.\r
175 *\r
176 * NOTES\r
177 *       This function type is provided as function prototype reference for\r
178 *       the function provided by the user as an optional parameter to the\r
179 *       cl_cpool_init function.\r
180 *\r
181 *       The destructor is invoked once per allocated object, allowing the user\r
182 *       to perform any necessary cleanup. Users should not attempt to deallocate\r
183 *       the memory for the composite object, as the composite pool manages\r
184 *       object allocation and deallocation.\r
185 *\r
186 * SEE ALSO\r
187 *       Composite Pool, cl_cpool_init\r
188 *********/\r
189 \r
190 \r
191 /****s* Component Library: Composite Pool/cl_cpool_t\r
192 * NAME\r
193 *       cl_cpool_t\r
194 *\r
195 * DESCRIPTION\r
196 *       Composite pool structure.\r
197 *\r
198 *       The cl_cpool_t structure should be treated as opaque and should be\r
199 *       manipulated only through the provided functions.\r
200 *\r
201 * SYNOPSIS\r
202 */\r
203 typedef struct _cl_cpool\r
204 {\r
205         cl_qcpool_t                             qcpool;\r
206         cl_pfn_cpool_init_t             pfn_init;\r
207         cl_pfn_cpool_dtor_t             pfn_dtor;\r
208         const void                              *context;\r
209 \r
210 } cl_cpool_t;\r
211 /*\r
212 * FIELDS\r
213 *       qcpool\r
214 *               Quick composite pool that manages all objects.\r
215 *\r
216 *       pfn_init\r
217 *               Pointer to the user's initializer callback, used by the pool\r
218 *               to translate the quick composite pool's initializer callback to\r
219 *               a composite pool initializer callback.\r
220 *\r
221 *       pfn_dtor\r
222 *               Pointer to the user's destructor callback, used by the pool\r
223 *               to translate the quick composite pool's destructor callback to\r
224 *               a composite pool destructor callback.\r
225 *\r
226 *       context\r
227 *               User's provided context for callback functions, used by the pool\r
228 *               to when invoking callbacks.\r
229 *\r
230 * SEE ALSO\r
231 *       Composite Pool\r
232 *********/\r
233 \r
234 \r
235 \r
236 #ifdef __cplusplus\r
237 extern "C"\r
238 {\r
239 #endif  /* __cplusplus */\r
240 \r
241 \r
242 /****f* Component Library: Composite Pool/cl_cpool_construct\r
243 * NAME\r
244 *       cl_cpool_construct\r
245 *\r
246 * DESCRIPTION\r
247 *       The cl_cpool_construct function constructs a composite pool.\r
248 *\r
249 * SYNOPSIS\r
250 */\r
251 CL_EXPORT void CL_API\r
252 cl_cpool_construct(\r
253         IN      cl_cpool_t* const       p_pool );\r
254 /*\r
255 * PARAMETERS\r
256 *       p_pool\r
257 *               [in] Pointer to a cl_cpool_t structure whose state to initialize.\r
258 *\r
259 * RETURN VALUE\r
260 *       This function does not return a value.\r
261 *\r
262 * NOTES\r
263 *       Allows calling cl_pool_init, cl_cpool_destroy, cl_is_cpool_inited.\r
264 *\r
265 *       Calling cl_cpool_construct is a prerequisite to calling any other\r
266 *       composite pool function except cl_cpool_init.\r
267 *\r
268 * SEE ALSO\r
269 *       Composite Pool, cl_cpool_init, cl_cpool_destroy, cl_is_cpool_inited\r
270 *********/\r
271 \r
272 \r
273 /****f* Component Library: Composite Pool/cl_is_cpool_inited\r
274 * NAME\r
275 *       cl_is_cpool_inited\r
276 *\r
277 * DESCRIPTION\r
278 *       The cl_is_cpool_inited function returns whether a composite pool was\r
279 *       successfully initialized.\r
280 *\r
281 * SYNOPSIS\r
282 */\r
283 CL_INLINE boolean_t CL_API\r
284 cl_is_cpool_inited(\r
285         IN      const cl_cpool_t* const p_pool )\r
286 {\r
287         /* CL_ASSERT that a non-null pointer is provided. */\r
288         CL_ASSERT( p_pool );\r
289         return( cl_is_qcpool_inited( &p_pool->qcpool ) );\r
290 }\r
291 /*\r
292 * PARAMETERS\r
293 *       p_pool\r
294 *               [in] Pointer to a cl_cpool_t structure whose initialization state\r
295 *               to check.\r
296 *\r
297 * RETURN VALUES\r
298 *       TRUE if the composite pool was initialized successfully.\r
299 *\r
300 *       FALSE otherwise.\r
301 *\r
302 * NOTES\r
303 *       Allows checking the state of a composite pool to determine if invoking\r
304 *       member functions is appropriate.\r
305 *\r
306 * SEE ALSO\r
307 *       Composite Pool\r
308 *********/\r
309 \r
310 \r
311 /****f* Component Library: Composite Pool/cl_cpool_init\r
312 * NAME\r
313 *       cl_cpool_init\r
314 *\r
315 * DESCRIPTION\r
316 *       The cl_cpool_init function initializes a composite pool for use.\r
317 *\r
318 * SYNOPSIS\r
319 */\r
320 CL_EXPORT cl_status_t CL_API\r
321 cl_cpool_init(\r
322         IN      cl_cpool_t* const               p_pool,\r
323         IN      const size_t                    min_size,\r
324         IN      const size_t                    max_size,\r
325         IN      const size_t                    grow_size,\r
326         IN      size_t* const                   component_sizes,\r
327         IN      const uint32_t                  num_components,\r
328         IN      cl_pfn_cpool_init_t             pfn_initializer OPTIONAL,\r
329         IN      cl_pfn_cpool_dtor_t             pfn_destructor OPTIONAL,\r
330         IN      const void* const               context );\r
331 /*\r
332 * PARAMETERS\r
333 *       p_pool\r
334 *               [in] Pointer to a cl_cpool_t structure to initialize.\r
335 *\r
336 *       min_size\r
337 *               [in] Minimum number of objects that the pool should support. All\r
338 *               necessary allocations to allow storing the minimum number of items\r
339 *               are performed at initialization time, and all necessary callbacks\r
340 *               successfully invoked.\r
341 *\r
342 *       max_size\r
343 *               [in] Maximum number of objects to which the pool is allowed to grow.\r
344 *               A value of zero specifies no maximum.\r
345 *\r
346 *       grow_size\r
347 *               [in] Number of objects to allocate when incrementally growing the pool.\r
348 *               A value of zero disables automatic growth.\r
349 *\r
350 *       component_sizes\r
351 *               [in] Pointer to the first entry in an array of sizes describing,\r
352 *               in order, the sizes of the components that make up a composite object.\r
353 *\r
354 *       num_components\r
355 *               [in] Number of components that make up a composite object.\r
356 *\r
357 *       pfn_initializer\r
358 *               [in] Initialization callback to invoke for every new object when\r
359 *               growing the pool. This parameter may be NULL only if the objects\r
360 *               stored in the composite pool consist of only one component.\r
361 *               See the cl_pfn_cpool_init function type declaration for details\r
362 *               about the callback function.\r
363 *\r
364 *       pfn_destructor\r
365 *               [in] Destructor callback to invoke for every object before memory for\r
366 *               that object is freed. This parameter is optional and may be NULL.\r
367 *               See the cl_pfn_cpool_dtor function type declaration for details\r
368 *               about the callback function.\r
369 *\r
370 *       context\r
371 *               [in] Value to pass to the callback functions to provide context.\r
372 *\r
373 * RETURN VALUES\r
374 *       CL_SUCCESS if the composite pool was initialized successfully.\r
375 *\r
376 *       CL_INSUFFICIENT_MEMORY if there was not enough memory to initialize the\r
377 *       composite pool.\r
378 *\r
379 *       CL_INVALID_SETTING if a NULL constructor was provided for composite objects\r
380 *       consisting of more than one component.  Also returns CL_INVALID_SETTING if\r
381 *       the maximum size is non-zero and less than the minimum size.\r
382 *\r
383 *       Other cl_status_t value returned by optional initialization callback function\r
384 *       specified by the pfn_initializer parameter.\r
385 *\r
386 * NOTES\r
387 *       cl_cpool_init initializes, and if necessary, grows the pool to\r
388 *       the capacity desired.\r
389 *\r
390 * SEE ALSO\r
391 *       Composite Pool, cl_cpool_construct, cl_cpool_destroy,\r
392 *       cl_cpool_get, cl_cpool_put, cl_cpool_grow,\r
393 *       cl_cpool_count, cl_pfn_cpool_ctor_t, cl_pfn_cpool_init_t,\r
394 *       cl_pfn_cpool_dtor_t\r
395 *********/\r
396 \r
397 \r
398 /****f* Component Library: Composite Pool/cl_cpool_destroy\r
399 * NAME\r
400 *       cl_cpool_destroy\r
401 *\r
402 * DESCRIPTION\r
403 *       The cl_cpool_destroy function destroys a composite pool.\r
404 *\r
405 * SYNOPSIS\r
406 */\r
407 CL_INLINE void CL_API\r
408 cl_cpool_destroy(\r
409         IN      cl_cpool_t* const       p_pool )\r
410 {\r
411         CL_ASSERT( p_pool );\r
412 \r
413         cl_qcpool_destroy( &p_pool->qcpool );\r
414 }\r
415 /*\r
416 * PARAMETERS\r
417 *       p_pool\r
418 *               [in] Pointer to a cl_cpool_t structure to destroy.\r
419 *\r
420 * RETURN VALUE\r
421 *       This function does not return a value.\r
422 *\r
423 * NOTES\r
424 *       All memory allocated for composite objects is freed. The destructor\r
425 *       callback, if any, will be invoked for every allocated object. Further\r
426 *       operations on the composite pool should not be attempted after\r
427 *       cl_cpool_destroy is invoked.\r
428 *\r
429 *       This function should only be called after a call to cl_cpool_construct.\r
430 *\r
431 *       In a debug build, cl_cpool_destroy asserts that all objects are in\r
432 *       the pool.\r
433 *\r
434 * SEE ALSO\r
435 *       Composite Pool, cl_cpool_construct, cl_cpool_init\r
436 *********/\r
437 \r
438 \r
439 /****f* Component Library: Composite Pool/cl_cpool_count\r
440 * NAME\r
441 *       cl_cpool_count\r
442 *\r
443 * DESCRIPTION\r
444 *       The cl_cpool_count function returns the number of available objects\r
445 *       in a composite pool.\r
446 *\r
447 * SYNOPSIS\r
448 */\r
449 CL_INLINE size_t CL_API\r
450 cl_cpool_count(\r
451         IN      cl_cpool_t* const       p_pool )\r
452 {\r
453         CL_ASSERT( p_pool );\r
454         return( cl_qcpool_count( &p_pool->qcpool ) );\r
455 }\r
456 /*\r
457 * PARAMETERS\r
458 *       p_pool\r
459 *               [in] Pointer to a cl_cpool_t structure for which the number of\r
460 *               available objects is requested.\r
461 *\r
462 * RETURN VALUE\r
463 *       Returns the number of objects available in the specified\r
464 *       composite pool.\r
465 *\r
466 * SEE ALSO\r
467 *       Composite Pool\r
468 *********/\r
469 \r
470 \r
471 /****f* Component Library: Composite Pool/cl_cpool_get\r
472 * NAME\r
473 *       cl_cpool_get\r
474 *\r
475 * DESCRIPTION\r
476 *       The cl_cpool_get function retrieves an object from a\r
477 *       composite pool.\r
478 *\r
479 * SYNOPSIS\r
480 */\r
481 CL_INLINE void* CL_API\r
482 cl_cpool_get(\r
483         IN      cl_cpool_t* const       p_pool )\r
484 {\r
485         cl_pool_obj_t   *p_pool_obj;\r
486 \r
487         CL_ASSERT( p_pool );\r
488 \r
489         p_pool_obj = (cl_pool_obj_t*)cl_qcpool_get( &p_pool->qcpool );\r
490         if( !p_pool_obj )\r
491                 return( NULL );\r
492 \r
493         CL_ASSERT( p_pool_obj->list_obj.p_object );\r
494         return( (void*)p_pool_obj->list_obj.p_object );\r
495 }\r
496 /*\r
497 * PARAMETERS\r
498 *       p_pool\r
499 *               [in] Pointer to a cl_cpool_t structure from which to retrieve\r
500 *               an object.\r
501 *\r
502 * RETURN VALUES\r
503 *       Returns a pointer to the first component of a composite object.\r
504 *\r
505 *       Returns NULL if the pool is empty and can not be grown automatically.\r
506 *\r
507 * NOTES\r
508 *       cl_cpool_get returns the object at the head of the pool. If the pool is\r
509 *       empty, it is automatically grown to accommodate this request unless the\r
510 *       grow_size parameter passed to the cl_cpool_init function was zero.\r
511 *\r
512 * SEE ALSO\r
513 *       Composite Pool, cl_cpool_get_tail, cl_cpool_put, cl_cpool_grow,\r
514 *       cl_cpool_count\r
515 *********/\r
516 \r
517 \r
518 /****f* Component Library: Composite Pool/cl_cpool_put\r
519 * NAME\r
520 *       cl_cpool_put\r
521 *\r
522 * DESCRIPTION\r
523 *       The cl_cpool_put function returns an object to a composite pool.\r
524 *\r
525 * SYNOPSIS\r
526 */\r
527 CL_INLINE void CL_API\r
528 cl_cpool_put(\r
529         IN      cl_cpool_t* const       p_pool,\r
530         IN      void* const                     p_object )\r
531 {\r
532         cl_pool_obj_t   *p_pool_obj;\r
533 \r
534         CL_ASSERT( p_pool );\r
535         CL_ASSERT( p_object );\r
536 \r
537         /* Calculate the offset to the list object representing this object. */\r
538         p_pool_obj = (cl_pool_obj_t*)\r
539                 (((uint8_t*)p_object) - sizeof(cl_pool_obj_t));\r
540 \r
541         /* good sanity check */\r
542         CL_ASSERT( p_pool_obj->list_obj.p_object == p_object );\r
543 \r
544         cl_qcpool_put( &p_pool->qcpool, (cl_pool_item_t*)p_pool_obj );\r
545 }\r
546 /*\r
547 * PARAMETERS\r
548 *       p_pool\r
549 *               [in] Pointer to a cl_cpool_t structure to which to return\r
550 *               an object.\r
551 *\r
552 *       p_object\r
553 *               [in] Pointer to the first component of an object to return to the pool.\r
554 *\r
555 * RETURN VALUE\r
556 *       This function does not return a value.\r
557 *\r
558 * NOTES\r
559 *       cl_cpool_put places the returned object at the head of the pool.\r
560 *\r
561 *       The object specified by the p_object parameter must have been\r
562 *       retrieved from the pool by a previous call to cl_cpool_get.\r
563 *\r
564 * SEE ALSO\r
565 *       Composite Pool, cl_cpool_put_tail, cl_cpool_get\r
566 *********/\r
567 \r
568 \r
569 /****f* Component Library: Composite Pool/cl_cpool_grow\r
570 * NAME\r
571 *       cl_cpool_grow\r
572 *\r
573 * DESCRIPTION\r
574 *       The cl_cpool_grow function grows a composite pool by\r
575 *       the specified number of objects.\r
576 *\r
577 * SYNOPSIS\r
578 */\r
579 CL_INLINE cl_status_t CL_API\r
580 cl_cpool_grow(\r
581         IN      cl_cpool_t* const       p_pool,\r
582         IN      const size_t            obj_count )\r
583 {\r
584         CL_ASSERT( p_pool );\r
585         return( cl_qcpool_grow( &p_pool->qcpool, obj_count ) );\r
586 }\r
587 /*\r
588 * PARAMETERS\r
589 *       p_pool\r
590 *               [in] Pointer to a cl_cpool_t structure whose capacity to grow.\r
591 *\r
592 *       obj_count\r
593 *               [in] Number of objects by which to grow the pool.\r
594 *\r
595 * RETURN VALUES\r
596 *       CL_SUCCESS if the composite pool grew successfully.\r
597 *\r
598 *       CL_INSUFFICIENT_MEMORY if there was not enough memory to grow the\r
599 *       composite pool.\r
600 *\r
601 *       cl_status_t value returned by optional initialization callback function\r
602 *       specified by the pfn_initializer parameter passed to the\r
603 *       cl_cpool_init function.\r
604 *\r
605 * NOTES\r
606 *       It is not necessary to call cl_cpool_grow if the pool is\r
607 *       configured to grow automatically.\r
608 *\r
609 * SEE ALSO\r
610 *       Composite Pool\r
611 *********/\r
612 \r
613 \r
614 #ifdef __cplusplus\r
615 }       /* extern "C" */\r
616 #endif  /* __cplusplus */\r
617 \r
618 \r
619 #endif  /* _CL_COMP_POOL_H_ */\r