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 57 BEGIN_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 */ 111 typedef 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 */ 161 typedef 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 */ 200 typedef 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 */ 238 void 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 */ 267 static 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 */ 302 cl_status_t 303 cl_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 */ 387 static 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 */ 427 static 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 */ 457 static 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 */ 501 static inline void 502 cl_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 */ 551 static inline cl_status_t 552 cl_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 584 END_C_DECLS 585 #endif /* _CL_COMP_POOL_H_ */ 586