xref: /freebsd/contrib/ofed/opensm/include/complib/cl_qpool.h (revision 87181516ef48be852d5e5fee53c6e0dbfc62f21e)
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 
56 BEGIN_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 */
110 typedef 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 */
166 typedef 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 */
206 typedef 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 */
244 void 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 */
cl_is_qpool_inited(IN const cl_qpool_t * const p_pool)273 static 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 */
308 cl_status_t
309 cl_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 */
cl_qpool_destroy(IN cl_qpool_t * const p_pool)387 static 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 */
cl_qpool_count(IN cl_qpool_t * const p_pool)427 static 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 */
cl_qpool_get(IN cl_qpool_t * const p_pool)456 static 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 */
491 static inline void
cl_qpool_put(IN cl_qpool_t * const p_pool,IN cl_pool_item_t * const p_pool_item)492 cl_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 */
532 static inline void
cl_qpool_put_list(IN cl_qpool_t * const p_pool,IN cl_qlist_t * const p_list)533 cl_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 */
572 static inline cl_status_t
cl_qpool_grow(IN cl_qpool_t * const p_pool,IN const size_t obj_count)573 cl_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 
605 END_C_DECLS
606 #endif				/* _CL_QUICK_POOL_H_ */
607