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