1 /*
2  * Copyright (c) 2004, 2005 Voltaire, Inc. All rights reserved.
3  * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
4  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
5  *
6  * This software is available to you under a choice of one of two
7  * licenses.  You may choose to be licensed under the terms of the GNU
8  * General Public License (GPL) Version 2, available from the file
9  * COPYING in the main directory of this source tree, or the
10  * OpenIB.org BSD license below:
11  *
12  *     Redistribution and use in source and binary forms, with or
13  *     without modification, are permitted provided that the following
14  *     conditions are met:
15  *
16  *      - Redistributions of source code must retain the above
17  *        copyright notice, this list of conditions and the following
18  *        disclaimer.
19  *
20  *      - Redistributions in binary form must reproduce the above
21  *        copyright notice, this list of conditions and the following
22  *        disclaimer in the documentation and/or other materials
23  *        provided with the distribution.
24  *
25  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32  * SOFTWARE.
33  *
34  */
35 
36 /*
37  * Abstract:
38  *	Declaration of the quick composite pool.  The quick composite pool
39  *	manages a pool of composite objects.  A composite object is an object
40  *	that is made of multiple sub objects.
41  *	It can grow to meet demand, limited only by system memory.
42  */
43 
44 #ifndef _CL_QUICK_COMPOSITE_POOL_H_
45 #define _CL_QUICK_COMPOSITE_POOL_H_
46 
47 #include <complib/cl_types.h>
48 #include <complib/cl_qlist.h>
49 
50 #ifdef __cplusplus
51 #  define BEGIN_C_DECLS extern "C" {
52 #  define END_C_DECLS   }
53 #else				/* !__cplusplus */
54 #  define BEGIN_C_DECLS
55 #  define END_C_DECLS
56 #endif				/* __cplusplus */
57 
58 BEGIN_C_DECLS
59 /****h* Component Library/Quick Composite Pool
60 * NAME
61 *	Quick Composite Pool
62 *
63 * DESCRIPTION
64 *	The Quick Composite Pool provides a self-contained and self-sustaining
65 *	pool of user defined composite objects.
66 *
67 *	A composite object is an object that is composed of one or more
68 *	sub-objects, each of which needs to be treated separately for
69 *	initialization. Objects can be retrieved from the pool as long as there
70 *	is memory in the system.
71 *
72 *	To aid in object oriented design, the Quick Composite Pool provides users
73 *	the ability to specify callbacks that are invoked for each object for
74 *	construction, initialization, and destruction. Constructor and destructor
75 *	callback functions may not fail.
76 *
77 *	A Quick Composite Pool does not return memory to the system as the user
78 *	returns objects to the pool. The only method of returning memory to the
79 *	system is to destroy the pool.
80 *
81 *	The Quick Composite Pool operates on cl_pool_item_t structures that
82 *	describe composite objects. This provides for more efficient memory use.
83 *	If using a cl_pool_item_t is not desired, the Composite Pool provides
84 *	similar functionality but operates on opaque objects.
85 *
86 *	The Quick Composit Pool functions operate on a cl_qcpool_t structure
87 *	which should be treated as opaque and should be manipulated only through
88 *	the provided functions.
89 *
90 * SEE ALSO
91 *	Structures:
92 *		cl_qcpool_t, cl_pool_item_t
93 *
94 *	Callbacks:
95 *		cl_pfn_qcpool_init_t, cl_pfn_qcpool_dtor_t
96 *
97 *	Initialization/Destruction:
98 *		cl_qcpool_construct, cl_qcpool_init, cl_qcpool_destroy
99 *
100 *	Manipulation:
101 *		cl_qcpool_get, cl_qcpool_put, cl_qcpool_put_list, cl_qcpool_grow
102 *
103 *	Attributes:
104 *		cl_is_qcpool_inited, cl_qcpool_count
105 *********/
106 /****s* Component Library: Quick Composite Pool/cl_pool_item_t
107 * NAME
108 *	cl_pool_item_t
109 *
110 * DESCRIPTION
111 *	The cl_pool_item_t structure is used by pools to store objects.
112 *
113 * SYNOPSIS
114 */
115 typedef struct _cl_pool_item {
116 	cl_list_item_t list_item;
117 #ifdef _DEBUG_
118 	/* Pointer to the owner pool used for sanity checks. */
119 	struct _cl_qcpool *p_pool;
120 #endif
121 } cl_pool_item_t;
122 /*
123 * FIELDS
124 *	list_item
125 *		Used internally by the pool. Users should not use this field.
126 *
127 *	p_pool
128 *		Used internally by the pool in debug builds to check for consistency.
129 *
130 * NOTES
131 *	The pool item structure is defined in such a way as to safely allow
132 *	users to cast from a pool item to a list item for storing items
133 *	retrieved from a quick pool in a quick list.
134 *
135 * SEE ALSO
136 *	Quick Composite Pool, cl_list_item_t
137 *********/
138 
139 /****i* Component Library: Quick List/cl_pool_obj_t
140 * NAME
141 *	cl_pool_obj_t
142 *
143 * DESCRIPTION
144 *	The cl_pool_obj_t structure is used by pools to store objects.
145 *
146 * SYNOPSIS
147 */
148 typedef struct _cl_pool_obj {
149 	/* The pool item must be the first item to allow casting. */
150 	cl_pool_item_t pool_item;
151 	const void *p_object;
152 } cl_pool_obj_t;
153 /*
154 * FIELDS
155 *	pool_item
156 *		Used internally by the pool. Users should not use this field.
157 *
158 *	p_object
159 *		Pointer to the user's object being stored in the pool.
160 *
161 * NOTES
162 *	The pool object structure is used by non-quick pools to store object.
163 *
164 * SEE ALSO
165 *	cl_pool_item_t
166 *********/
167 
168 /****d* Component Library: Quick Composite Pool/cl_pfn_qcpool_init_t
169 * NAME
170 *	cl_pfn_qcpool_init_t
171 *
172 * DESCRIPTION
173 *	The cl_pfn_qcpool_init_t function type defines the prototype for
174 *	functions used as initializer for objects being allocated by a
175 *	quick composite pool.
176 *
177 * SYNOPSIS
178 */
179 typedef cl_status_t
180     (*cl_pfn_qcpool_init_t) (IN void **const p_comp_array,
181 			     IN const uint32_t num_components,
182 			     IN void *context,
183 			     OUT cl_pool_item_t ** const pp_pool_item);
184 /*
185 * PARAMETERS
186 *	p_comp_array
187 *		[in] Pointer to the first entry in an array of pointers, each of
188 *		which points to a component that makes up a composite object.
189 *
190 *	num_components
191 *		[in] Number of components that in the component array.
192 *
193 *	context
194 *		[in] Context provided in a call to cl_qcpool_init.
195 *
196 *	pp_pool_item
197 *		[out] Users should set this pointer to reference the cl_pool_item_t
198 *		structure that represents the composite object.  This pointer must
199 *		not be NULL if the function returns CL_SUCCESS.
200 *
201 * RETURN VALUE
202 *	Return CL_SUCCESS to indicate that initialization of the object
203 *	was successful and that initialization of further objects may continue.
204 *
205 *	Other cl_status_t values will be returned by cl_qcpool_init
206 *	and cl_qcpool_grow.
207 *
208 * NOTES
209 *	This function type is provided as function prototype reference for
210 *	the function provided by the user as a parameter to the
211 *	cl_qcpool_init function.
212 *
213 *	The initializer is invoked once per allocated object, allowing the user
214 *	to chain components to form a composite object and perform any necessary
215 *	initialization.  Returning a status other than CL_SUCCESS aborts a grow
216 *	operation, initiated either through cl_qcpool_init or cl_qcpool_grow,
217 *	and causes the initiating function to fail.  Any non-CL_SUCCESS status
218 *	will be returned by the function that initiated the grow operation.
219 *
220 *	All memory for the requested number of components is pre-allocated.  Users
221 *	should include space in one of their components for the cl_pool_item_t
222 *	structure that will represent the composite object to avoid having to
223 *	allocate that structure in the initialization callback.  Alternatively,
224 *	users may specify an additional component for the cl_pool_item_t structure.
225 *
226 *	When later performing a cl_qcpool_get call, the return value is a pointer
227 *	to the cl_pool_item_t returned by this function in the pp_pool_item
228 *	parameter. Users must set pp_pool_item to a valid pointer to the
229 *	cl_pool_item_t representing the object if they return CL_SUCCESS.
230 *
231 * SEE ALSO
232 *	Quick Composite Pool, cl_qcpool_init
233 *********/
234 
235 /****d* Component Library: Quick Composite Pool/cl_pfn_qcpool_dtor_t
236 * NAME
237 *	cl_pfn_qcpool_dtor_t
238 *
239 * DESCRIPTION
240 *	The cl_pfn_qcpool_dtor_t function type defines the prototype for
241 *	functions used as destructor for objects being deallocated by a
242 *	quick composite pool.
243 *
244 * SYNOPSIS
245 */
246 typedef void
247  (*cl_pfn_qcpool_dtor_t) (IN const cl_pool_item_t * const p_pool_item,
248 			  IN void *context);
249 /*
250 * PARAMETERS
251 *	p_pool_item
252 *		[in] Pointer to a cl_pool_item_t structure representing an object.
253 *
254 *	context
255 *		[in] Context provided in a call to cl_qcpool_init.
256 *
257 * RETURN VALUE
258 *	This function does not return a value.
259 *
260 * NOTES
261 *	This function type is provided as function prototype reference for
262 *	the function provided by the user as an optional parameter to the
263 *	cl_qcpool_init function.
264 *
265 *	The destructor is invoked once per allocated object, allowing the user
266 *	to perform any necessary cleanup. Users should not attempt to deallocate
267 *	the memory for the composite object, as the quick composite pool manages
268 *	object allocation and deallocation.
269 *
270 * SEE ALSO
271 *	Quick Composite Pool, cl_qcpool_init
272 *********/
273 
274 /****s* Component Library: Quick Composite Pool/cl_qcpool_t
275 * NAME
276 *	cl_qcpool_t
277 *
278 * DESCRIPTION
279 *	Quick composite pool structure.
280 *
281 *	The cl_qcpool_t structure should be treated as opaque and should be
282 *	manipulated only through the provided functions.
283 *
284 * SYNOPSIS
285 */
286 typedef struct _cl_qcpool {
287 	uint32_t num_components;
288 	size_t *component_sizes;
289 	void **p_components;
290 	size_t num_objects;
291 	size_t max_objects;
292 	size_t grow_size;
293 	cl_pfn_qcpool_init_t pfn_init;
294 	cl_pfn_qcpool_dtor_t pfn_dtor;
295 	const void *context;
296 	cl_qlist_t free_list;
297 	cl_qlist_t alloc_list;
298 	cl_state_t state;
299 } cl_qcpool_t;
300 /*
301 * FIELDS
302 *	num_components
303 *		Number of components per object.
304 *
305 *	component_sizes
306 *		Array of sizes, one for each component.
307 *
308 *	p_components
309 *		Array of pointers to components, used for the constructor callback.
310 *
311 *	num_objects
312 *		Number of objects managed by the pool
313 *
314 *	grow_size
315 *		Number of objects to add when automatically growing the pool.
316 *
317 *	pfn_init
318 *		Pointer to the user's initializer callback to invoke when initializing
319 *		new objects.
320 *
321 *	pfn_dtor
322 *		Pointer to the user's destructor callback to invoke before deallocating
323 *		memory allocated for objects.
324 *
325 *	context
326 *		User's provided context for callback functions, used by the pool
327 *		when invoking callbacks.
328 *
329 *	free_list
330 *		Quick list of objects available.
331 *
332 *	alloc_list
333 *		Quick list used to store information about allocations.
334 *
335 *	state
336 *		State of the pool.
337 *
338 * SEE ALSO
339 *	Quick Composite Pool
340 *********/
341 
342 /****f* Component Library: Quick Composite Pool/cl_qcpool_construct
343 * NAME
344 *	cl_qcpool_construct
345 *
346 * DESCRIPTION
347 *	The cl_qcpool_construct function constructs a quick composite pool.
348 *
349 * SYNOPSIS
350 */
351 void cl_qcpool_construct(IN cl_qcpool_t * const p_pool);
352 /*
353 * PARAMETERS
354 *	p_pool
355 *		[in] Pointer to a cl_qcpool_t structure whose state to initialize.
356 *
357 * RETURN VALUE
358 *	This function does not return a value.
359 *
360 * NOTES
361 *	Allows calling cl_qcpool_init, cl_qcpool_destroy, cl_is_qcpool_inited.
362 *
363 *	Calling cl_qcpool_construct is a prerequisite to calling any other
364 *	quick composite pool function except cl_qcpool_init.
365 *
366 * SEE ALSO
367 *	Quick Composite Pool, cl_qcpool_init, cl_qcpool_destroy,
368 *	cl_is_qcpool_inited
369 *********/
370 
371 /****f* Component Library: Quick Composite Pool/cl_is_qcpool_inited
372 * NAME
373 *	cl_is_qcpool_inited
374 *
375 * DESCRIPTION
376 *	The cl_is_qcpool_inited function returns whether a quick composite pool was
377 *	successfully initialized.
378 *
379 * SYNOPSIS
380 */
cl_is_qcpool_inited(IN const cl_qcpool_t * const p_pool)381 static inline uint32_t cl_is_qcpool_inited(IN const cl_qcpool_t * const p_pool)
382 {
383 	/* CL_ASSERT that a non-null pointer is provided. */
384 	CL_ASSERT(p_pool);
385 	/* CL_ASSERT that the pool is not in some invalid state. */
386 	CL_ASSERT(cl_is_state_valid(p_pool->state));
387 
388 	return (p_pool->state == CL_INITIALIZED);
389 }
390 
391 /*
392 * PARAMETERS
393 *	p_pool
394 *		[in] Pointer to a cl_qcpool_t structure to check.
395 *
396 * RETURN VALUES
397 *	TRUE if the quick composite pool was initialized successfully.
398 *
399 *	FALSE otherwise.
400 *
401 * NOTES
402 *	Allows checking the state of a quick composite pool to determine if
403 *	invoking member functions is appropriate.
404 *
405 * SEE ALSO
406 *	Quick Composite Pool
407 *********/
408 
409 /****f* Component Library: Quick Composite Pool/cl_qcpool_init
410 * NAME
411 *	cl_qcpool_init
412 *
413 * DESCRIPTION
414 *	The cl_qcpool_init function initializes a quick composite pool for use.
415 *
416 * SYNOPSIS
417 */
418 cl_status_t
419 cl_qcpool_init(IN cl_qcpool_t * const p_pool,
420 	       IN const size_t min_size,
421 	       IN const size_t max_size,
422 	       IN const size_t grow_size,
423 	       IN const size_t * const component_sizes,
424 	       IN const uint32_t num_components,
425 	       IN cl_pfn_qcpool_init_t pfn_initializer OPTIONAL,
426 	       IN cl_pfn_qcpool_dtor_t pfn_destructor OPTIONAL,
427 	       IN const void *const context);
428 /*
429 * PARAMETERS
430 *	p_pool
431 *		[in] Pointer to a cl_qcpool_t structure to initialize.
432 *
433 *	min_size
434 *		[in] Minimum number of objects that the pool should support. All
435 *		necessary allocations to allow storing the minimum number of items
436 *		are performed at initialization time, and all necessary callbacks
437 *		successfully invoked.
438 *
439 *	max_size
440 *		[in] Maximum number of objects to which the pool is allowed to grow.
441 *		A value of zero specifies no maximum.
442 *
443 *	grow_size
444 *		[in] Number of objects to allocate when incrementally growing the pool.
445 *		A value of zero disables automatic growth.
446 *
447 *	component_sizes
448 *		[in] Pointer to the first entry in an array of sizes describing,
449 *		in order, the sizes of the components that make up a composite object.
450 *
451 *	num_components
452 *		[in] Number of components that make up a composite object.
453 *
454 *	pfn_initializer
455 *		[in] Initializer callback to invoke for every new object when growing
456 *		the pool. This parameter may be NULL only if the objects stored in
457 *		the quick composite pool consist of only one component. If NULL, the
458 *		pool assumes the cl_pool_item_t structure describing objects is
459 *		located at the head of each object. See the cl_pfn_qcpool_init_t
460 *		function type declaration for details about the callback function.
461 *
462 *	pfn_destructor
463 *		[in] Destructor callback to invoke for every object before memory for
464 *		that object is freed. This parameter is optional and may be NULL.
465 *		See the cl_pfn_qcpool_dtor_t function type declaration for details
466 *		about the callback function.
467 *
468 *	context
469 *		[in] Value to pass to the callback functions to provide context.
470 *
471 * RETURN VALUES
472 *	CL_SUCCESS if the quick composite pool was initialized successfully.
473 *
474 *	CL_INSUFFICIENT_MEMORY if there was not enough memory to initialize the
475 *	quick composite pool.
476 *
477 *	CL_INVALID_SETTING if a NULL constructor was provided for composite objects
478 *	consisting of more than one component.  Also returns CL_INVALID_SETTING if
479 *	the maximum size is non-zero and less than the minimum size.
480 *
481 *	Other cl_status_t value returned by optional initialization callback function
482 *	specified by the pfn_initializer parameter.
483 *
484 *	If initialization fails, the pool is left in a destroyed state.  Callers
485 *	may still safely call cl_qcpool_destroy.
486 *
487 * NOTES
488 *	cl_qcpool_init initializes, and if necessary, grows the pool to
489 *	the capacity desired.
490 *
491 * SEE ALSO
492 *	Quick Composite Pool, cl_qcpool_construct, cl_qcpool_destroy,
493 *	cl_qcpool_get, cl_qcpool_put, cl_qcpool_grow,
494 *	cl_qcpool_count, cl_pfn_qcpool_init_t, cl_pfn_qcpool_dtor_t
495 *********/
496 
497 /****f* Component Library: Quick Composite Pool/cl_qcpool_destroy
498 * NAME
499 *	cl_qcpool_destroy
500 *
501 * DESCRIPTION
502 *	The cl_qcpool_destroy function destroys a quick composite pool.
503 *
504 * SYNOPSIS
505 */
506 void cl_qcpool_destroy(IN cl_qcpool_t * const p_pool);
507 /*
508 * PARAMETERS
509 *	p_pool
510 *		[in] Pointer to a cl_qcpool_t structure to destroy.
511 *
512 * RETURN VALUE
513 *	This function does not return a value.
514 *
515 * NOTES
516 *	All memory allocated for composite objects is freed. The destructor
517 *	callback, if any, will be invoked for every allocated object. Further
518 *	operations on the composite pool should not be attempted after
519 *	cl_qcpool_destroy is invoked.
520 *
521 *	This function should only be called after a call to
522 *	cl_qcpool_construct or cl_qcpool_init.
523 *
524 *	In a debug build, cl_qcpool_destroy asserts that all objects are in
525 *	the pool.
526 *
527 * SEE ALSO
528 *	Quick Composite Pool, cl_qcpool_construct, cl_qcpool_init
529 *********/
530 
531 /****f* Component Library: Quick Composite Pool/cl_qcpool_count
532 * NAME
533 *	cl_qcpool_count
534 *
535 * DESCRIPTION
536 *	The cl_qcpool_count function returns the number of available objects
537 *	in a quick composite pool.
538 *
539 * SYNOPSIS
540 */
cl_qcpool_count(IN cl_qcpool_t * const p_pool)541 static inline size_t cl_qcpool_count(IN cl_qcpool_t * const p_pool)
542 {
543 	CL_ASSERT(p_pool);
544 	CL_ASSERT(p_pool->state == CL_INITIALIZED);
545 
546 	return (cl_qlist_count(&p_pool->free_list));
547 }
548 
549 /*
550 * PARAMETERS
551 *	p_pool
552 *		[in] Pointer to a cl_qcpool_t structure for which the number of
553 *		available objects is requested.
554 *
555 * RETURN VALUE
556 *	Returns the number of objects available in the specified
557 *	quick composite pool.
558 *
559 * SEE ALSO
560 *	Quick Composite Pool
561 *********/
562 
563 /****f* Component Library: Quick Composite Pool/cl_qcpool_get
564 * NAME
565 *	cl_qcpool_get
566 *
567 * DESCRIPTION
568 *	The cl_qcpool_get function retrieves an object from a
569 *	quick composite pool.
570 *
571 * SYNOPSIS
572 */
573 cl_pool_item_t *cl_qcpool_get(IN cl_qcpool_t * const p_pool);
574 /*
575 * PARAMETERS
576 *	p_pool
577 *		[in] Pointer to a cl_qcpool_t structure from which to retrieve
578 *		an object.
579 *
580 * RETURN VALUES
581 *	Returns a pointer to a cl_pool_item_t for a composite object.
582 *
583 *	Returns NULL if the pool is empty and can not be grown automatically.
584 *
585 * NOTES
586 *	cl_qcpool_get returns the object at the head of the pool. If the pool is
587 *	empty, it is automatically grown to accommodate this request unless the
588 *	grow_size parameter passed to the cl_qcpool_init function was zero.
589 *
590 * SEE ALSO
591 *	Quick Composite Pool, cl_qcpool_get_tail, cl_qcpool_put,
592 *	cl_qcpool_grow, cl_qcpool_count
593 *********/
594 
595 /****f* Component Library: Quick Composite Pool/cl_qcpool_put
596 * NAME
597 *	cl_qcpool_put
598 *
599 * DESCRIPTION
600 *	The cl_qcpool_put function returns an object to a quick composite pool.
601 *
602 * SYNOPSIS
603 */
604 static inline void
cl_qcpool_put(IN cl_qcpool_t * const p_pool,IN cl_pool_item_t * const p_pool_item)605 cl_qcpool_put(IN cl_qcpool_t * const p_pool,
606 	      IN cl_pool_item_t * const p_pool_item)
607 {
608 	CL_ASSERT(p_pool);
609 	CL_ASSERT(p_pool->state == CL_INITIALIZED);
610 	CL_ASSERT(p_pool_item);
611 	/* Make sure items being returned came from the specified pool. */
612 	CL_ASSERT(p_pool_item->p_pool == p_pool);
613 
614 	/* return this lil' doggy to the pool */
615 	cl_qlist_insert_head(&p_pool->free_list, &p_pool_item->list_item);
616 }
617 
618 /*
619 * PARAMETERS
620 *	p_pool
621 *		[in] Pointer to a cl_qcpool_t structure to which to return
622 *		an object.
623 *
624 *	p_pool_item
625 *		[in] Pointer to a cl_pool_item_t structure for the object
626 *		being returned.
627 *
628 * RETURN VALUE
629 *	This function does not return a value.
630 *
631 * NOTES
632 *	cl_qcpool_put places the returned object at the head of the pool.
633 *
634 *	The object specified by the p_pool_item parameter must have been
635 *	retrieved from the pool by a previous call to cl_qcpool_get.
636 *
637 * SEE ALSO
638 *	Quick Composite Pool, cl_qcpool_put_tail, cl_qcpool_get
639 *********/
640 
641 /****f* Component Library: Quick Composite Pool/cl_qcpool_put_list
642 * NAME
643 *	cl_qcpool_put_list
644 *
645 * DESCRIPTION
646 *	The cl_qcpool_put_list function returns a list of objects to the head of
647 *	a quick composite pool.
648 *
649 * SYNOPSIS
650 */
651 static inline void
cl_qcpool_put_list(IN cl_qcpool_t * const p_pool,IN cl_qlist_t * const p_list)652 cl_qcpool_put_list(IN cl_qcpool_t * const p_pool, IN cl_qlist_t * const p_list)
653 {
654 #ifdef _DEBUG_
655 	cl_list_item_t *p_item;
656 #endif
657 
658 	CL_ASSERT(p_pool);
659 	CL_ASSERT(p_pool->state == CL_INITIALIZED);
660 	CL_ASSERT(p_list);
661 
662 #ifdef _DEBUG_
663 	/* Chech that all items in the list came from this pool. */
664 	p_item = cl_qlist_head(p_list);
665 	while (p_item != cl_qlist_end(p_list)) {
666 		CL_ASSERT(((cl_pool_item_t *) p_item)->p_pool == p_pool);
667 		p_item = cl_qlist_next(p_item);
668 	}
669 #endif
670 
671 	/* return these lil' doggies to the pool */
672 	cl_qlist_insert_list_head(&p_pool->free_list, p_list);
673 }
674 
675 /*
676 * PARAMETERS
677 *	p_pool
678 *		[in] Pointer to a cl_qcpool_t structure to which to return
679 *		a list of objects.
680 *
681 *	p_list
682 *		[in] Pointer to a cl_qlist_t structure for the list of objects
683 *		being returned.
684 *
685 * RETURN VALUE
686 *	This function does not return a value.
687 *
688 * NOTES
689 *	cl_qcpool_put_list places the returned objects at the head of the pool.
690 *
691 *	The objects in the list specified by the p_list parameter must have been
692 *	retrieved from the pool by a previous call to cl_qcpool_get.
693 *
694 * SEE ALSO
695 *	Quick Composite Pool, cl_qcpool_put, cl_qcpool_put_tail, cl_qcpool_get
696 *********/
697 
698 /****f* Component Library: Quick Composite Pool/cl_qcpool_grow
699 * NAME
700 *	cl_qcpool_grow
701 *
702 * DESCRIPTION
703 *	The cl_qcpool_grow function grows a quick composite pool by
704 *	the specified number of objects.
705 *
706 * SYNOPSIS
707 */
708 cl_status_t cl_qcpool_grow(IN cl_qcpool_t * const p_pool, IN size_t obj_count);
709 /*
710 * PARAMETERS
711 *	p_pool
712 *		[in] Pointer to a cl_qcpool_t structure whose capacity to grow.
713 *
714 *	obj_count
715 *		[in] Number of objects by which to grow the pool.
716 *
717 * RETURN VALUES
718 *	CL_SUCCESS if the quick composite pool grew successfully.
719 *
720 *	CL_INSUFFICIENT_MEMORY if there was not enough memory to grow the
721 *	quick composite pool.
722 *
723 *	cl_status_t value returned by optional initialization callback function
724 *	specified by the pfn_initializer parameter passed to the
725 *	cl_qcpool_init function.
726 *
727 * NOTES
728 *	It is not necessary to call cl_qcpool_grow if the pool is
729 *	configured to grow automatically.
730 *
731 * SEE ALSO
732 *	Quick Composite Pool
733 *********/
734 
735 END_C_DECLS
736 #endif				/* _CL_QUICK_COMPOSITE_POOL_H_ */
737