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.
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:
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
16 * - Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
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.
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
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.
44 #ifndef _CL_QUICK_COMPOSITE_POOL_H_
45 #define _CL_QUICK_COMPOSITE_POOL_H_
47 #include <complib/cl_types.h>
48 #include <complib/cl_qlist.h>
51 # define BEGIN_C_DECLS extern "C" {
52 # define END_C_DECLS }
53 #else /* !__cplusplus */
54 # define BEGIN_C_DECLS
56 #endif /* __cplusplus */
59 /****h* Component Library/Quick Composite Pool
61 * Quick Composite Pool
64 * The Quick Composite Pool provides a self-contained and self-sustaining
65 * pool of user defined composite objects.
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.
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.
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.
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.
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.
92 * cl_qcpool_t, cl_pool_item_t
95 * cl_pfn_qcpool_init_t, cl_pfn_qcpool_dtor_t
97 * Initialization/Destruction:
98 * cl_qcpool_construct, cl_qcpool_init, cl_qcpool_destroy
101 * cl_qcpool_get, cl_qcpool_put, cl_qcpool_put_list, cl_qcpool_grow
104 * cl_is_qcpool_inited, cl_qcpool_count
106 /****s* Component Library: Quick Composite Pool/cl_pool_item_t
111 * The cl_pool_item_t structure is used by pools to store objects.
115 typedef struct _cl_pool_item {
116 cl_list_item_t list_item;
118 /* Pointer to the owner pool used for sanity checks. */
119 struct _cl_qcpool *p_pool;
125 * Used internally by the pool. Users should not use this field.
128 * Used internally by the pool in debug builds to check for consistency.
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.
136 * Quick Composite Pool, cl_list_item_t
139 /****i* Component Library: Quick List/cl_pool_obj_t
144 * The cl_pool_obj_t structure is used by pools to store objects.
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;
156 * Used internally by the pool. Users should not use this field.
159 * Pointer to the user's object being stored in the pool.
162 * The pool object structure is used by non-quick pools to store object.
168 /****d* Component Library: Quick Composite Pool/cl_pfn_qcpool_init_t
170 * cl_pfn_qcpool_init_t
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.
180 (*cl_pfn_qcpool_init_t) (IN void **const p_comp_array,
181 IN const uint32_t num_components,
183 OUT cl_pool_item_t ** const pp_pool_item);
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.
191 * [in] Number of components that in the component array.
194 * [in] Context provided in a call to cl_qcpool_init.
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.
202 * Return CL_SUCCESS to indicate that initialization of the object
203 * was successful and that initialization of further objects may continue.
205 * Other cl_status_t values will be returned by cl_qcpool_init
206 * and cl_qcpool_grow.
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.
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.
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.
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.
232 * Quick Composite Pool, cl_qcpool_init
235 /****d* Component Library: Quick Composite Pool/cl_pfn_qcpool_dtor_t
237 * cl_pfn_qcpool_dtor_t
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.
247 (*cl_pfn_qcpool_dtor_t) (IN const cl_pool_item_t * const p_pool_item,
252 * [in] Pointer to a cl_pool_item_t structure representing an object.
255 * [in] Context provided in a call to cl_qcpool_init.
258 * This function does not return a value.
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.
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.
271 * Quick Composite Pool, cl_qcpool_init
274 /****s* Component Library: Quick Composite Pool/cl_qcpool_t
279 * Quick composite pool structure.
281 * The cl_qcpool_t structure should be treated as opaque and should be
282 * manipulated only through the provided functions.
286 typedef struct _cl_qcpool {
287 uint32_t num_components;
288 size_t *component_sizes;
293 cl_pfn_qcpool_init_t pfn_init;
294 cl_pfn_qcpool_dtor_t pfn_dtor;
296 cl_qlist_t free_list;
297 cl_qlist_t alloc_list;
303 * Number of components per object.
306 * Array of sizes, one for each component.
309 * Array of pointers to components, used for the constructor callback.
312 * Number of objects managed by the pool
315 * Number of objects to add when automatically growing the pool.
318 * Pointer to the user's initializer callback to invoke when initializing
322 * Pointer to the user's destructor callback to invoke before deallocating
323 * memory allocated for objects.
326 * User's provided context for callback functions, used by the pool
327 * when invoking callbacks.
330 * Quick list of objects available.
333 * Quick list used to store information about allocations.
339 * Quick Composite Pool
342 /****f* Component Library: Quick Composite Pool/cl_qcpool_construct
344 * cl_qcpool_construct
347 * The cl_qcpool_construct function constructs a quick composite pool.
351 void cl_qcpool_construct(IN cl_qcpool_t * const p_pool);
355 * [in] Pointer to a cl_qcpool_t structure whose state to initialize.
358 * This function does not return a value.
361 * Allows calling cl_qcpool_init, cl_qcpool_destroy, cl_is_qcpool_inited.
363 * Calling cl_qcpool_construct is a prerequisite to calling any other
364 * quick composite pool function except cl_qcpool_init.
367 * Quick Composite Pool, cl_qcpool_init, cl_qcpool_destroy,
368 * cl_is_qcpool_inited
371 /****f* Component Library: Quick Composite Pool/cl_is_qcpool_inited
373 * cl_is_qcpool_inited
376 * The cl_is_qcpool_inited function returns whether a quick composite pool was
377 * successfully initialized.
381 static inline uint32_t cl_is_qcpool_inited(IN const cl_qcpool_t * const p_pool)
383 /* CL_ASSERT that a non-null pointer is provided. */
385 /* CL_ASSERT that the pool is not in some invalid state. */
386 CL_ASSERT(cl_is_state_valid(p_pool->state));
388 return (p_pool->state == CL_INITIALIZED);
394 * [in] Pointer to a cl_qcpool_t structure to check.
397 * TRUE if the quick composite pool was initialized successfully.
402 * Allows checking the state of a quick composite pool to determine if
403 * invoking member functions is appropriate.
406 * Quick Composite Pool
409 /****f* Component Library: Quick Composite Pool/cl_qcpool_init
414 * The cl_qcpool_init function initializes a quick composite pool for use.
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);
431 * [in] Pointer to a cl_qcpool_t structure to initialize.
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.
440 * [in] Maximum number of objects to which the pool is allowed to grow.
441 * A value of zero specifies no maximum.
444 * [in] Number of objects to allocate when incrementally growing the pool.
445 * A value of zero disables automatic growth.
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.
452 * [in] Number of components that make up a composite object.
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.
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.
469 * [in] Value to pass to the callback functions to provide context.
472 * CL_SUCCESS if the quick composite pool was initialized successfully.
474 * CL_INSUFFICIENT_MEMORY if there was not enough memory to initialize the
475 * quick composite pool.
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.
481 * Other cl_status_t value returned by optional initialization callback function
482 * specified by the pfn_initializer parameter.
484 * If initialization fails, the pool is left in a destroyed state. Callers
485 * may still safely call cl_qcpool_destroy.
488 * cl_qcpool_init initializes, and if necessary, grows the pool to
489 * the capacity desired.
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
497 /****f* Component Library: Quick Composite Pool/cl_qcpool_destroy
502 * The cl_qcpool_destroy function destroys a quick composite pool.
506 void cl_qcpool_destroy(IN cl_qcpool_t * const p_pool);
510 * [in] Pointer to a cl_qcpool_t structure to destroy.
513 * This function does not return a value.
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.
521 * This function should only be called after a call to
522 * cl_qcpool_construct or cl_qcpool_init.
524 * In a debug build, cl_qcpool_destroy asserts that all objects are in
528 * Quick Composite Pool, cl_qcpool_construct, cl_qcpool_init
531 /****f* Component Library: Quick Composite Pool/cl_qcpool_count
536 * The cl_qcpool_count function returns the number of available objects
537 * in a quick composite pool.
541 static inline size_t cl_qcpool_count(IN cl_qcpool_t * const p_pool)
544 CL_ASSERT(p_pool->state == CL_INITIALIZED);
546 return (cl_qlist_count(&p_pool->free_list));
552 * [in] Pointer to a cl_qcpool_t structure for which the number of
553 * available objects is requested.
556 * Returns the number of objects available in the specified
557 * quick composite pool.
560 * Quick Composite Pool
563 /****f* Component Library: Quick Composite Pool/cl_qcpool_get
568 * The cl_qcpool_get function retrieves an object from a
569 * quick composite pool.
573 cl_pool_item_t *cl_qcpool_get(IN cl_qcpool_t * const p_pool);
577 * [in] Pointer to a cl_qcpool_t structure from which to retrieve
581 * Returns a pointer to a cl_pool_item_t for a composite object.
583 * Returns NULL if the pool is empty and can not be grown automatically.
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.
591 * Quick Composite Pool, cl_qcpool_get_tail, cl_qcpool_put,
592 * cl_qcpool_grow, cl_qcpool_count
595 /****f* Component Library: Quick Composite Pool/cl_qcpool_put
600 * The cl_qcpool_put function returns an object to a quick composite pool.
605 cl_qcpool_put(IN cl_qcpool_t * const p_pool,
606 IN cl_pool_item_t * const p_pool_item)
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);
614 /* return this lil' doggy to the pool */
615 cl_qlist_insert_head(&p_pool->free_list, &p_pool_item->list_item);
621 * [in] Pointer to a cl_qcpool_t structure to which to return
625 * [in] Pointer to a cl_pool_item_t structure for the object
629 * This function does not return a value.
632 * cl_qcpool_put places the returned object at the head of the pool.
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.
638 * Quick Composite Pool, cl_qcpool_put_tail, cl_qcpool_get
641 /****f* Component Library: Quick Composite Pool/cl_qcpool_put_list
646 * The cl_qcpool_put_list function returns a list of objects to the head of
647 * a quick composite pool.
652 cl_qcpool_put_list(IN cl_qcpool_t * const p_pool, IN cl_qlist_t * const p_list)
655 cl_list_item_t *p_item;
659 CL_ASSERT(p_pool->state == CL_INITIALIZED);
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);
671 /* return these lil' doggies to the pool */
672 cl_qlist_insert_list_head(&p_pool->free_list, p_list);
678 * [in] Pointer to a cl_qcpool_t structure to which to return
682 * [in] Pointer to a cl_qlist_t structure for the list of objects
686 * This function does not return a value.
689 * cl_qcpool_put_list places the returned objects at the head of the pool.
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.
695 * Quick Composite Pool, cl_qcpool_put, cl_qcpool_put_tail, cl_qcpool_get
698 /****f* Component Library: Quick Composite Pool/cl_qcpool_grow
703 * The cl_qcpool_grow function grows a quick composite pool by
704 * the specified number of objects.
708 cl_status_t cl_qcpool_grow(IN cl_qcpool_t * const p_pool, IN size_t obj_count);
712 * [in] Pointer to a cl_qcpool_t structure whose capacity to grow.
715 * [in] Number of objects by which to grow the pool.
718 * CL_SUCCESS if the quick composite pool grew successfully.
720 * CL_INSUFFICIENT_MEMORY if there was not enough memory to grow the
721 * quick composite pool.
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.
728 * It is not necessary to call cl_qcpool_grow if the pool is
729 * configured to grow automatically.
732 * Quick Composite Pool
736 #endif /* _CL_QUICK_COMPOSITE_POOL_H_ */