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 composite pool. The quick composite pool 39 * manages a pool of composite objects. A composite object is an object 40 * that is made of multiple sub objects. 41 * It can grow to meet demand, limited only by system memory. 42 */ 43 44#ifndef _CL_QUICK_COMPOSITE_POOL_H_ 45#define _CL_QUICK_COMPOSITE_POOL_H_ 46 47#include <complib/cl_types.h> 48#include <complib/cl_qlist.h> 49 50#ifdef __cplusplus 51# define BEGIN_C_DECLS extern "C" { 52# define END_C_DECLS } 53#else /* !__cplusplus */ 54# define BEGIN_C_DECLS 55# define END_C_DECLS 56#endif /* __cplusplus */ 57 58BEGIN_C_DECLS 59/****h* Component Library/Quick Composite Pool 60* NAME 61* Quick Composite Pool 62* 63* DESCRIPTION 64* The Quick Composite Pool provides a self-contained and self-sustaining 65* pool of user defined composite objects. 66* 67* A composite object is an object that is composed of one or more 68* sub-objects, each of which needs to be treated separately for 69* initialization. Objects can be retrieved from the pool as long as there 70* is memory in the system. 71* 72* To aid in object oriented design, the Quick Composite Pool provides users 73* the ability to specify callbacks that are invoked for each object for 74* construction, initialization, and destruction. Constructor and destructor 75* callback functions may not fail. 76* 77* A Quick Composite Pool does not return memory to the system as the user 78* returns objects to the pool. The only method of returning memory to the 79* system is to destroy the pool. 80* 81* The Quick Composite Pool operates on cl_pool_item_t structures that 82* describe composite objects. This provides for more efficient memory use. 83* If using a cl_pool_item_t is not desired, the Composite Pool provides 84* similar functionality but operates on opaque objects. 85* 86* The Quick Composit Pool functions operate on a cl_qcpool_t structure 87* which should be treated as opaque and should be manipulated only through 88* the provided functions. 89* 90* SEE ALSO 91* Structures: 92* cl_qcpool_t, cl_pool_item_t 93* 94* Callbacks: 95* cl_pfn_qcpool_init_t, cl_pfn_qcpool_dtor_t 96* 97* Initialization/Destruction: 98* cl_qcpool_construct, cl_qcpool_init, cl_qcpool_destroy 99* 100* Manipulation: 101* cl_qcpool_get, cl_qcpool_put, cl_qcpool_put_list, cl_qcpool_grow 102* 103* Attributes: 104* cl_is_qcpool_inited, cl_qcpool_count 105*********/ 106/****s* Component Library: Quick Composite Pool/cl_pool_item_t 107* NAME 108* cl_pool_item_t 109* 110* DESCRIPTION 111* The cl_pool_item_t structure is used by pools to store objects. 112* 113* SYNOPSIS 114*/ 115typedef struct _cl_pool_item { 116 cl_list_item_t list_item; 117#ifdef _DEBUG_ 118 /* Pointer to the owner pool used for sanity checks. */ 119 struct _cl_qcpool *p_pool; 120#endif 121} cl_pool_item_t; 122/* 123* FIELDS 124* list_item 125* Used internally by the pool. Users should not use this field. 126* 127* p_pool 128* Used internally by the pool in debug builds to check for consistency. 129* 130* NOTES 131* The pool item structure is defined in such a way as to safely allow 132* users to cast from a pool item to a list item for storing items 133* retrieved from a quick pool in a quick list. 134* 135* SEE ALSO 136* Quick Composite Pool, cl_list_item_t 137*********/ 138 139/****i* Component Library: Quick List/cl_pool_obj_t 140* NAME 141* cl_pool_obj_t 142* 143* DESCRIPTION 144* The cl_pool_obj_t structure is used by pools to store objects. 145* 146* SYNOPSIS 147*/ 148typedef struct _cl_pool_obj { 149 /* The pool item must be the first item to allow casting. */ 150 cl_pool_item_t pool_item; 151 const void *p_object; 152} cl_pool_obj_t; 153/* 154* FIELDS 155* pool_item 156* Used internally by the pool. Users should not use this field. 157* 158* p_object 159* Pointer to the user's object being stored in the pool. 160* 161* NOTES 162* The pool object structure is used by non-quick pools to store object. 163* 164* SEE ALSO 165* cl_pool_item_t 166*********/ 167 168/****d* Component Library: Quick Composite Pool/cl_pfn_qcpool_init_t 169* NAME 170* cl_pfn_qcpool_init_t 171* 172* DESCRIPTION 173* The cl_pfn_qcpool_init_t function type defines the prototype for 174* functions used as initializer for objects being allocated by a 175* quick composite pool. 176* 177* SYNOPSIS 178*/ 179typedef cl_status_t 180 (*cl_pfn_qcpool_init_t) (IN void **const p_comp_array, 181 IN const uint32_t num_components, 182 IN void *context, 183 OUT cl_pool_item_t ** const pp_pool_item); 184/* 185* PARAMETERS 186* p_comp_array 187* [in] Pointer to the first entry in an array of pointers, each of 188* which points to a component that makes up a composite object. 189* 190* num_components 191* [in] Number of components that in the component array. 192* 193* context 194* [in] Context provided in a call to cl_qcpool_init. 195* 196* pp_pool_item 197* [out] Users should set this pointer to reference the cl_pool_item_t 198* structure that represents the composite object. This pointer must 199* not be NULL if the function returns CL_SUCCESS. 200* 201* RETURN VALUE 202* Return CL_SUCCESS to indicate that initialization of the object 203* was successful and that initialization of further objects may continue. 204* 205* Other cl_status_t values will be returned by cl_qcpool_init 206* and cl_qcpool_grow. 207* 208* NOTES 209* This function type is provided as function prototype reference for 210* the function provided by the user as a parameter to the 211* cl_qcpool_init function. 212* 213* The initializer is invoked once per allocated object, allowing the user 214* to chain components to form a composite object and perform any necessary 215* initialization. Returning a status other than CL_SUCCESS aborts a grow 216* operation, initiated either through cl_qcpool_init or cl_qcpool_grow, 217* and causes the initiating function to fail. Any non-CL_SUCCESS status 218* will be returned by the function that initiated the grow operation. 219* 220* All memory for the requested number of components is pre-allocated. Users 221* should include space in one of their components for the cl_pool_item_t 222* structure that will represent the composite object to avoid having to 223* allocate that structure in the initialization callback. Alternatively, 224* users may specify an additional component for the cl_pool_item_t structure. 225* 226* When later performing a cl_qcpool_get call, the return value is a pointer 227* to the cl_pool_item_t returned by this function in the pp_pool_item 228* parameter. Users must set pp_pool_item to a valid pointer to the 229* cl_pool_item_t representing the object if they return CL_SUCCESS. 230* 231* SEE ALSO 232* Quick Composite Pool, cl_qcpool_init 233*********/ 234 235/****d* Component Library: Quick Composite Pool/cl_pfn_qcpool_dtor_t 236* NAME 237* cl_pfn_qcpool_dtor_t 238* 239* DESCRIPTION 240* The cl_pfn_qcpool_dtor_t function type defines the prototype for 241* functions used as destructor for objects being deallocated by a 242* quick composite pool. 243* 244* SYNOPSIS 245*/ 246typedef void 247 (*cl_pfn_qcpool_dtor_t) (IN const cl_pool_item_t * const p_pool_item, 248 IN void *context); 249/* 250* PARAMETERS 251* p_pool_item 252* [in] Pointer to a cl_pool_item_t structure representing an object. 253* 254* context 255* [in] Context provided in a call to cl_qcpool_init. 256* 257* RETURN VALUE 258* This function does not return a value. 259* 260* NOTES 261* This function type is provided as function prototype reference for 262* the function provided by the user as an optional parameter to the 263* cl_qcpool_init function. 264* 265* The destructor is invoked once per allocated object, allowing the user 266* to perform any necessary cleanup. Users should not attempt to deallocate 267* the memory for the composite object, as the quick composite pool manages 268* object allocation and deallocation. 269* 270* SEE ALSO 271* Quick Composite Pool, cl_qcpool_init 272*********/ 273 274/****s* Component Library: Quick Composite Pool/cl_qcpool_t 275* NAME 276* cl_qcpool_t 277* 278* DESCRIPTION 279* Quick composite pool structure. 280* 281* The cl_qcpool_t structure should be treated as opaque and should be 282* manipulated only through the provided functions. 283* 284* SYNOPSIS 285*/ 286typedef struct _cl_qcpool { 287 uint32_t num_components; 288 size_t *component_sizes; 289 void **p_components; 290 size_t num_objects; 291 size_t max_objects; 292 size_t grow_size; 293 cl_pfn_qcpool_init_t pfn_init; 294 cl_pfn_qcpool_dtor_t pfn_dtor; 295 const void *context; 296 cl_qlist_t free_list; 297 cl_qlist_t alloc_list; 298 cl_state_t state; 299} cl_qcpool_t; 300/* 301* FIELDS 302* num_components 303* Number of components per object. 304* 305* component_sizes 306* Array of sizes, one for each component. 307* 308* p_components 309* Array of pointers to components, used for the constructor callback. 310* 311* num_objects 312* Number of objects managed by the pool 313* 314* grow_size 315* Number of objects to add when automatically growing the pool. 316* 317* pfn_init 318* Pointer to the user's initializer callback to invoke when initializing 319* new objects. 320* 321* pfn_dtor 322* Pointer to the user's destructor callback to invoke before deallocating 323* memory allocated for objects. 324* 325* context 326* User's provided context for callback functions, used by the pool 327* when invoking callbacks. 328* 329* free_list 330* Quick list of objects available. 331* 332* alloc_list 333* Quick list used to store information about allocations. 334* 335* state 336* State of the pool. 337* 338* SEE ALSO 339* Quick Composite Pool 340*********/ 341 342/****f* Component Library: Quick Composite Pool/cl_qcpool_construct 343* NAME 344* cl_qcpool_construct 345* 346* DESCRIPTION 347* The cl_qcpool_construct function constructs a quick composite pool. 348* 349* SYNOPSIS 350*/ 351void cl_qcpool_construct(IN cl_qcpool_t * const p_pool); 352/* 353* PARAMETERS 354* p_pool 355* [in] Pointer to a cl_qcpool_t structure whose state to initialize. 356* 357* RETURN VALUE 358* This function does not return a value. 359* 360* NOTES 361* Allows calling cl_qcpool_init, cl_qcpool_destroy, cl_is_qcpool_inited. 362* 363* Calling cl_qcpool_construct is a prerequisite to calling any other 364* quick composite pool function except cl_qcpool_init. 365* 366* SEE ALSO 367* Quick Composite Pool, cl_qcpool_init, cl_qcpool_destroy, 368* cl_is_qcpool_inited 369*********/ 370 371/****f* Component Library: Quick Composite Pool/cl_is_qcpool_inited 372* NAME 373* cl_is_qcpool_inited 374* 375* DESCRIPTION 376* The cl_is_qcpool_inited function returns whether a quick composite pool was 377* successfully initialized. 378* 379* SYNOPSIS 380*/ 381static inline uint32_t cl_is_qcpool_inited(IN const cl_qcpool_t * const p_pool) 382{ 383 /* CL_ASSERT that a non-null pointer is provided. */ 384 CL_ASSERT(p_pool); 385 /* CL_ASSERT that the pool is not in some invalid state. */ 386 CL_ASSERT(cl_is_state_valid(p_pool->state)); 387 388 return (p_pool->state == CL_INITIALIZED); 389} 390 391/* 392* PARAMETERS 393* p_pool 394* [in] Pointer to a cl_qcpool_t structure to check. 395* 396* RETURN VALUES 397* TRUE if the quick composite pool was initialized successfully. 398* 399* FALSE otherwise. 400* 401* NOTES 402* Allows checking the state of a quick composite pool to determine if 403* invoking member functions is appropriate. 404* 405* SEE ALSO 406* Quick Composite Pool 407*********/ 408 409/****f* Component Library: Quick Composite Pool/cl_qcpool_init 410* NAME 411* cl_qcpool_init 412* 413* DESCRIPTION 414* The cl_qcpool_init function initializes a quick composite pool for use. 415* 416* SYNOPSIS 417*/ 418cl_status_t 419cl_qcpool_init(IN cl_qcpool_t * const p_pool, 420 IN const size_t min_size, 421 IN const size_t max_size, 422 IN const size_t grow_size, 423 IN const size_t * const component_sizes, 424 IN const uint32_t num_components, 425 IN cl_pfn_qcpool_init_t pfn_initializer OPTIONAL, 426 IN cl_pfn_qcpool_dtor_t pfn_destructor OPTIONAL, 427 IN const void *const context); 428/* 429* PARAMETERS 430* p_pool 431* [in] Pointer to a cl_qcpool_t structure to initialize. 432* 433* min_size 434* [in] Minimum number of objects that the pool should support. All 435* necessary allocations to allow storing the minimum number of items 436* are performed at initialization time, and all necessary callbacks 437* successfully invoked. 438* 439* max_size 440* [in] Maximum number of objects to which the pool is allowed to grow. 441* A value of zero specifies no maximum. 442* 443* grow_size 444* [in] Number of objects to allocate when incrementally growing the pool. 445* A value of zero disables automatic growth. 446* 447* component_sizes 448* [in] Pointer to the first entry in an array of sizes describing, 449* in order, the sizes of the components that make up a composite object. 450* 451* num_components 452* [in] Number of components that make up a composite object. 453* 454* pfn_initializer 455* [in] Initializer callback to invoke for every new object when growing 456* the pool. This parameter may be NULL only if the objects stored in 457* the quick composite pool consist of only one component. If NULL, the 458* pool assumes the cl_pool_item_t structure describing objects is 459* located at the head of each object. See the cl_pfn_qcpool_init_t 460* function type declaration for details about the callback function. 461* 462* pfn_destructor 463* [in] Destructor callback to invoke for every object before memory for 464* that object is freed. This parameter is optional and may be NULL. 465* See the cl_pfn_qcpool_dtor_t function type declaration for details 466* about the callback function. 467* 468* context 469* [in] Value to pass to the callback functions to provide context. 470* 471* RETURN VALUES 472* CL_SUCCESS if the quick composite pool was initialized successfully. 473* 474* CL_INSUFFICIENT_MEMORY if there was not enough memory to initialize the 475* quick composite pool. 476* 477* CL_INVALID_SETTING if a NULL constructor was provided for composite objects 478* consisting of more than one component. Also returns CL_INVALID_SETTING if 479* the maximum size is non-zero and less than the minimum size. 480* 481* Other cl_status_t value returned by optional initialization callback function 482* specified by the pfn_initializer parameter. 483* 484* If initialization fails, the pool is left in a destroyed state. Callers 485* may still safely call cl_qcpool_destroy. 486* 487* NOTES 488* cl_qcpool_init initializes, and if necessary, grows the pool to 489* the capacity desired. 490* 491* SEE ALSO 492* Quick Composite Pool, cl_qcpool_construct, cl_qcpool_destroy, 493* cl_qcpool_get, cl_qcpool_put, cl_qcpool_grow, 494* cl_qcpool_count, cl_pfn_qcpool_init_t, cl_pfn_qcpool_dtor_t 495*********/ 496 497/****f* Component Library: Quick Composite Pool/cl_qcpool_destroy 498* NAME 499* cl_qcpool_destroy 500* 501* DESCRIPTION 502* The cl_qcpool_destroy function destroys a quick composite pool. 503* 504* SYNOPSIS 505*/ 506void cl_qcpool_destroy(IN cl_qcpool_t * const p_pool); 507/* 508* PARAMETERS 509* p_pool 510* [in] Pointer to a cl_qcpool_t structure to destroy. 511* 512* RETURN VALUE 513* This function does not return a value. 514* 515* NOTES 516* All memory allocated for composite objects is freed. The destructor 517* callback, if any, will be invoked for every allocated object. Further 518* operations on the composite pool should not be attempted after 519* cl_qcpool_destroy is invoked. 520* 521* This function should only be called after a call to 522* cl_qcpool_construct or cl_qcpool_init. 523* 524* In a debug build, cl_qcpool_destroy asserts that all objects are in 525* the pool. 526* 527* SEE ALSO 528* Quick Composite Pool, cl_qcpool_construct, cl_qcpool_init 529*********/ 530 531/****f* Component Library: Quick Composite Pool/cl_qcpool_count 532* NAME 533* cl_qcpool_count 534* 535* DESCRIPTION 536* The cl_qcpool_count function returns the number of available objects 537* in a quick composite pool. 538* 539* SYNOPSIS 540*/ 541static inline size_t cl_qcpool_count(IN cl_qcpool_t * const p_pool) 542{ 543 CL_ASSERT(p_pool); 544 CL_ASSERT(p_pool->state == CL_INITIALIZED); 545 546 return (cl_qlist_count(&p_pool->free_list)); 547} 548 549/* 550* PARAMETERS 551* p_pool 552* [in] Pointer to a cl_qcpool_t structure for which the number of 553* available objects is requested. 554* 555* RETURN VALUE 556* Returns the number of objects available in the specified 557* quick composite pool. 558* 559* SEE ALSO 560* Quick Composite Pool 561*********/ 562 563/****f* Component Library: Quick Composite Pool/cl_qcpool_get 564* NAME 565* cl_qcpool_get 566* 567* DESCRIPTION 568* The cl_qcpool_get function retrieves an object from a 569* quick composite pool. 570* 571* SYNOPSIS 572*/ 573cl_pool_item_t *cl_qcpool_get(IN cl_qcpool_t * const p_pool); 574/* 575* PARAMETERS 576* p_pool 577* [in] Pointer to a cl_qcpool_t structure from which to retrieve 578* an object. 579* 580* RETURN VALUES 581* Returns a pointer to a cl_pool_item_t for a composite object. 582* 583* Returns NULL if the pool is empty and can not be grown automatically. 584* 585* NOTES 586* cl_qcpool_get returns the object at the head of the pool. If the pool is 587* empty, it is automatically grown to accommodate this request unless the 588* grow_size parameter passed to the cl_qcpool_init function was zero. 589* 590* SEE ALSO 591* Quick Composite Pool, cl_qcpool_get_tail, cl_qcpool_put, 592* cl_qcpool_grow, cl_qcpool_count 593*********/ 594 595/****f* Component Library: Quick Composite Pool/cl_qcpool_put 596* NAME 597* cl_qcpool_put 598* 599* DESCRIPTION 600* The cl_qcpool_put function returns an object to a quick composite pool. 601* 602* SYNOPSIS 603*/ 604static inline void 605cl_qcpool_put(IN cl_qcpool_t * const p_pool, 606 IN cl_pool_item_t * const p_pool_item) 607{ 608 CL_ASSERT(p_pool); 609 CL_ASSERT(p_pool->state == CL_INITIALIZED); 610 CL_ASSERT(p_pool_item); 611 /* Make sure items being returned came from the specified pool. */ 612 CL_ASSERT(p_pool_item->p_pool == p_pool); 613 614 /* return this lil' doggy to the pool */ 615 cl_qlist_insert_head(&p_pool->free_list, &p_pool_item->list_item); 616} 617 618/* 619* PARAMETERS 620* p_pool 621* [in] Pointer to a cl_qcpool_t structure to which to return 622* an object. 623* 624* p_pool_item 625* [in] Pointer to a cl_pool_item_t structure for the object 626* being returned. 627* 628* RETURN VALUE 629* This function does not return a value. 630* 631* NOTES 632* cl_qcpool_put places the returned object at the head of the pool. 633* 634* The object specified by the p_pool_item parameter must have been 635* retrieved from the pool by a previous call to cl_qcpool_get. 636* 637* SEE ALSO 638* Quick Composite Pool, cl_qcpool_put_tail, cl_qcpool_get 639*********/ 640 641/****f* Component Library: Quick Composite Pool/cl_qcpool_put_list 642* NAME 643* cl_qcpool_put_list 644* 645* DESCRIPTION 646* The cl_qcpool_put_list function returns a list of objects to the head of 647* a quick composite pool. 648* 649* SYNOPSIS 650*/ 651static inline void 652cl_qcpool_put_list(IN cl_qcpool_t * const p_pool, IN cl_qlist_t * const p_list) 653{ 654#ifdef _DEBUG_ 655 cl_list_item_t *p_item; 656#endif 657 658 CL_ASSERT(p_pool); 659 CL_ASSERT(p_pool->state == CL_INITIALIZED); 660 CL_ASSERT(p_list); 661 662#ifdef _DEBUG_ 663 /* Chech that all items in the list came from this pool. */ 664 p_item = cl_qlist_head(p_list); 665 while (p_item != cl_qlist_end(p_list)) { 666 CL_ASSERT(((cl_pool_item_t *) p_item)->p_pool == p_pool); 667 p_item = cl_qlist_next(p_item); 668 } 669#endif 670 671 /* return these lil' doggies to the pool */ 672 cl_qlist_insert_list_head(&p_pool->free_list, p_list); 673} 674 675/* 676* PARAMETERS 677* p_pool 678* [in] Pointer to a cl_qcpool_t structure to which to return 679* a list of objects. 680* 681* p_list 682* [in] Pointer to a cl_qlist_t structure for the list of objects 683* being returned. 684* 685* RETURN VALUE 686* This function does not return a value. 687* 688* NOTES 689* cl_qcpool_put_list places the returned objects at the head of the pool. 690* 691* The objects in the list specified by the p_list parameter must have been 692* retrieved from the pool by a previous call to cl_qcpool_get. 693* 694* SEE ALSO 695* Quick Composite Pool, cl_qcpool_put, cl_qcpool_put_tail, cl_qcpool_get 696*********/ 697 698/****f* Component Library: Quick Composite Pool/cl_qcpool_grow 699* NAME 700* cl_qcpool_grow 701* 702* DESCRIPTION 703* The cl_qcpool_grow function grows a quick composite pool by 704* the specified number of objects. 705* 706* SYNOPSIS 707*/ 708cl_status_t cl_qcpool_grow(IN cl_qcpool_t * const p_pool, IN size_t obj_count); 709/* 710* PARAMETERS 711* p_pool 712* [in] Pointer to a cl_qcpool_t structure whose capacity to grow. 713* 714* obj_count 715* [in] Number of objects by which to grow the pool. 716* 717* RETURN VALUES 718* CL_SUCCESS if the quick composite pool grew successfully. 719* 720* CL_INSUFFICIENT_MEMORY if there was not enough memory to grow the 721* quick composite pool. 722* 723* cl_status_t value returned by optional initialization callback function 724* specified by the pfn_initializer parameter passed to the 725* cl_qcpool_init function. 726* 727* NOTES 728* It is not necessary to call cl_qcpool_grow if the pool is 729* configured to grow automatically. 730* 731* SEE ALSO 732* Quick Composite Pool 733*********/ 734 735END_C_DECLS 736#endif /* _CL_QUICK_COMPOSITE_POOL_H_ */ 737