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 list. 39 */ 40 41 #ifndef _CL_LIST_H_ 42 #define _CL_LIST_H_ 43 44 #include <complib/cl_qlist.h> 45 #include <complib/cl_qpool.h> 46 47 #ifdef __cplusplus 48 # define BEGIN_C_DECLS extern "C" { 49 # define END_C_DECLS } 50 #else /* !__cplusplus */ 51 # define BEGIN_C_DECLS 52 # define END_C_DECLS 53 #endif /* __cplusplus */ 54 55 BEGIN_C_DECLS 56 /****h* Component Library/List 57 * NAME 58 * List 59 * 60 * DESCRIPTION 61 * List stores objects in a doubly linked list. 62 * 63 * Unlike quick list, users pass pointers to the object being stored, rather 64 * than to a cl_list_item_t structure. Insertion operations on a list can 65 * fail, and callers should trap for such failures. 66 * 67 * Use quick list in situations where insertion failures cannot be tolerated. 68 * 69 * List is not thread safe, and users must provide serialization. 70 * 71 * The list functions operates on a cl_list_t structure which should be 72 * treated as opaque and should be manipulated only through the provided 73 * functions. 74 * 75 * SEE ALSO 76 * Types: 77 * cl_list_iterator_t 78 * 79 * Structures: 80 * cl_list_t 81 * 82 * Callbacks: 83 * cl_pfn_list_apply_t, cl_pfn_list_find_t 84 * 85 * Initialization/Destruction: 86 * cl_list_construct, cl_list_init, cl_list_destroy 87 * 88 * Iteration: 89 * cl_list_next, cl_list_prev, cl_list_head, cl_list_tail, 90 * cl_list_end 91 * 92 * Manipulation: 93 * cl_list_insert_head, cl_list_insert_tail, 94 * cl_list_insert_array_head, cl_list_insert_array_tail, 95 * cl_list_insert_prev, cl_list_insert_next, 96 * cl_list_remove_head, cl_list_remove_tail, 97 * cl_list_remove_object, cl_list_remove_item, cl_list_remove_all 98 * 99 * Search: 100 * cl_is_object_in_list, cl_list_find_from_head, cl_list_find_from_tail, 101 * cl_list_apply_func 102 * 103 * Attributes: 104 * cl_list_count, cl_is_list_empty, cl_is_list_inited 105 *********/ 106 /****s* Component Library: List/cl_list_t 107 * NAME 108 * cl_list_t 109 * 110 * DESCRIPTION 111 * List structure. 112 * 113 * The cl_list_t structure should be treated as opaque and should be 114 * manipulated only through the provided functions. 115 * 116 * SYNOPSIS 117 */ 118 typedef struct _cl_list { 119 cl_qlist_t list; 120 cl_qpool_t list_item_pool; 121 } cl_list_t; 122 /* 123 * FIELDS 124 * list 125 * Quick list of items stored in the list. 126 * 127 * list_item_pool 128 * Quick pool of list objects for storing objects in the quick list. 129 * 130 * SEE ALSO 131 * List 132 *********/ 133 134 /****d* Component Library: List/cl_list_iterator_t 135 * NAME 136 * cl_list_iterator_t 137 * 138 * DESCRIPTION 139 * Iterator type used to walk a list. 140 * 141 * SYNOPSIS 142 */ 143 typedef const cl_list_item_t *cl_list_iterator_t; 144 /* 145 * NOTES 146 * The iterator should be treated as opaque to prevent corrupting the list. 147 * 148 * SEE ALSO 149 * List, cl_list_head, cl_list_tail, cl_list_next, cl_list_prev, 150 * cl_list_obj 151 *********/ 152 153 /****d* Component Library: List/cl_pfn_list_apply_t 154 * NAME 155 * cl_pfn_list_apply_t 156 * 157 * DESCRIPTION 158 * The cl_pfn_list_apply_t function type defines the prototype for functions 159 * used to iterate objects in a list. 160 * 161 * SYNOPSIS 162 */ 163 typedef void 164 (*cl_pfn_list_apply_t) (IN void *const p_object, IN void *context); 165 /* 166 * PARAMETERS 167 * p_object 168 * [in] Pointer to an object stored in a list. 169 * 170 * context 171 * [in] Context provided in a call to cl_list_apply_func. 172 * 173 * RETURN VALUE 174 * This function does not return a value. 175 * 176 * NOTES 177 * This function type is provided as function prototype reference for the 178 * function provided by users as a parameter to the cl_list_apply_func 179 * function. 180 * 181 * SEE ALSO 182 * List, cl_list_apply_func 183 *********/ 184 185 /****d* Component Library: List/cl_pfn_list_find_t 186 * NAME 187 * cl_pfn_list_find_t 188 * 189 * DESCRIPTION 190 * The cl_pfn_list_find_t function type defines the prototype for functions 191 * used to find objects in a list. 192 * 193 * SYNOPSIS 194 */ 195 typedef cl_status_t 196 (*cl_pfn_list_find_t) (IN const void *const p_object, IN void *context); 197 /* 198 * PARAMETERS 199 * p_object 200 * [in] Pointer to an object stored in a list. 201 * 202 * context 203 * [in] Context provided in a call to ListFindFromHead or ListFindFromTail. 204 * 205 * RETURN VALUES 206 * Return CL_SUCCESS if the desired item was found. This stops list iteration. 207 * 208 * Return CL_NOT_FOUND to continue the list iteration. 209 * 210 * NOTES 211 * This function type is provided as function prototype reference for the 212 * function provided by users as a parameter to the cl_list_find_from_head 213 * and cl_list_find_from_tail functions. 214 * 215 * SEE ALSO 216 * List, cl_list_find_from_head, cl_list_find_from_tail 217 *********/ 218 219 /****f* Component Library: List/cl_list_construct 220 * NAME 221 * cl_list_construct 222 * 223 * DESCRIPTION 224 * The cl_list_construct function constructs a list. 225 * 226 * SYNOPSIS 227 */ 228 void cl_list_construct(IN cl_list_t * const p_list); 229 /* 230 * PARAMETERS 231 * p_list 232 * [in] Pointer to cl_list_t object whose state to initialize. 233 * 234 * RETURN VALUE 235 * This function does not return a value. 236 * 237 * NOTES 238 * Allows calling cl_list_init, cl_list_destroy and cl_is_list_inited. 239 * 240 * Calling cl_list_construct is a prerequisite to calling any other 241 * list function except cl_list_init. 242 * 243 * SEE ALSO 244 * List, cl_list_init, cl_list_destroy, cl_is_list_inited 245 *********/ 246 247 /****f* Component Library: List/cl_is_list_inited 248 * NAME 249 * cl_is_list_inited 250 * 251 * DESCRIPTION 252 * The cl_is_list_inited function returns whether a list was 253 * initialized successfully. 254 * 255 * SYNOPSIS 256 */ 257 static inline boolean_t cl_is_list_inited(IN const cl_list_t * const p_list) 258 { 259 /* CL_ASSERT that a non-null pointer is provided. */ 260 CL_ASSERT(p_list); 261 /* 262 * The pool is the last thing initialized. If it is initialized, the 263 * list is initialized too. 264 */ 265 return (cl_is_qpool_inited(&p_list->list_item_pool)); 266 } 267 268 /* 269 * PARAMETERS 270 * p_list 271 * [in] Pointer to a cl_list_t structure whose initilization state 272 * to check. 273 * 274 * RETURN VALUES 275 * TRUE if the list was initialized successfully. 276 * 277 * FALSE otherwise. 278 * 279 * NOTES 280 * Allows checking the state of a list to determine if invoking 281 * member functions is appropriate. 282 * 283 * SEE ALSO 284 * List 285 *********/ 286 287 /****f* Component Library: List/cl_list_init 288 * NAME 289 * cl_list_init 290 * 291 * DESCRIPTION 292 * The cl_list_init function initializes a list for use. 293 * 294 * SYNOPSIS 295 */ 296 cl_status_t 297 cl_list_init(IN cl_list_t * const p_list, IN const size_t min_items); 298 /* 299 * PARAMETERS 300 * p_list 301 * [in] Pointer to cl_list_t structure to initialize. 302 * 303 * min_items 304 * [in] Minimum number of items that can be stored. All necessary 305 * allocations to allow storing the minimum number of items is performed 306 * at initialization time. 307 * 308 * RETURN VALUES 309 * CL_SUCCESS if the list was initialized successfully. 310 * 311 * CL_INSUFFICIENT_MEMORY if there was not enough memory for initialization. 312 * 313 * NOTES 314 * The list will always be able to store at least as many items as specified 315 * by the min_items parameter. 316 * 317 * SEE ALSO 318 * List, cl_list_construct, cl_list_destroy, cl_list_insert_head, 319 * cl_list_insert_tail, cl_list_remove_head, cl_list_remove_tail 320 *********/ 321 322 /****f* Component Library: List/cl_list_destroy 323 * NAME 324 * cl_list_destroy 325 * 326 * DESCRIPTION 327 * The cl_list_destroy function destroys a list. 328 * 329 * SYNOPSIS 330 */ 331 void cl_list_destroy(IN cl_list_t * const p_list); 332 /* 333 * PARAMETERS 334 * p_list 335 * [in] Pointer to cl_list_t structure to destroy. 336 * 337 * RETURN VALUE 338 * This function does not return a value. 339 * 340 * NOTES 341 * cl_list_destroy does not affect any of the objects stored in the list, 342 * but does release all memory allocated internally. Further operations 343 * should not be attempted on the list after cl_list_destroy is invoked. 344 * 345 * This function should only be called after a call to cl_list_construct 346 * or cl_list_init. 347 * 348 * In debug builds, cl_list_destroy asserts if the list is not empty. 349 * 350 * SEE ALSO 351 * List, cl_list_construct, cl_list_init 352 *********/ 353 354 /****f* Component Library: List/cl_is_list_empty 355 * NAME 356 * cl_is_list_empty 357 * 358 * DESCRIPTION 359 * The cl_is_list_empty function returns whether a list is empty. 360 * 361 * SYNOPSIS 362 */ 363 static inline boolean_t cl_is_list_empty(IN const cl_list_t * const p_list) 364 { 365 CL_ASSERT(p_list); 366 CL_ASSERT(cl_is_qpool_inited(&p_list->list_item_pool)); 367 return (cl_is_qlist_empty(&p_list->list)); 368 } 369 370 /* 371 * PARAMETERS 372 * p_list 373 * [in] Pointer to a cl_list_t structure. 374 * 375 * RETURN VALUES 376 * TRUE if the specified list is empty. 377 * 378 * FALSE otherwise. 379 * 380 * SEE ALSO 381 * List, cl_list_count, cl_list_remove_all 382 *********/ 383 384 /****f* Component Library: List/cl_list_insert_head 385 * NAME 386 * cl_list_insert_head 387 * 388 * DESCRIPTION 389 * The cl_list_insert_head function inserts an object at the head of a list. 390 * 391 * SYNOPSIS 392 */ 393 static inline cl_status_t 394 cl_list_insert_head(IN cl_list_t * const p_list, IN const void *const p_object) 395 { 396 cl_pool_obj_t *p_pool_obj; 397 398 CL_ASSERT(p_list); 399 CL_ASSERT(cl_is_qpool_inited(&p_list->list_item_pool)); 400 401 /* Get a list item to add to the list. */ 402 p_pool_obj = (cl_pool_obj_t *) cl_qpool_get(&p_list->list_item_pool); 403 if (!p_pool_obj) 404 return (CL_INSUFFICIENT_MEMORY); 405 406 p_pool_obj->p_object = p_object; 407 cl_qlist_insert_head(&p_list->list, &p_pool_obj->pool_item.list_item); 408 return (CL_SUCCESS); 409 } 410 411 /* 412 * PARAMETERS 413 * p_list 414 * [in] Pointer to a cl_list_t structure into which to insert the object. 415 * 416 * p_object 417 * [in] Pointer to an object to insert into the list. 418 * 419 * RETURN VALUES 420 * CL_SUCCESS if the insertion was successful. 421 * 422 * CL_INSUFFICIENT_MEMORY if there was not enough memory for the insertion. 423 * 424 * NOTES 425 * Inserts the specified object at the head of the list. List insertion 426 * operations are guaranteed to work for the minimum number of items as 427 * specified in cl_list_init by the min_items parameter. 428 * 429 * SEE ALSO 430 * List, cl_list_insert_tail, cl_list_insert_array_head, 431 * cl_list_insert_array_tail, cl_list_insert_prev, cl_list_insert_next, 432 * cl_list_remove_head 433 *********/ 434 435 /****f* Component Library: List/cl_list_insert_tail 436 * NAME 437 * cl_list_insert_tail 438 * 439 * DESCRIPTION 440 * The cl_list_insert_tail function inserts an object at the tail of a list. 441 * 442 * SYNOPSIS 443 */ 444 static inline cl_status_t 445 cl_list_insert_tail(IN cl_list_t * const p_list, IN const void *const p_object) 446 { 447 cl_pool_obj_t *p_pool_obj; 448 449 CL_ASSERT(p_list); 450 CL_ASSERT(cl_is_qpool_inited(&p_list->list_item_pool)); 451 452 /* Get a list item to add to the list. */ 453 p_pool_obj = (cl_pool_obj_t *) cl_qpool_get(&p_list->list_item_pool); 454 if (!p_pool_obj) 455 return (CL_INSUFFICIENT_MEMORY); 456 457 p_pool_obj->p_object = p_object; 458 cl_qlist_insert_tail(&p_list->list, &p_pool_obj->pool_item.list_item); 459 return (CL_SUCCESS); 460 } 461 462 /* 463 * PARAMETERS 464 * p_list 465 * [in] Pointer to a cl_list_t structure into which to insert the object. 466 * 467 * p_object 468 * [in] Pointer to an object to insert into the list. 469 * 470 * RETURN VALUES 471 * CL_SUCCESS if the insertion was successful. 472 * 473 * CL_INSUFFICIENT_MEMORY if there was not enough memory for the insertion. 474 * 475 * NOTES 476 * Inserts the specified object at the tail of the list. List insertion 477 * operations are guaranteed to work for the minimum number of items as 478 * specified in cl_list_init by the min_items parameter. 479 * 480 * SEE ALSO 481 * List, cl_list_insert_head, cl_list_insert_array_head, 482 * cl_list_insert_array_tail, cl_list_insert_prev, cl_list_insert_next, 483 * cl_list_remove_tail 484 *********/ 485 486 /****f* Component Library: List/cl_list_insert_array_head 487 * NAME 488 * cl_list_insert_array_head 489 * 490 * DESCRIPTION: 491 * The cl_list_insert_array_head function inserts an array of objects 492 * at the head of a list. 493 * 494 * SYNOPSIS 495 */ 496 cl_status_t 497 cl_list_insert_array_head(IN cl_list_t * const p_list, 498 IN const void *const p_array, 499 IN uint32_t item_count, IN const uint32_t item_size); 500 /* 501 * PARAMETERS 502 * p_list 503 * [in] Pointer to a cl_list_t structure into which to insert the objects. 504 * 505 * p_array 506 * [in] Pointer to the first object in an array. 507 * 508 * item_count 509 * [in] Number of objects in the array. 510 * 511 * item_size 512 * [in] Size of the objects added to the list. This is the stride in the 513 * array from one object to the next. 514 * 515 * RETURN VALUES 516 * CL_SUCCESS if the insertion was successful. 517 * 518 * CL_INSUFFICIENT_MEMORY if there was not enough memory for the insertion. 519 * 520 * NOTES 521 * Inserts all objects in the array to the head of the list, preserving the 522 * ordering of the objects. If not successful, no items are added. 523 * List insertion operations are guaranteed to work for the minimum number 524 * of items as specified in cl_list_init by the min_items parameter. 525 * 526 * SEE ALSO 527 * List, cl_list_insert_array_tail, cl_list_insert_head, cl_list_insert_tail, 528 * cl_list_insert_prev, cl_list_insert_next 529 *********/ 530 531 /****f* Component Library: List/cl_list_insert_array_tail 532 * NAME 533 * cl_list_insert_array_tail 534 * 535 * DESCRIPTION 536 * The cl_list_insert_array_tail function inserts an array of objects 537 * at the tail of a list. 538 * 539 * SYNOPSIS 540 */ 541 cl_status_t 542 cl_list_insert_array_tail(IN cl_list_t * const p_list, 543 IN const void *const p_array, 544 IN uint32_t item_count, IN const uint32_t item_size); 545 /* 546 * PARAMETERS 547 * p_list 548 * [in] Pointer to a cl_list_t structure into which to insert the objects. 549 * 550 * p_array 551 * [in] Pointer to the first object in an array. 552 * 553 * item_count 554 * [in] Number of objects in the array. 555 * 556 * item_size 557 * [in] Size of the objects added to the list. This is the stride in the 558 * array from one object to the next. 559 * 560 * RETURN VALUES 561 * CL_SUCCESS if the insertion was successful. 562 * 563 * CL_INSUFFICIENT_MEMORY if there was not enough memory for the insertion. 564 * 565 * NOTES 566 * Inserts all objects in the array to the tail of the list, preserving the 567 * ordering of the objects. If not successful, no items are added. 568 * List insertion operations are guaranteed to work for the minimum number 569 * of items as specified in cl_list_init by the min_items parameter. 570 * 571 * SEE ALSO 572 * List, cl_list_insert_array_head, cl_list_insert_head, cl_list_insert_tail, 573 * cl_list_insert_prev, cl_list_insert_next 574 *********/ 575 576 /****f* Component Library: List/cl_list_insert_next 577 * NAME 578 * cl_list_insert_next 579 * 580 * DESCRIPTION 581 * The cl_list_insert_next function inserts an object in a list after 582 * the object associated with a given iterator. 583 * 584 * SYNOPSIS 585 */ 586 static inline cl_status_t 587 cl_list_insert_next(IN cl_list_t * const p_list, 588 IN cl_list_iterator_t iterator, 589 IN const void *const p_object) 590 { 591 cl_pool_obj_t *p_pool_obj; 592 593 CL_ASSERT(p_list); 594 CL_ASSERT(cl_is_qpool_inited(&p_list->list_item_pool)); 595 596 /* Get a list item to add to the list. */ 597 p_pool_obj = (cl_pool_obj_t *) cl_qpool_get(&p_list->list_item_pool); 598 if (!p_pool_obj) 599 return (CL_INSUFFICIENT_MEMORY); 600 601 p_pool_obj->p_object = p_object; 602 cl_qlist_insert_next(&p_list->list, (cl_list_item_t *) iterator, 603 &p_pool_obj->pool_item.list_item); 604 return (CL_SUCCESS); 605 } 606 607 /* 608 * PARAMETERS 609 * p_list 610 * [in] Pointer to a cl_list_t structure into which to insert the object. 611 * 612 * iterator 613 * [in] cl_list_iterator_t returned by a previous call to cl_list_head, 614 * cl_list_tail, cl_list_next, or cl_list_prev. 615 * 616 * p_object 617 * [in] Pointer to an object to insert into the list. 618 * 619 * RETURN VALUES 620 * CL_SUCCESS if the insertion was successful. 621 * 622 * CL_INSUFFICIENT_MEMORY if there was not enough memory for the insertion. 623 * 624 * SEE ALSO 625 * List, cl_list_insert_prev, cl_list_insert_head, cl_list_insert_tail, 626 * cl_list_insert_array_head, cl_list_insert_array_tail 627 *********/ 628 629 /****f* Component Library: List/cl_list_insert_prev 630 * NAME 631 * cl_list_insert_prev 632 * 633 * DESCRIPTION 634 * The cl_list_insert_prev function inserts an object in a list before 635 * the object associated with a given iterator. 636 * 637 * SYNOPSIS 638 */ 639 static inline cl_status_t 640 cl_list_insert_prev(IN cl_list_t * const p_list, 641 IN cl_list_iterator_t iterator, 642 IN const void *const p_object) 643 { 644 cl_pool_obj_t *p_pool_obj; 645 646 CL_ASSERT(p_list); 647 CL_ASSERT(cl_is_qpool_inited(&p_list->list_item_pool)); 648 649 /* Get a list item to add to the list. */ 650 p_pool_obj = (cl_pool_obj_t *) cl_qpool_get(&p_list->list_item_pool); 651 if (!p_pool_obj) 652 return (CL_INSUFFICIENT_MEMORY); 653 654 p_pool_obj->p_object = p_object; 655 cl_qlist_insert_prev(&p_list->list, (cl_list_item_t *) iterator, 656 &p_pool_obj->pool_item.list_item); 657 return (CL_SUCCESS); 658 } 659 660 /* 661 * PARAMETERS 662 * p_list 663 * [in] Pointer to a cl_list_t structure into which to insert the object. 664 * 665 * iterator 666 * [in] cl_list_iterator_t returned by a previous call to cl_list_head, 667 * cl_list_tail, cl_list_next, or cl_list_prev. 668 * 669 * p_object 670 * [in] Pointer to an object to insert into the list. 671 * 672 * RETURN VALUES 673 * CL_SUCCESS if the insertion was successful. 674 * 675 * CL_INSUFFICIENT_MEMORY if there was not enough memory for the insertion. 676 * 677 * SEE ALSO 678 * List, cl_list_insert_next, cl_list_insert_head, cl_list_insert_tail, 679 * cl_list_insert_array_head, cl_list_insert_array_tail 680 *********/ 681 682 /****f* Component Library: List/cl_list_remove_head 683 * NAME 684 * cl_list_remove_head 685 * 686 * DESCRIPTION 687 * The cl_list_remove_head function removes an object from the head of a list. 688 * 689 * SYNOPSIS 690 */ 691 static inline void *cl_list_remove_head(IN cl_list_t * const p_list) 692 { 693 cl_pool_obj_t *p_pool_obj; 694 void *p_obj; 695 696 CL_ASSERT(p_list); 697 CL_ASSERT(cl_is_qpool_inited(&p_list->list_item_pool)); 698 699 /* See if the list is empty. */ 700 if (cl_is_qlist_empty(&p_list->list)) 701 return (NULL); 702 703 /* Get the item at the head of the list. */ 704 p_pool_obj = (cl_pool_obj_t *) cl_qlist_remove_head(&p_list->list); 705 706 p_obj = (void *)p_pool_obj->p_object; 707 /* Place the pool item back into the pool. */ 708 cl_qpool_put(&p_list->list_item_pool, &p_pool_obj->pool_item); 709 710 return (p_obj); 711 } 712 713 /* 714 * PARAMETERS 715 * p_list 716 * [in] Pointer to a cl_list_t structure from which to remove an object. 717 * 718 * RETURN VALUES 719 * Returns the pointer to the object formerly at the head of the list. 720 * 721 * NULL if the list was empty. 722 * 723 * SEE ALSO 724 * List, cl_list_remove_tail, cl_list_remove_all, cl_list_remove_object, 725 * cl_list_remove_item, cl_list_insert_head 726 *********/ 727 728 /****f* Component Library: List/cl_list_remove_tail 729 * NAME 730 * cl_list_remove_tail 731 * 732 * DESCRIPTION 733 * The cl_list_remove_tail function removes an object from the tail of a list. 734 * 735 * SYNOPSIS 736 */ 737 static inline void *cl_list_remove_tail(IN cl_list_t * const p_list) 738 { 739 cl_pool_obj_t *p_pool_obj; 740 741 CL_ASSERT(p_list); 742 CL_ASSERT(cl_is_qpool_inited(&p_list->list_item_pool)); 743 744 /* See if the list is empty. */ 745 if (cl_is_qlist_empty(&p_list->list)) 746 return (NULL); 747 748 /* Get the item at the head of the list. */ 749 p_pool_obj = (cl_pool_obj_t *) cl_qlist_remove_tail(&p_list->list); 750 751 /* Place the list item back into the pool. */ 752 cl_qpool_put(&p_list->list_item_pool, &p_pool_obj->pool_item); 753 754 return ((void *)p_pool_obj->p_object); 755 } 756 757 /* 758 * PARAMETERS 759 * p_list 760 * [in] Pointer to a cl_list_t structure from which to remove an object. 761 * 762 * RETURN VALUES 763 * Returns the pointer to the object formerly at the tail of the list. 764 * 765 * NULL if the list was empty. 766 * 767 * SEE ALSO 768 * List, cl_list_remove_head, cl_list_remove_all, cl_list_remove_object, 769 * cl_list_remove_item, cl_list_insert_head 770 *********/ 771 772 /****f* Component Library: List/cl_list_remove_all 773 * NAME 774 * cl_list_remove_all 775 * 776 * DESCRIPTION 777 * The cl_list_remove_all function removes all objects from a list, 778 * leaving it empty. 779 * 780 * SYNOPSIS 781 */ 782 static inline void cl_list_remove_all(IN cl_list_t * const p_list) 783 { 784 CL_ASSERT(p_list); 785 CL_ASSERT(cl_is_qpool_inited(&p_list->list_item_pool)); 786 787 /* Return all the list items to the pool. */ 788 cl_qpool_put_list(&p_list->list_item_pool, &p_list->list); 789 } 790 791 /* 792 * PARAMETERS 793 * p_list 794 * [in] Pointer to a cl_list_t structure from which to remove all objects. 795 * 796 * RETURN VALUE 797 * This function does not return a value. 798 * 799 * SEE ALSO 800 * List, cl_list_remove_head, cl_list_remove_tail, cl_list_remove_object, 801 * cl_list_remove_item 802 *********/ 803 804 /****f* Component Library: List/cl_list_remove_object 805 * NAME 806 * cl_list_remove_object 807 * 808 * DESCRIPTION 809 * The cl_list_remove_object function removes a specific object from a list. 810 * 811 * SYNOPSIS 812 */ 813 cl_status_t 814 cl_list_remove_object(IN cl_list_t * const p_list, 815 IN const void *const p_object); 816 /* 817 * PARAMETERS 818 * p_list 819 * [in] Pointer to a cl_list_t structure from which to remove the object. 820 * 821 * p_object 822 * [in] Pointer to an object to remove from the list. 823 * 824 * RETURN VALUES 825 * CL_SUCCESS if the object was removed. 826 * 827 * CL_NOT_FOUND if the object was not found in the list. 828 * 829 * NOTES 830 * Removes the first occurrence of an object from a list. 831 * 832 * SEE ALSO 833 * List, cl_list_remove_item, cl_list_remove_head, cl_list_remove_tail, 834 * cl_list_remove_all 835 *********/ 836 837 /****f* Component Library: List/cl_list_remove_item 838 * NAME 839 * cl_list_remove_item 840 * 841 * DESCRIPTION 842 * The cl_list_remove_item function removes an object from the head of a list. 843 * 844 * SYNOPSIS 845 */ 846 static inline void 847 cl_list_remove_item(IN cl_list_t * const p_list, IN cl_list_iterator_t iterator) 848 { 849 CL_ASSERT(p_list); 850 CL_ASSERT(cl_is_qpool_inited(&p_list->list_item_pool)); 851 852 cl_qlist_remove_item(&p_list->list, (cl_list_item_t *) iterator); 853 854 /* Place the list item back into the pool. */ 855 cl_qpool_put(&p_list->list_item_pool, (cl_pool_item_t *) iterator); 856 } 857 858 /* 859 * PARAMETERS 860 * p_list 861 * [in] Pointer to a cl_list_t structure from which to remove the item. 862 * 863 * iterator 864 * [in] cl_list_iterator_t returned by a previous call to cl_list_head, 865 * cl_list_tail, cl_list_next, or cl_list_prev. 866 * 867 * RETURN VALUE 868 * This function does not return a value. 869 * 870 * SEE ALSO 871 * List, cl_list_remove_object, cl_list_remove_head, cl_list_remove_tail, 872 * cl_list_remove_all 873 *********/ 874 875 /****f* Component Library: List/cl_is_object_in_list 876 * NAME 877 * cl_is_object_in_list 878 * 879 * DESCRIPTION 880 * The cl_is_object_in_list function returns whether an object 881 * is stored in a list. 882 * 883 * SYNOPSIS 884 */ 885 boolean_t 886 cl_is_object_in_list(IN const cl_list_t * const p_list, 887 IN const void *const p_object); 888 /* 889 * PARAMETERS 890 * p_list 891 * [in] Pointer to a cl_list_t structure in which to look for the object. 892 * 893 * p_object 894 * [in] Pointer to an object stored in a list. 895 * 896 * RETURN VALUES 897 * TRUE if p_object was found in the list. 898 * 899 * FALSE otherwise. 900 * 901 * SEE ALSO 902 * List 903 *********/ 904 905 /****f* Component Library: List/cl_list_end 906 * NAME 907 * cl_list_end 908 * 909 * DESCRIPTION 910 * The cl_list_end function returns returns the list iterator for 911 * the end of a list. 912 * 913 * SYNOPSIS 914 */ 915 static inline cl_list_iterator_t cl_list_end(IN const cl_list_t * const p_list) 916 { 917 CL_ASSERT(p_list); 918 CL_ASSERT(cl_is_qpool_inited(&p_list->list_item_pool)); 919 920 return (cl_qlist_end(&p_list->list)); 921 } 922 923 /* 924 * PARAMETERS 925 * p_list 926 * [in] Pointer to a cl_list_t structure for which the iterator for the 927 * object at the head is to be returned. 928 * 929 * RETURN VALUE 930 * cl_list_iterator_t for the end of the list. 931 * 932 * NOTES 933 * Use cl_list_obj to retrieve the object associated with the 934 * returned cl_list_iterator_t. 935 * 936 * SEE ALSO 937 * List, cl_list_head, cl_list_tail, cl_list_next, cl_list_prev, 938 * cl_list_obj 939 *********/ 940 941 /****f* Component Library: List/cl_list_head 942 * NAME 943 * cl_list_head 944 * 945 * DESCRIPTION 946 * The cl_list_head function returns returns a list iterator for 947 * the head of a list. 948 * 949 * SYNOPSIS 950 */ 951 static inline cl_list_iterator_t cl_list_head(IN const cl_list_t * const p_list) 952 { 953 CL_ASSERT(p_list); 954 CL_ASSERT(cl_is_qpool_inited(&p_list->list_item_pool)); 955 956 return (cl_qlist_head(&p_list->list)); 957 } 958 959 /* 960 * PARAMETERS 961 * p_list 962 * [in] Pointer to a cl_list_t structure for which the iterator for the 963 * object at the head is to be returned. 964 * 965 * RETURN VALUES 966 * cl_list_iterator_t for the head of the list. 967 * 968 * cl_list_iterator_t for the end of the list if the list is empty. 969 * 970 * NOTES 971 * Use cl_list_obj to retrieve the object associated with the 972 * returned cl_list_iterator_t. 973 * 974 * SEE ALSO 975 * List, cl_list_tail, cl_list_next, cl_list_prev, cl_list_end, 976 * cl_list_obj 977 *********/ 978 979 /****f* Component Library: List/cl_list_tail 980 * NAME 981 * cl_list_tail 982 * 983 * DESCRIPTION 984 * The cl_list_tail function returns returns a list iterator for 985 * the tail of a list. 986 * 987 * SYNOPSIS 988 */ 989 static inline cl_list_iterator_t cl_list_tail(IN const cl_list_t * const p_list) 990 { 991 CL_ASSERT(p_list); 992 CL_ASSERT(cl_is_qpool_inited(&p_list->list_item_pool)); 993 994 return (cl_qlist_tail(&p_list->list)); 995 } 996 997 /* 998 * PARAMETERS 999 * p_list 1000 * [in] Pointer to a cl_list_t structure for which the iterator for the 1001 * object at the tail is to be returned. 1002 * 1003 * RETURN VALUES 1004 * cl_list_iterator_t for the tail of the list. 1005 * 1006 * cl_list_iterator_t for the end of the list if the list is empty. 1007 * 1008 * NOTES 1009 * Use cl_list_obj to retrieve the object associated with the 1010 * 1011 * returned cl_list_iterator_t. 1012 * 1013 * SEE ALSO 1014 * List, cl_list_head, cl_list_next, cl_list_prev, cl_list_end, 1015 * cl_list_obj 1016 *********/ 1017 1018 /****f* Component Library: List/cl_list_next 1019 * NAME 1020 * cl_list_next 1021 * 1022 * DESCRIPTION 1023 * The cl_list_next function returns a list iterator for the object stored 1024 * in a list after the object associated with a given list iterator. 1025 * 1026 * SYNOPSIS 1027 */ 1028 static inline cl_list_iterator_t cl_list_next(IN cl_list_iterator_t iterator) 1029 { 1030 CL_ASSERT(iterator); 1031 1032 return (cl_qlist_next(iterator)); 1033 } 1034 1035 /* 1036 * PARAMETERS 1037 * p_list 1038 * [in] Pointer to a cl_list_t structure for which the iterator for the 1039 * next object is to be returned. 1040 * 1041 * iterator 1042 * [in] cl_list_iterator_t returned by a previous call to cl_list_head, 1043 * cl_list_tail, cl_list_next, or cl_list_prev. 1044 * 1045 * RETURN VALUES 1046 * cl_list_iterator_t for the object following the object associated with 1047 * the list iterator specified by the iterator parameter. 1048 * 1049 * cl_list_iterator_t for the end of the list if the list is empty. 1050 * 1051 * NOTES 1052 * Use cl_list_obj to retrieve the object associated with the 1053 * returned cl_list_iterator_t. 1054 * 1055 * SEE ALSO 1056 * List, cl_list_prev, cl_list_head, cl_list_tail, cl_list_end, 1057 * cl_list_obj 1058 *********/ 1059 1060 /****f* Component Library: List/cl_list_prev 1061 * NAME 1062 * cl_list_prev 1063 * 1064 * DESCRIPTION 1065 * The cl_list_prev function returns a list iterator for the object stored 1066 * in a list before the object associated with a given list iterator. 1067 * 1068 * SYNOPSIS 1069 */ 1070 static inline cl_list_iterator_t cl_list_prev(IN cl_list_iterator_t iterator) 1071 { 1072 CL_ASSERT(iterator); 1073 1074 return (cl_qlist_prev(iterator)); 1075 } 1076 1077 /* 1078 * PARAMETERS 1079 * p_list 1080 * [in] Pointer to a cl_list_t structure for which the iterator for the 1081 * next object is to be returned. 1082 * 1083 * iterator 1084 * [in] cl_list_iterator_t returned by a previous call to cl_list_head, 1085 * cl_list_tail, cl_list_next, or cl_list_prev. 1086 * 1087 * RETURN VALUES 1088 * cl_list_iterator_t for the object preceding the object associated with 1089 * the list iterator specified by the iterator parameter. 1090 * 1091 * cl_list_iterator_t for the end of the list if the list is empty. 1092 * 1093 * NOTES 1094 * Use cl_list_obj to retrieve the object associated with the 1095 * returned cl_list_iterator_t. 1096 * 1097 * SEE ALSO 1098 * List, cl_list_next, cl_list_head, cl_list_tail, cl_list_end, 1099 * cl_list_obj 1100 *********/ 1101 1102 /****f* Component Library: List/cl_list_obj 1103 * NAME 1104 * cl_list_obj 1105 * 1106 * DESCRIPTION 1107 * The cl_list_obj function returns the object associated 1108 * with a list iterator. 1109 * 1110 * SYNOPSIS 1111 */ 1112 static inline void *cl_list_obj(IN cl_list_iterator_t iterator) 1113 { 1114 CL_ASSERT(iterator); 1115 1116 return ((void *)((cl_pool_obj_t *) iterator)->p_object); 1117 } 1118 1119 /* 1120 * PARAMETERS 1121 * iterator 1122 * [in] cl_list_iterator_t returned by a previous call to cl_list_head, 1123 * cl_list_tail, cl_list_next, or cl_list_prev whose object is requested. 1124 * 1125 * RETURN VALUE 1126 * Pointer to the object associated with the list iterator specified 1127 * by the iterator parameter. 1128 * 1129 * SEE ALSO 1130 * List, cl_list_head, cl_list_tail, cl_list_next, cl_list_prev 1131 *********/ 1132 1133 /****f* Component Library: List/cl_list_find_from_head 1134 * NAME 1135 * cl_list_find_from_head 1136 * 1137 * DESCRIPTION 1138 * The cl_list_find_from_head function uses a specified function 1139 * to search for an object starting from the head of a list. 1140 * 1141 * SYNOPSIS 1142 */ 1143 cl_list_iterator_t 1144 cl_list_find_from_head(IN const cl_list_t * const p_list, 1145 IN cl_pfn_list_find_t pfn_func, 1146 IN const void *const context); 1147 /* 1148 * PARAMETERS 1149 * p_list 1150 * [in] Pointer to a cl_list_t structure to search. 1151 * 1152 * pfn_func 1153 * [in] Function invoked to determine if a match was found. 1154 * See the cl_pfn_list_find_t function type declaration for details 1155 * about the callback function. 1156 * 1157 * context 1158 * [in] Value to pass to the callback functions to provide context. 1159 * 1160 * RETURN VALUES 1161 * Returns the iterator for the object if found. 1162 * 1163 * Returns the iterator for the list end otherwise. 1164 * 1165 * NOTES 1166 * cl_list_find_from_head does not remove the found object from 1167 * the list. The iterator for the object is returned when the function 1168 * provided by the pfn_func parameter returns CL_SUCCESS. The function 1169 * specified by the pfn_func parameter must not perform any list 1170 * operations as these would corrupt the list. 1171 * 1172 * SEE ALSO 1173 * List, cl_list_find_from_tail, cl_list_apply_func_t, 1174 * cl_pfn_list_find_t 1175 *********/ 1176 1177 /****f* Component Library: List/cl_list_find_from_tail 1178 * NAME 1179 * cl_list_find_from_tail 1180 * 1181 * DESCRIPTION 1182 * The cl_list_find_from_tail function uses a specified function 1183 * to search for an object starting from the tail of a list. 1184 * 1185 * SYNOPSIS 1186 */ 1187 cl_list_iterator_t 1188 cl_list_find_from_tail(IN const cl_list_t * const p_list, 1189 IN cl_pfn_list_find_t pfn_func, 1190 IN const void *const context); 1191 /* 1192 * PARAMETERS 1193 * p_list 1194 * [in] Pointer to a cl_list_t structure to search. 1195 * 1196 * pfn_func 1197 * [in] Function invoked to determine if a match was found. 1198 * See the cl_pfn_list_find_t function type declaration for details 1199 * about the callback function. 1200 * 1201 * context 1202 * [in] Value to pass to the callback functions to provide context. 1203 * 1204 * RETURN VALUES 1205 * Returns the iterator for the object if found. 1206 * 1207 * Returns the iterator for the list end otherwise. 1208 * 1209 * NOTES 1210 * cl_list_find_from_tail does not remove the found object from 1211 * the list. The iterator for the object is returned when the function 1212 * provided by the pfn_func parameter returns CL_SUCCESS. The function 1213 * specified by the pfn_func parameter must not perform any list 1214 * operations as these would corrupt the list. 1215 * 1216 * SEE ALSO 1217 * List, cl_list_find_from_head, cl_list_apply_func_t, 1218 * cl_pfn_list_find_t 1219 *********/ 1220 1221 /****f* Component Library: List/cl_list_apply_func 1222 * NAME 1223 * cl_list_apply_func 1224 * 1225 * DESCRIPTION 1226 * The cl_list_apply_func function executes a specified function for every 1227 * object stored in a list. 1228 * 1229 * SYNOPSIS 1230 */ 1231 void 1232 cl_list_apply_func(IN const cl_list_t * const p_list, 1233 IN cl_pfn_list_apply_t pfn_func, 1234 IN const void *const context); 1235 /* 1236 * PARAMETERS 1237 * p_list 1238 * [in] Pointer to a cl_list_t structure to iterate. 1239 * 1240 * pfn_func 1241 * [in] Function invoked for every item in a list. 1242 * See the cl_pfn_list_apply_t function type declaration for details 1243 * about the callback function. 1244 * 1245 * context 1246 * [in] Value to pass to the callback functions to provide context. 1247 * 1248 * RETURN VALUE 1249 * This function does not return a value. 1250 * 1251 * NOTES 1252 * cl_list_apply_func invokes the specified callback function for every 1253 * object stored in the list, starting from the head. The function specified 1254 * by the pfn_func parameter must not perform any list operations as these 1255 * would corrupt the list. 1256 * 1257 * SEE ALSO 1258 * List, cl_list_find_from_head, cl_list_find_from_tail, 1259 * cl_pfn_list_apply_t 1260 *********/ 1261 1262 /****f* Component Library: List/cl_list_count 1263 * NAME 1264 * cl_list_count 1265 * 1266 * DESCRIPTION 1267 * The cl_list_count function returns the number of objects stored in a list. 1268 * 1269 * SYNOPSIS 1270 */ 1271 static inline size_t cl_list_count(IN const cl_list_t * const p_list) 1272 { 1273 CL_ASSERT(p_list); 1274 CL_ASSERT(cl_is_qpool_inited(&p_list->list_item_pool)); 1275 1276 return (cl_qlist_count(&p_list->list)); 1277 } 1278 1279 /* 1280 * PARAMETERS 1281 * p_list 1282 * [in] Pointer to a cl_list_t structure whose object to count. 1283 * 1284 * RETURN VALUES 1285 * Number of objects stored in the specified list. 1286 * 1287 * SEE ALSO 1288 * List 1289 *********/ 1290 1291 END_C_DECLS 1292 #endif /* _CL_LIST_H_ */ 1293