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 pool.
39 *	The quick pool manages a pool of objects.
40 *	The pool can grow to meet demand, limited only by system memory.
41 */
42
43#ifndef _CL_QUICK_POOL_H_
44#define _CL_QUICK_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/Quick Pool
58* NAME
59*	Quick Pool
60*
61* DESCRIPTION
62*	The quick pool provides a self-contained and self-sustaining pool
63*	of user defined objects.
64*
65*	To aid in object oriented design, the quick 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 quick 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 quick pool operates on cl_pool_item_t structures that describe
75*	objects. This can provides for more efficient memory use and operation.
76*	If using a cl_pool_item_t is not desired, the Pool provides similar
77*	functionality but operates on opaque objects.
78*
79*	The quick pool functions operates on a cl_qpool_t structure which should
80*	be treated as opaque and should be manipulated only through the provided
81*	functions.
82*
83* SEE ALSO
84*	Structures:
85*		cl_qpool_t, cl_pool_item_t
86*
87*	Callbacks:
88*		cl_pfn_qpool_init_t, cl_pfn_qpool_dtor_t
89*
90*	Initialization/Destruction:
91*		cl_qpool_construct, cl_qpool_init, cl_qpool_destroy
92*
93*	Manipulation:
94*		cl_qpool_get, cl_qpool_put, cl_qpool_put_list, cl_qpool_grow
95*
96*	Attributes:
97*		cl_is_qpool_inited, cl_qpool_count
98*********/
99/****d* Component Library: Quick Pool/cl_pfn_qpool_init_t
100* NAME
101*	cl_pfn_qpool_init_t
102*
103* DESCRIPTION
104*	The cl_pfn_qpool_init_t function type defines the prototype for
105*	functions used as constructor for objects being allocated by a
106*	quick pool.
107*
108* SYNOPSIS
109*/
110typedef cl_status_t
111    (*cl_pfn_qpool_init_t) (IN void *const p_object,
112			    IN void *context,
113			    OUT cl_pool_item_t ** const pp_pool_item);
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_qpool_init.
121*
122* RETURN VALUES
123*	Return CL_SUCCESS to indicate 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_qcpool_init
127*	and cl_qcpool_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_qpool_init function.
133*
134*	The initializer is invoked once per allocated object, allowing the user
135*	to perform any necessary initialization.  Returning a status other than
136*	CL_SUCCESS aborts a grow operation, initiated either through cl_qcpool_init
137*	or cl_qcpool_grow, causing the initiating function to fail.
138*	Any non-CL_SUCCESS status will be returned by the function that initiated
139*	the grow operation.
140*
141*	All memory for the object is pre-allocated.  Users should include space in
142*	their objects for the cl_pool_item_t structure that will represent the
143*	object to avoid having to allocate that structure in the initialization
144*	callback.
145*
146*	When later performing a cl_qcpool_get call, the return value is a pointer
147*	to the cl_pool_item_t returned by this function in the pp_pool_item
148*	parameter.  Users must set pp_pool_item to a valid pointer to the
149*	cl_pool_item_t representing the object if they return CL_SUCCESS.
150*
151* SEE ALSO
152*	Quick Pool, cl_qpool_init
153*********/
154
155/****d* Component Library: Quick Pool/cl_pfn_qpool_dtor_t
156* NAME
157*	cl_pfn_qpool_dtor_t
158*
159* DESCRIPTION
160*	The cl_pfn_qpool_dtor_t function type defines the prototype for
161*	functions used as destructor for objects being deallocated by a
162*	quick pool.
163*
164* SYNOPSIS
165*/
166typedef void
167 (*cl_pfn_qpool_dtor_t) (IN const cl_pool_item_t * const p_pool_item,
168			 IN void *context);
169/*
170* PARAMETERS
171*	p_pool_item
172*		[in] Pointer to a cl_pool_item_t structure representing an object.
173*
174*	context
175*		[in] Context provided in a call to cl_qpool_init.
176*
177* RETURN VALUE
178*	This function does not return a value.
179*
180* NOTES
181*	This function type is provided as function prototype reference for
182*	the function provided by the user as an optional parameter to the
183*	cl_qpool_init function.
184*
185*	The destructor is invoked once per allocated object, allowing the user
186*	to perform any necessary cleanup. Users should not attempt to deallocate
187*	the memory for the object, as the quick pool manages object
188*	allocation and deallocation.
189*
190* SEE ALSO
191*	Quick Pool, cl_qpool_init
192*********/
193
194/****s* Component Library: Quick Pool/cl_qpool_t
195* NAME
196*	cl_qpool_t
197*
198* DESCRIPTION
199*	Quick pool structure.
200*
201*	The cl_qpool_t structure should be treated as opaque and should be
202*	manipulated only through the provided functions.
203*
204* SYNOPSIS
205*/
206typedef struct _cl_qpool {
207	cl_qcpool_t qcpool;
208	cl_pfn_qpool_init_t pfn_init;
209	cl_pfn_qpool_dtor_t pfn_dtor;
210	const void *context;
211} cl_qpool_t;
212/*
213* FIELDS
214*	qcpool
215*		Quick composite pool that manages all objects.
216*
217*	pfn_init
218*		Pointer to the user's initializer callback, used by the pool
219*		to translate the quick composite pool's initializer callback to
220*		a quick pool initializer callback.
221*
222*	pfn_dtor
223*		Pointer to the user's destructor callback, used by the pool
224*		to translate the quick composite pool's destructor callback to
225*		a quick pool destructor callback.
226*
227*	context
228*		User's provided context for callback functions, used by the pool
229*		to when invoking callbacks.
230*
231* SEE ALSO
232*	Quick Pool
233*********/
234
235/****f* Component Library: Quick Pool/cl_qpool_construct
236* NAME
237*	cl_qpool_construct
238*
239* DESCRIPTION
240*	The cl_qpool_construct function constructs a quick pool.
241*
242* SYNOPSIS
243*/
244void cl_qpool_construct(IN cl_qpool_t * const p_pool);
245/*
246* PARAMETERS
247*	p_pool
248*		[in] Pointer to a cl_qpool_t structure whose state to initialize.
249*
250* RETURN VALUE
251*	This function does not return a value.
252*
253* NOTES
254*	Allows calling cl_qpool_init, cl_qpool_destroy, cl_is_qpool_inited.
255*
256*	Calling cl_qpool_construct is a prerequisite to calling any other
257*	quick pool function except cl_pool_init.
258*
259* SEE ALSO
260*	Quick Pool, cl_qpool_init, cl_qpool_destroy, cl_is_qpool_inited.
261*********/
262
263/****f* Component Library: Quick Pool/cl_is_qpool_inited
264* NAME
265*	cl_is_qpool_inited
266*
267* DESCRIPTION
268*	The cl_is_qpool_inited function returns whether a quick pool was
269*	successfully initialized.
270*
271* SYNOPSIS
272*/
273static inline uint32_t cl_is_qpool_inited(IN const cl_qpool_t * const p_pool)
274{
275	/* CL_ASSERT that a non-null pointer is provided. */
276	CL_ASSERT(p_pool);
277	return (cl_is_qcpool_inited(&p_pool->qcpool));
278}
279
280/*
281* PARAMETERS
282*	p_pool
283*		[in] Pointer to a cl_qpool_t structure whose initialization state
284*		to check.
285*
286* RETURN VALUES
287*	TRUE if the quick pool was initialized successfully.
288*
289*	FALSE otherwise.
290*
291* NOTES
292*	Allows checking the state of a quick pool to determine if
293*	invoking member functions is appropriate.
294*
295* SEE ALSO
296*	Quick Pool
297*********/
298
299/****f* Component Library: Quick Pool/cl_qpool_init
300* NAME
301*	cl_qpool_init
302*
303* DESCRIPTION
304*	The cl_qpool_init function initializes a quick pool for use.
305*
306* SYNOPSIS
307*/
308cl_status_t
309cl_qpool_init(IN cl_qpool_t * const p_pool,
310	      IN const size_t min_size,
311	      IN const size_t max_size,
312	      IN const size_t grow_size,
313	      IN const size_t object_size,
314	      IN cl_pfn_qpool_init_t pfn_initializer OPTIONAL,
315	      IN cl_pfn_qpool_dtor_t pfn_destructor OPTIONAL,
316	      IN const void *const context);
317/*
318* PARAMETERS
319*	p_pool
320*		[in] Pointer to a cl_qpool_t structure to initialize.
321*
322*	min_size
323*		[in] Minimum number of objects that the pool should support. All
324*		necessary allocations to allow storing the minimum number of items
325*		are performed at initialization time, and all necessary callbacks
326*		successfully invoked.
327*
328*	max_size
329*		[in] Maximum number of objects to which the pool is allowed to grow.
330*		A value of zero specifies no maximum.
331*
332*	grow_size
333*		[in] Number of objects to allocate when incrementally growing the pool.
334*		A value of zero disables automatic growth.
335*
336*	object_size
337*		[in] Size, in bytes, of each object.
338*
339*	pfn_initializer
340*		[in] Initialization callback to invoke for every new object when
341*		growing the pool. This parameter is optional and may be NULL. If NULL,
342*		the pool assumes the cl_pool_item_t structure describing objects is
343*		located at the head of each object. See the cl_pfn_qpool_init_t
344*		function type declaration for details about the callback function.
345*
346*	pfn_destructor
347*		[in] Destructor callback to invoke for every object before memory for
348*		that object is freed. This parameter is optional and may be NULL.
349*		See the cl_pfn_qpool_dtor_t function type declaration for details
350*		about the callback function.
351*
352*	context
353*		[in] Value to pass to the callback functions to provide context.
354*
355* RETURN VALUES
356*	CL_SUCCESS if the quick pool was initialized successfully.
357*
358*	CL_INSUFFICIENT_MEMORY if there was not enough memory to initialize the
359*	quick pool.
360*
361*	CL_INVALID_SETTING if a the maximum size is non-zero and less than the
362*	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_qpool_init initializes, and if necessary, grows the pool to
369*	the capacity desired.
370*
371* SEE ALSO
372*	Quick Pool, cl_qpool_construct, cl_qpool_destroy,
373*	cl_qpool_get, cl_qpool_put, cl_qpool_grow,
374*	cl_qpool_count, cl_pfn_qpool_init_t, cl_pfn_qpool_init_t,
375*	cl_pfn_qpool_dtor_t
376*********/
377
378/****f* Component Library: Quick Pool/cl_qpool_destroy
379* NAME
380*	cl_qpool_destroy
381*
382* DESCRIPTION
383*	The cl_qpool_destroy function destroys a quick pool.
384*
385* SYNOPSIS
386*/
387static inline void cl_qpool_destroy(IN cl_qpool_t * const p_pool)
388{
389	CL_ASSERT(p_pool);
390	cl_qcpool_destroy(&p_pool->qcpool);
391}
392
393/*
394* PARAMETERS
395*	p_pool
396*		[in] Pointer to a cl_qpool_t structure to destroy.
397*
398* RETURN VALUE
399*	This function does not return a value.
400*
401* NOTES
402*	All memory allocated for objects is freed. The destructor callback,
403*	if any, will be invoked for every allocated object. Further operations
404*	on the pool should not be attempted after cl_qpool_destroy
405*	is invoked.
406*
407*	This function should only be called after a call to
408*	cl_qpool_construct or cl_qpool_init.
409*
410*	In a debug build, cl_qpool_destroy asserts that all objects are in
411*	the pool.
412*
413* SEE ALSO
414*	Quick Pool, cl_qpool_construct, cl_qpool_init
415*********/
416
417/****f* Component Library: Quick Pool/cl_qpool_count
418* NAME
419*	cl_qpool_count
420*
421* DESCRIPTION
422*	The cl_qpool_count function returns the number of available objects
423*	in a quick pool.
424*
425* SYNOPSIS
426*/
427static inline size_t cl_qpool_count(IN cl_qpool_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_qpool_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 quick pool.
441*
442* SEE ALSO
443*	Quick Pool
444*********/
445
446/****f* Component Library: Quick Pool/cl_qpool_get
447* NAME
448*	cl_qpool_get
449*
450* DESCRIPTION
451*	The cl_qpool_get function retrieves an object from a
452*	quick pool.
453*
454* SYNOPSIS
455*/
456static inline cl_pool_item_t *cl_qpool_get(IN cl_qpool_t * const p_pool)
457{
458	CL_ASSERT(p_pool);
459	return (cl_qcpool_get(&p_pool->qcpool));
460}
461
462/*
463* PARAMETERS
464*	p_pool
465*		[in] Pointer to a cl_qpool_t structure from which to retrieve
466*		an object.
467*
468* RETURN VALUES
469*	Returns a pointer to a cl_pool_item_t for an object.
470*
471*	Returns NULL if the pool is empty and can not be grown automatically.
472*
473* NOTES
474*	cl_qpool_get returns the object at the head of the pool. If the pool is
475*	empty, it is automatically grown to accommodate this request unless the
476*	grow_size parameter passed to the cl_qpool_init function was zero.
477*
478* SEE ALSO
479*	Quick Pool, cl_qpool_get_tail, cl_qpool_put, cl_qpool_grow, cl_qpool_count
480*********/
481
482/****f* Component Library: Quick Pool/cl_qpool_put
483* NAME
484*	cl_qpool_put
485*
486* DESCRIPTION
487*	The cl_qpool_put function returns an object to the head of a quick pool.
488*
489* SYNOPSIS
490*/
491static inline void
492cl_qpool_put(IN cl_qpool_t * const p_pool,
493	     IN cl_pool_item_t * const p_pool_item)
494{
495	CL_ASSERT(p_pool);
496	cl_qcpool_put(&p_pool->qcpool, p_pool_item);
497}
498
499/*
500* PARAMETERS
501*	p_pool
502*		[in] Pointer to a cl_qpool_t structure to which to return
503*		an object.
504*
505*	p_pool_item
506*		[in] Pointer to a cl_pool_item_t structure for the object
507*		being returned.
508*
509* RETURN VALUE
510*	This function does not return a value.
511*
512* NOTES
513*	cl_qpool_put places the returned object at the head of the pool.
514*
515*	The object specified by the p_pool_item parameter must have been
516*	retrieved from the pool by a previous call to cl_qpool_get.
517*
518* SEE ALSO
519*	Quick Pool, cl_qpool_put_tail, cl_qpool_get
520*********/
521
522/****f* Component Library: Quick Pool/cl_qpool_put_list
523* NAME
524*	cl_qpool_put_list
525*
526* DESCRIPTION
527*	The cl_qpool_put_list function returns a list of objects to the head
528*	of a quick pool.
529*
530* SYNOPSIS
531*/
532static inline void
533cl_qpool_put_list(IN cl_qpool_t * const p_pool, IN cl_qlist_t * const p_list)
534{
535	CL_ASSERT(p_pool);
536	cl_qcpool_put_list(&p_pool->qcpool, p_list);
537}
538
539/*
540* PARAMETERS
541*	p_pool
542*		[in] Pointer to a cl_qpool_t structure to which to return
543*		a list of objects.
544*
545*	p_list
546*		[in] Pointer to a cl_qlist_t structure for the list of objects
547*		being returned.
548*
549* RETURN VALUE
550*	This function does not return a value.
551*
552* NOTES
553*	cl_qpool_put_list places the returned objects at the head of the pool.
554*
555*	The objects in the list specified by the p_list parameter must have been
556*	retrieved from the pool by a previous call to cl_qpool_get.
557*
558* SEE ALSO
559*	Quick Pool, cl_qpool_put, cl_qpool_put_tail, cl_qpool_get
560*********/
561
562/****f* Component Library: Quick Pool/cl_qpool_grow
563* NAME
564*	cl_qpool_grow
565*
566* DESCRIPTION
567*	The cl_qpool_grow function grows a quick pool by
568*	the specified number of objects.
569*
570* SYNOPSIS
571*/
572static inline cl_status_t
573cl_qpool_grow(IN cl_qpool_t * const p_pool, IN const size_t obj_count)
574{
575	CL_ASSERT(p_pool);
576	return (cl_qcpool_grow(&p_pool->qcpool, obj_count));
577}
578
579/*
580* PARAMETERS
581*	p_pool
582*		[in] Pointer to a cl_qpool_t structure whose capacity to grow.
583*
584*	obj_count
585*		[in] Number of objects by which to grow the pool.
586*
587* RETURN VALUES
588*	CL_SUCCESS if the quick pool grew successfully.
589*
590*	CL_INSUFFICIENT_MEMORY if there was not enough memory to grow the
591*	quick pool.
592*
593*	cl_status_t value returned by optional initialization callback function
594*	specified by the pfn_initializer parameter passed to the
595*	cl_qpool_init function.
596*
597* NOTES
598*	It is not necessary to call cl_qpool_grow if the pool is
599*	configured to grow automatically.
600*
601* SEE ALSO
602*	Quick Pool
603*********/
604
605END_C_DECLS
606#endif				/* _CL_QUICK_POOL_H_ */
607