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 */ 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 */ 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 */ 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 */ 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 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 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 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