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