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 56 BEGIN_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 */ 104 typedef 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 */ 148 typedef 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 */ 187 typedef 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 */ 225 void 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 */ 254 static 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 */ 289 cl_status_t 290 cl_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 */ 366 static 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 */ 406 static 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 */ 434 static 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 */ 477 static inline void 478 cl_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 */ 527 static inline cl_status_t 528 cl_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 560 END_C_DECLS 561 #endif /* _CL_POOL_H_ */ 562