1 /* 2 * Copyright (c) 2004-2008 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 quick list. 39 */ 40 41 #ifndef _CL_QUICK_LIST_H_ 42 #define _CL_QUICK_LIST_H_ 43 44 #include <complib/cl_types.h> 45 46 #ifdef __cplusplus 47 # define BEGIN_C_DECLS extern "C" { 48 # define END_C_DECLS } 49 #else /* !__cplusplus */ 50 # define BEGIN_C_DECLS 51 # define END_C_DECLS 52 #endif /* __cplusplus */ 53 54 BEGIN_C_DECLS 55 /****h* Component Library/Quick List 56 * NAME 57 * Quick List 58 * 59 * DESCRIPTION 60 * Quick list implements a doubly linked that stores user provided 61 * cl_list_item_t structures. 62 * Quick list does not allocate any memory, and can therefore not fail any 63 * operations. Quick list can therefore be useful in minimizing the error 64 * paths in code. 65 * 66 * Quick list is not thread safe, and users must provide serialization when 67 * adding and removing items from the list. Note that it is possible to 68 * walk a quick list while simultaneously adding to it. 69 * 70 * The Quick List functions operate on a cl_qlist_t structure which should be 71 * treated as opaque and should be manipulated only through the provided 72 * functions. 73 * 74 * SEE ALSO 75 * Structures: 76 * cl_qlist_t, cl_list_item_t, cl_list_obj_t 77 * 78 * Callbacks: 79 * cl_pfn_qlist_apply_t, cl_pfn_qlist_find_t 80 * 81 * Item Manipulation: 82 * cl_qlist_set_obj, cl_qlist_obj 83 * 84 * Initialization: 85 * cl_qlist_init 86 * 87 * Iteration: 88 * cl_qlist_next, cl_qlist_prev, cl_qlist_head, cl_qlist_tail, 89 * cl_qlist_end 90 * 91 * Manipulation: 92 * cl_qlist_insert_head, cl_qlist_insert_tail, 93 * cl_qlist_insert_list_head, cl_qlist_insert_list_tail, 94 * cl_qlist_insert_array_head, cl_qlist_insert_array_tail, 95 * cl_qlist_insert_prev, cl_qlist_insert_next, 96 * cl_qlist_remove_head, cl_qlist_remove_tail, 97 * cl_qlist_remove_item, cl_qlist_remove_all 98 * 99 * Search: 100 * cl_is_item_in_qlist, cl_qlist_find_next, cl_qlist_find_prev, 101 * cl_qlist_find_from_head, cl_qlist_find_from_tail 102 * cl_qlist_apply_func, cl_qlist_move_items 103 * 104 * Attributes: 105 * cl_qlist_count, cl_is_qlist_empty 106 *********/ 107 /****s* Component Library: Quick List/cl_list_item_t 108 * NAME 109 * cl_list_item_t 110 * 111 * DESCRIPTION 112 * The cl_list_item_t structure is used by lists to store objects. 113 * 114 * SYNOPSIS 115 */ 116 typedef struct _cl_list_item { 117 struct _cl_list_item *p_next; 118 struct _cl_list_item *p_prev; 119 #ifdef _DEBUG_ 120 struct _cl_qlist *p_list; 121 #endif 122 } cl_list_item_t; 123 /* 124 * FIELDS 125 * p_next 126 * Used internally by the list. Users should not use this field. 127 * 128 * p_prev 129 * Used internally by the list. Users should not use this field. 130 * 131 * SEE ALSO 132 * Quick List 133 *********/ 134 135 #define cl_item_obj(item_ptr, obj_ptr, item_field) (typeof(obj_ptr)) \ 136 ((void *)item_ptr - (unsigned long)&((typeof(obj_ptr))0)->item_field) 137 138 139 /****s* Component Library: Quick List/cl_list_obj_t 140 * NAME 141 * cl_list_obj_t 142 * 143 * DESCRIPTION 144 * The cl_list_obj_t structure is used by lists to store objects. 145 * 146 * SYNOPSIS 147 */ 148 typedef struct _cl_list_obj { 149 cl_list_item_t list_item; 150 const void *p_object; /* User's context */ 151 } cl_list_obj_t; 152 /* 153 * FIELDS 154 * list_item 155 * Used internally by the list. Users should not use this field. 156 * 157 * p_object 158 * User defined context. Users should not access this field directly. 159 * Use cl_qlist_set_obj and cl_qlist_obj to set and retrieve the value 160 * of this field. 161 * 162 * NOTES 163 * Users can use the cl_qlist_set_obj and cl_qlist_obj functions to store 164 * and retrieve context information in the list item. 165 * 166 * SEE ALSO 167 * Quick List, cl_qlist_set_obj, cl_qlist_obj, cl_list_item_t 168 *********/ 169 170 /****s* Component Library: Quick List/cl_qlist_t 171 * NAME 172 * cl_qlist_t 173 * 174 * DESCRIPTION 175 * Quick list structure. 176 * 177 * The cl_qlist_t structure should be treated as opaque and should be 178 * manipulated only through the provided functions. 179 * 180 * SYNOPSIS 181 */ 182 typedef struct _cl_qlist { 183 cl_list_item_t end; 184 size_t count; 185 cl_state_t state; 186 } cl_qlist_t; 187 /* 188 * FIELDS 189 * end 190 * List item used to mark the end of the list. 191 * 192 * count 193 * Number of items in the list. 194 * 195 * state 196 * State of the quick list. 197 * 198 * SEE ALSO 199 * Quick List 200 *********/ 201 202 /****d* Component Library: Quick List/cl_pfn_qlist_apply_t 203 * NAME 204 * cl_pfn_qlist_apply_t 205 * 206 * DESCRIPTION 207 * The cl_pfn_qlist_apply_t function type defines the prototype for functions 208 * used to iterate items in a quick list. 209 * 210 * SYNOPSIS 211 */ 212 typedef void 213 (*cl_pfn_qlist_apply_t) (IN cl_list_item_t * const p_list_item, 214 IN void *context); 215 /* 216 * PARAMETERS 217 * p_list_item 218 * [in] Pointer to a cl_list_item_t structure. 219 * 220 * context 221 * [in] Value passed to the callback function. 222 * 223 * RETURN VALUE 224 * This function does not return a value. 225 * 226 * NOTES 227 * This function type is provided as function prototype reference for the 228 * function provided by users as a parameter to the cl_qlist_apply_func 229 * function. 230 * 231 * SEE ALSO 232 * Quick List, cl_qlist_apply_func 233 *********/ 234 235 /****d* Component Library: Quick List/cl_pfn_qlist_find_t 236 * NAME 237 * cl_pfn_qlist_find_t 238 * 239 * DESCRIPTION 240 * The cl_pfn_qlist_find_t function type defines the prototype for functions 241 * used to find items in a quick list. 242 * 243 * SYNOPSIS 244 */ 245 typedef cl_status_t 246 (*cl_pfn_qlist_find_t) (IN const cl_list_item_t * const p_list_item, 247 IN void *context); 248 /* 249 * PARAMETERS 250 * p_list_item 251 * [in] Pointer to a cl_list_item_t. 252 * 253 * context 254 * [in] Value passed to the callback function. 255 * 256 * RETURN VALUES 257 * Return CL_SUCCESS if the desired item was found. This stops list iteration. 258 * 259 * Return CL_NOT_FOUND to continue list iteration. 260 * 261 * NOTES 262 * This function type is provided as function prototype reference for the 263 * function provided by users as a parameter to the cl_qlist_find_from_head, 264 * cl_qlist_find_from_tail, cl_qlist_find_next, and cl_qlist_find_prev 265 * functions. 266 * 267 * SEE ALSO 268 * Quick List, cl_qlist_find_from_head, cl_qlist_find_from_tail, 269 * cl_qlist_find_next, cl_qlist_find_prev 270 *********/ 271 272 /****i* Component Library: Quick List/__cl_primitive_insert 273 * NAME 274 * __cl_primitive_insert 275 * 276 * DESCRIPTION 277 * Add a new item in front of the specified item. This is a low level 278 * function for use internally by the queuing routines. 279 * 280 * SYNOPSIS 281 */ 282 static inline void 283 __cl_primitive_insert(IN cl_list_item_t * const p_list_item, 284 IN cl_list_item_t * const p_new_item) 285 { 286 /* CL_ASSERT that a non-null pointer is provided. */ 287 CL_ASSERT(p_list_item); 288 /* CL_ASSERT that a non-null pointer is provided. */ 289 CL_ASSERT(p_new_item); 290 291 p_new_item->p_next = p_list_item; 292 p_new_item->p_prev = p_list_item->p_prev; 293 p_list_item->p_prev = p_new_item; 294 p_new_item->p_prev->p_next = p_new_item; 295 } 296 297 /* 298 * PARAMETERS 299 * p_list_item 300 * [in] Pointer to cl_list_item_t to insert in front of 301 * 302 * p_new_item 303 * [in] Pointer to cl_list_item_t to add 304 * 305 * RETURN VALUE 306 * This function does not return a value. 307 *********/ 308 309 /****i* Component Library: Quick List/__cl_primitive_remove 310 * NAME 311 * __cl_primitive_remove 312 * 313 * DESCRIPTION 314 * Remove an item from a list. This is a low level routine 315 * for use internally by the queuing routines. 316 * 317 * SYNOPSIS 318 */ 319 static inline void __cl_primitive_remove(IN cl_list_item_t * const p_list_item) 320 { 321 /* CL_ASSERT that a non-null pointer is provided. */ 322 CL_ASSERT(p_list_item); 323 324 /* set the back pointer */ 325 p_list_item->p_next->p_prev = p_list_item->p_prev; 326 /* set the next pointer */ 327 p_list_item->p_prev->p_next = p_list_item->p_next; 328 329 /* if we're debugging, spruce up the pointers to help find bugs */ 330 #if defined( _DEBUG_ ) 331 if (p_list_item != p_list_item->p_next) { 332 p_list_item->p_next = NULL; 333 p_list_item->p_prev = NULL; 334 } 335 #endif /* defined( _DEBUG_ ) */ 336 } 337 338 /* 339 * PARAMETERS 340 * p_list_item 341 * [in] Pointer to cl_list_item_t to remove 342 * 343 * RETURN VALUE 344 * This function does not return a value. 345 *********/ 346 347 /* 348 * Declaration of quick list functions 349 */ 350 351 /****f* Component Library: Quick List/cl_qlist_set_obj 352 * NAME 353 * cl_qlist_set_obj 354 * 355 * DESCRIPTION 356 * The cl_qlist_set_obj function sets the object stored in a list object. 357 * 358 * SYNOPSIS 359 */ 360 static inline void 361 cl_qlist_set_obj(IN cl_list_obj_t * const p_list_obj, 362 IN const void *const p_object) 363 { 364 /* CL_ASSERT that a non-null pointer is provided. */ 365 CL_ASSERT(p_list_obj); 366 p_list_obj->p_object = p_object; 367 } 368 369 /* 370 * PARAMETERS 371 * p_list_obj 372 * [in] Pointer to a cl_list_obj_t structure. 373 * 374 * p_object 375 * [in] User defined context. 376 * 377 * RETURN VALUE 378 * This function does not return a value. 379 * 380 * SEE ALSO 381 * Quick List, cl_qlist_obj 382 *********/ 383 384 /****f* Component Library: Quick List/cl_qlist_obj 385 * NAME 386 * cl_qlist_obj 387 * 388 * DESCRIPTION 389 * The cl_qlist_set_obj function returns the object stored in a list object. 390 * 391 * SYNOPSIS 392 */ 393 static inline void *cl_qlist_obj(IN const cl_list_obj_t * const p_list_obj) 394 { 395 /* CL_ASSERT that a non-null pointer is provided. */ 396 CL_ASSERT(p_list_obj); 397 398 return ((void *)p_list_obj->p_object); 399 } 400 401 /* 402 * PARAMETERS 403 * p_list_obj 404 * [in] Pointer to a cl_list_obj_t structure. 405 * 406 * RETURN VALUE 407 * Returns the value of the object pointer stored in the list object. 408 * 409 * SEE ALSO 410 * Quick List, cl_qlist_set_obj 411 *********/ 412 413 static inline void __cl_qlist_reset(IN cl_qlist_t * const p_list) 414 { 415 /* Point the end item to itself. */ 416 p_list->end.p_next = &p_list->end; 417 p_list->end.p_prev = &p_list->end; 418 #if defined( _DEBUG_ ) 419 p_list->end.p_list = p_list; 420 #endif 421 422 /* Clear the count. */ 423 p_list->count = 0; 424 } 425 426 /****f* Component Library: Quick List/cl_qlist_init 427 * NAME 428 * cl_qlist_init 429 * 430 * DESCRIPTION 431 * The cl_qlist_init function initializes a quick list. 432 * 433 * SYNOPSIS 434 */ 435 static inline void cl_qlist_init(IN cl_qlist_t * const p_list) 436 { 437 /* CL_ASSERT that a non-null pointer is provided. */ 438 CL_ASSERT(p_list); 439 440 p_list->state = CL_INITIALIZED; 441 442 /* Reset the quick list data structure. */ 443 __cl_qlist_reset(p_list); 444 } 445 446 /* 447 * PARAMETERS 448 * p_list 449 * [in] Pointer to a cl_qlist_t structure to initialize. 450 * 451 * RETURN VALUES 452 * This function does not return a value. 453 * 454 * NOTES 455 * Allows calling quick list manipulation functions. 456 * 457 * SEE ALSO 458 * Quick List, cl_qlist_insert_head, cl_qlist_insert_tail, 459 * cl_qlist_remove_head, cl_qlist_remove_tail 460 *********/ 461 462 /****f* Component Library: Quick List/cl_qlist_count 463 * NAME 464 * cl_qlist_count 465 * 466 * DESCRIPTION 467 * The cl_qlist_count function returns the number of list items stored 468 * in a quick list. 469 * 470 * SYNOPSIS 471 */ 472 static inline uint32_t cl_qlist_count(IN const cl_qlist_t * const p_list) 473 { 474 /* CL_ASSERT that a non-null pointer is provided. */ 475 CL_ASSERT(p_list); 476 /* CL_ASSERT that the list was initialized. */ 477 CL_ASSERT(p_list->state == CL_INITIALIZED); 478 return ((uint32_t) p_list->count); 479 480 } 481 482 /* 483 * PARAMETERS 484 * p_list 485 * [in] Pointer to a cl_qlist_t structure. 486 * 487 * RETURN VALUE 488 * Number of items in the list. This function iterates though the quick 489 * list to count the items. 490 * 491 * SEE ALSO 492 * Quick List, cl_is_qlist_empty 493 *********/ 494 495 /****f* Component Library: Quick List/cl_is_qlist_empty 496 * NAME 497 * cl_is_qlist_empty 498 * 499 * DESCRIPTION 500 * The cl_is_qlist_empty function returns whether a quick list is empty. 501 * 502 * SYNOPSIS 503 */ 504 static inline boolean_t cl_is_qlist_empty(IN const cl_qlist_t * const p_list) 505 { 506 /* CL_ASSERT that a non-null pointer is provided. */ 507 CL_ASSERT(p_list); 508 /* CL_ASSERT that the list was initialized. */ 509 CL_ASSERT(p_list->state == CL_INITIALIZED); 510 511 return (!cl_qlist_count(p_list)); 512 } 513 514 /* 515 * PARAMETERS 516 * p_list 517 * [in] Pointer to a cl_qlist_t structure. 518 * 519 * RETURN VALUES 520 * TRUE if the specified quick list is empty. 521 * 522 * FALSE otherwise. 523 * 524 * SEE ALSO 525 * Quick List, cl_qlist_count, cl_qlist_remove_all 526 *********/ 527 528 /****f* Component Library: Quick List/cl_qlist_next 529 * NAME 530 * cl_qlist_next 531 * 532 * DESCRIPTION 533 * The cl_qlist_next function returns a pointer to the list item following 534 * a given list item in a quick list. 535 * 536 * SYNOPSIS 537 */ 538 static inline cl_list_item_t *cl_qlist_next(IN const cl_list_item_t * 539 const p_list_item) 540 { 541 /* CL_ASSERT that a non-null pointer is provided. */ 542 CL_ASSERT(p_list_item); 543 /* CL_ASSERT that the list was initialized. */ 544 CL_ASSERT(p_list_item->p_list->state == CL_INITIALIZED); 545 546 /* Return the next item. */ 547 return (p_list_item->p_next); 548 } 549 550 /* 551 * PARAMETERS 552 * p_list_item 553 * [in] Pointer to the cl_list_item_t whose successor to return. 554 * 555 * Returns: 556 * Pointer to the list item following the list item specified by 557 * the p_list_item parameter in the quick list. 558 * 559 * Pointer to the list end if p_list_item was at the tail of the list. 560 * 561 * SEE ALSO 562 * Quick List, cl_qlist_head, cl_qlist_tail, cl_qlist_prev, cl_qlist_end, 563 * cl_list_item_t 564 *********/ 565 566 /****f* Component Library: Quick List/cl_qlist_prev 567 * NAME 568 * cl_qlist_prev 569 * 570 * DESCRIPTION 571 * The cl_qlist_prev function returns a poirter to the list item preceding 572 * a given list item in a quick list. 573 * 574 * SYNOPSIS 575 */ 576 static inline cl_list_item_t *cl_qlist_prev(IN const cl_list_item_t * 577 const p_list_item) 578 { 579 /* CL_ASSERT that a non-null pointer is provided. */ 580 CL_ASSERT(p_list_item); 581 /* CL_ASSERT that the list was initialized. */ 582 CL_ASSERT(p_list_item->p_list->state == CL_INITIALIZED); 583 584 /* Return the previous item. */ 585 return (p_list_item->p_prev); 586 } 587 588 /* 589 * PARAMETERS 590 * p_list_item 591 * [in] Pointer to the cl_list_item_t whose predecessor to return. 592 * 593 * Returns: 594 * Pointer to the list item preceding the list item specified by 595 * the p_list_item parameter in the quick list. 596 * 597 * Pointer to the list end if p_list_item was at the tail of the list. 598 * 599 * SEE ALSO 600 * Quick List, cl_qlist_head, cl_qlist_tail, cl_qlist_next, cl_qlist_end, 601 * cl_list_item_t 602 *********/ 603 604 /****f* Component Library: Quick List/cl_qlist_head 605 * NAME 606 * cl_qlist_head 607 * 608 * DESCRIPTION 609 * The cl_qlist_head function returns the list item at 610 * the head of a quick list. 611 * 612 * SYNOPSIS 613 */ 614 static inline cl_list_item_t *cl_qlist_head(IN const cl_qlist_t * const p_list) 615 { 616 /* CL_ASSERT that a non-null pointer is provided. */ 617 CL_ASSERT(p_list); 618 /* CL_ASSERT that the list was initialized. */ 619 CL_ASSERT(p_list->state == CL_INITIALIZED); 620 621 return (cl_qlist_next(&p_list->end)); 622 } 623 624 /* 625 * PARAMETERS 626 * p_list 627 * [in] Pointer to a cl_qlist_t structure. 628 * 629 * RETURN VALUES 630 * Pointer to the list item at the head of the quick list. 631 * 632 * Pointer to the list end if the list was empty. 633 * 634 * NOTES 635 * cl_qlist_head does not remove the item from the list. 636 * 637 * SEE ALSO 638 * Quick List, cl_qlist_tail, cl_qlist_next, cl_qlist_prev, cl_qlist_end, 639 * cl_list_item_t 640 *********/ 641 642 /****f* Component Library: Quick List/cl_qlist_tail 643 * NAME 644 * cl_qlist_tail 645 * 646 * DESCRIPTION 647 * The cl_qlist_tail function returns the list item at 648 * the tail of a quick list. 649 * 650 * SYNOPSIS 651 */ 652 static inline cl_list_item_t *cl_qlist_tail(IN const cl_qlist_t * const p_list) 653 { 654 /* CL_ASSERT that a non-null pointer is provided. */ 655 CL_ASSERT(p_list); 656 /* CL_ASSERT that the list was initialized. */ 657 CL_ASSERT(p_list->state == CL_INITIALIZED); 658 659 return (cl_qlist_prev(&p_list->end)); 660 } 661 662 /* 663 * PARAMETERS 664 * p_list 665 * [in] Pointer to a cl_qlist_t structure. 666 * 667 * RETURN VALUES 668 * Pointer to the list item at the tail of the quick list. 669 * 670 * Pointer to the list end if the list was empty. 671 * 672 * NOTES 673 * cl_qlist_tail does not remove the item from the list. 674 * 675 * SEE ALSO 676 * Quick List, cl_qlist_head, cl_qlist_next, cl_qlist_prev, cl_qlist_end, 677 * cl_list_item_t 678 *********/ 679 680 /****f* Component Library: Quick List/cl_qlist_end 681 * NAME 682 * cl_qlist_end 683 * 684 * DESCRIPTION 685 * The cl_qlist_end function returns the end of a quick list. 686 * 687 * SYNOPSIS 688 */ 689 static inline const cl_list_item_t *cl_qlist_end(IN const cl_qlist_t * 690 const p_list) 691 { 692 /* CL_ASSERT that a non-null pointer is provided. */ 693 CL_ASSERT(p_list); 694 /* CL_ASSERT that the list was initialized. */ 695 CL_ASSERT(p_list->state == CL_INITIALIZED); 696 697 return (&p_list->end); 698 } 699 700 /* 701 * PARAMETERS 702 * p_list 703 * [in] Pointer to a cl_qlist_t structure. 704 * 705 * RETURN VALUE 706 * Pointer to the end of the list. 707 * 708 * NOTES 709 * cl_qlist_end is useful for determining the validity of list items returned 710 * by cl_qlist_head, cl_qlist_tail, cl_qlist_next, cl_qlist_prev, as well as 711 * the cl_qlist_find functions. If the list item pointer returned by any of 712 * these functions compares to the end, the end of the list was encoutered. 713 * When using cl_qlist_head or cl_qlist_tail, this condition indicates that 714 * the list is empty. 715 * 716 * SEE ALSO 717 * Quick List, cl_qlist_head, cl_qlist_tail, cl_qlist_next, cl_qlist_prev, 718 * cl_list_item_t 719 *********/ 720 721 /****f* Component Library: Quick List/cl_qlist_insert_head 722 * NAME 723 * cl_qlist_insert_head 724 * 725 * DESCRIPTION 726 * The cl_qlist_insert_head function inserts a list item at the 727 * head of a quick list. 728 * 729 * SYNOPSIS 730 */ 731 static inline void 732 cl_qlist_insert_head(IN cl_qlist_t * const p_list, 733 IN cl_list_item_t * const p_list_item) 734 { 735 /* CL_ASSERT that a non-null pointer is provided. */ 736 CL_ASSERT(p_list); 737 /* CL_ASSERT that a non-null pointer is provided. */ 738 CL_ASSERT(p_list_item); 739 /* CL_ASSERT that the list was initialized. */ 740 CL_ASSERT(p_list->state == CL_INITIALIZED); 741 742 /* 743 * The list item must not already be part of the list. Note that this 744 * assertion may fail if an uninitialized list item happens to have its 745 * list pointer equal to the specified list. The chances of this 746 * happening are acceptable in light of the value of this check. 747 */ 748 CL_ASSERT(p_list_item->p_list != p_list); 749 750 #if defined( _DEBUG_ ) 751 p_list_item->p_list = p_list; 752 #endif 753 754 /* Insert before the head. */ 755 __cl_primitive_insert(cl_qlist_head(p_list), p_list_item); 756 757 p_list->count++; 758 } 759 760 /* 761 * PARAMETERS 762 * p_list 763 * [in] Pointer to a cl_qlist_t structure into which to insert the object. 764 * 765 * p_list_item 766 * [in] Pointer to a cl_list_item_t structure to add. 767 * 768 * RETURN VALUE 769 * This function does not return a value. 770 * 771 * NOTES 772 * In debug builds, cl_qlist_insert_head asserts that the specified list item 773 * is not already in the list. 774 * 775 * SEE ALSO 776 * Quick List, cl_qlist_insert_tail, cl_qlist_insert_list_head, 777 * cl_qlist_insert_list_tail, cl_qlist_insert_array_head, 778 * cl_qlist_insert_array_tail, cl_qlist_insert_prev, cl_qlist_insert_next, 779 * cl_qlist_remove_head, cl_list_item_t 780 *********/ 781 782 /****f* Component Library: Quick List/cl_qlist_insert_tail 783 * NAME 784 * cl_qlist_insert_tail 785 * 786 * DESCRIPTION 787 * The cl_qlist_insert_tail function inserts a list item at the tail 788 * of a quick list. 789 * 790 * SYNOPSIS 791 */ 792 static inline void 793 cl_qlist_insert_tail(IN cl_qlist_t * const p_list, 794 IN cl_list_item_t * const p_list_item) 795 { 796 /* CL_ASSERT that a non-null pointer is provided. */ 797 CL_ASSERT(p_list); 798 /* CL_ASSERT that a non-null pointer is provided. */ 799 CL_ASSERT(p_list_item); 800 /* CL_ASSERT that the list was initialized. */ 801 CL_ASSERT(p_list->state == CL_INITIALIZED); 802 803 /* 804 * The list item must not already be part of the list. Note that this 805 * assertion may fail if an uninitialized list item happens to have its 806 * list pointer equal to the specified list. The chances of this 807 * happening are acceptable in light of the value of this check. 808 */ 809 CL_ASSERT(p_list_item->p_list != p_list); 810 811 #if defined( _DEBUG_ ) 812 p_list_item->p_list = p_list; 813 #endif 814 815 /* 816 * Put the new element in front of the end which is the same 817 * as being at the tail 818 */ 819 __cl_primitive_insert(&p_list->end, p_list_item); 820 821 p_list->count++; 822 } 823 824 /* 825 * PARAMETERS 826 * p_list 827 * [in] Pointer to a cl_qlist_t structure into which to insert the object. 828 * 829 * p_list_item 830 * [in] Pointer to cl_list_item_t structure to add. 831 * 832 * RETURN VALUE 833 * This function does not return a value. 834 * 835 * NOTES 836 * In debug builds, cl_qlist_insert_tail asserts that the specified list item 837 * is not already in the list. 838 * 839 * SEE ALSO 840 * Quick List, cl_qlist_insert_head, cl_qlist_insert_list_head, 841 * cl_qlist_insert_list_tail, cl_qlist_insert_array_head, 842 * cl_qlist_insert_array_tail, cl_qlist_insert_prev, cl_qlist_insert_next, 843 * cl_qlist_remove_tail, cl_list_item_t 844 *********/ 845 846 /****f* Component Library: Quick List/cl_qlist_insert_list_head 847 * NAME 848 * cl_qlist_insert_list_head 849 * 850 * DESCRIPTION 851 * The cl_qlist_insert_list_head function merges two quick lists by 852 * inserting one at the head of the other. 853 * 854 * SYNOPSIS 855 */ 856 void 857 cl_qlist_insert_list_head(IN cl_qlist_t * const p_dest_list, 858 IN cl_qlist_t * const p_src_list); 859 /* 860 * PARAMETERS 861 * p_dest_list 862 * [in] Pointer to destination quicklist object. 863 * 864 * p_src_list 865 * [in] Pointer to quicklist to add. 866 * 867 * RETURN VALUE 868 * This function does not return a value. 869 * 870 * NOTES 871 * Inserts all list items in the source list to the head of the 872 * destination list. The ordering of the list items is preserved. 873 * 874 * The list pointed to by the p_src_list parameter is empty when 875 * the call returns. 876 * 877 * SEE ALSO 878 * Quick List, cl_qlist_insert_list_tail, cl_qlist_insert_head, 879 * cl_qlist_insert_tail, cl_qlist_insert_array_head, 880 * cl_qlist_insert_array_tail, cl_qlist_insert_prev, cl_qlist_insert_next, 881 * cl_list_item_t 882 *********/ 883 884 /****f* Component Library: Quick List/cl_qlist_insert_list_tail 885 * NAME 886 * cl_qlist_insert_list_tail 887 * 888 * DESCRIPTION 889 * The cl_qlist_insert_list_tail function merges two quick lists by 890 * inserting one at the tail of the other. 891 * 892 * SYNOPSIS 893 */ 894 void 895 cl_qlist_insert_list_tail(IN cl_qlist_t * const p_dest_list, 896 IN cl_qlist_t * const p_src_list); 897 /* 898 * PARAMETERS 899 * p_dest_list 900 * [in] Pointer to destination quicklist object 901 * 902 * p_src_list 903 * [in] Pointer to quicklist to add 904 * 905 * RETURN VALUE 906 * This function does not return a value. 907 * 908 * NOTES 909 * Inserts all list items in the source list to the tail of the 910 * destination list. The ordering of the list items is preserved. 911 * 912 * The list pointed to by the p_src_list parameter is empty when 913 * the call returns. 914 * 915 * SEE ALSO 916 * Quick List, cl_qlist_insert_list_head, cl_qlist_insert_head, 917 * cl_qlist_insert_tail, cl_qlist_insert_array_head, 918 * cl_qlist_insert_array_tail, cl_qlist_insert_prev, cl_qlist_insert_next, 919 * cl_list_item_t 920 *********/ 921 922 /****f* Component Library: Quick List/cl_qlist_insert_array_head 923 * NAME 924 * cl_qlist_insert_array_head 925 * 926 * DESCRIPTION 927 * The cl_qlist_insert_array_head function inserts an array of list items 928 * at the head of a quick list. 929 * 930 * SYNOPSIS 931 */ 932 void 933 cl_qlist_insert_array_head(IN cl_qlist_t * const p_list, 934 IN cl_list_item_t * const p_array, 935 IN uint32_t item_count, IN const uint32_t item_size); 936 /* 937 * PARAMETERS 938 * p_list 939 * [in] Pointer to a cl_qlist_t structure into which to insert 940 * the objects. 941 * 942 * p_array 943 * [in] Pointer to the first list item in an array of cl_list_item_t 944 * structures. 945 * 946 * item_count 947 * [in] Number of cl_list_item_t structures in the array. 948 * 949 * item_size 950 * [in] Size of the items added to the list. This is the stride in the 951 * array from one cl_list_item_t structure to the next. 952 * 953 * RETURN VALUE 954 * This function does not return a value. 955 * 956 * NOTES 957 * Inserts all the list items in the array specified by the p_array parameter 958 * to the head of the quick list specified by the p_list parameter, 959 * preserving ordering of the list items. 960 * 961 * The array pointer passed into the function points to the cl_list_item_t 962 * in the first element of the caller's element array. There is no 963 * restriction on where the element is stored in the parent structure. 964 * 965 * SEE ALSO 966 * Quick List, cl_qlist_insert_array_tail, cl_qlist_insert_head, 967 * cl_qlist_insert_tail, cl_qlist_insert_list_head, cl_qlist_insert_list_tail, 968 * cl_qlist_insert_prev, cl_qlist_insert_next, cl_list_item_t 969 *********/ 970 971 /****f* Component Library: Quick List/cl_qlist_insert_array_tail 972 * NAME 973 * cl_qlist_insert_array_tail 974 * 975 * DESCRIPTION 976 * The cl_qlist_insert_array_tail function inserts an array of list items 977 * at the tail of a quick list. 978 * 979 * SYNOPSIS 980 */ 981 void 982 cl_qlist_insert_array_tail(IN cl_qlist_t * const p_list, 983 IN cl_list_item_t * const p_array, 984 IN uint32_t item_count, IN const uint32_t item_size); 985 /* 986 * PARAMETERS 987 * p_list 988 * [in] Pointer to a cl_qlist_t structure into which to insert 989 * the objects. 990 * 991 * p_array 992 * [in] Pointer to the first list item in an array of cl_list_item_t 993 * structures. 994 * 995 * item_count 996 * [in] Number of cl_list_item_t structures in the array. 997 * 998 * item_size 999 * [in] Size of the items added to the list. This is the stride in the 1000 * array from one cl_list_item_t structure to the next. 1001 * 1002 * RETURN VALUE 1003 * This function does not return a value. 1004 * 1005 * NOTES 1006 * Inserts all the list items in the array specified by the p_array parameter 1007 * to the tail of the quick list specified by the p_list parameter, 1008 * preserving ordering of the list items. 1009 * 1010 * The array pointer passed into the function points to the cl_list_item_t 1011 * in the first element of the caller's element array. There is no 1012 * restriction on where the element is stored in the parent structure. 1013 * 1014 * SEE ALSO 1015 * Quick List, cl_qlist_insert_array_head, cl_qlist_insert_head, 1016 * cl_qlist_insert_tail, cl_qlist_insert_list_head, cl_qlist_insert_list_tail, 1017 * cl_qlist_insert_prev, cl_qlist_insert_next, cl_list_item_t 1018 *********/ 1019 1020 /****f* Component Library: Quick List/cl_qlist_insert_prev 1021 * NAME 1022 * cl_qlist_insert_prev 1023 * 1024 * DESCRIPTION 1025 * The cl_qlist_insert_prev function inserts a list item before a 1026 * specified list item in a quick list. 1027 * 1028 * SYNOPSIS 1029 */ 1030 static inline void 1031 cl_qlist_insert_prev(IN cl_qlist_t * const p_list, 1032 IN cl_list_item_t * const p_list_item, 1033 IN cl_list_item_t * const p_new_item) 1034 { 1035 /* CL_ASSERT that a non-null pointer is provided. */ 1036 CL_ASSERT(p_list); 1037 /* CL_ASSERT that a non-null pointer is provided. */ 1038 CL_ASSERT(p_list_item); 1039 /* CL_ASSERT that a non-null pointer is provided. */ 1040 CL_ASSERT(p_new_item); 1041 /* CL_ASSERT that the list was initialized. */ 1042 CL_ASSERT(p_list->state == CL_INITIALIZED); 1043 1044 /* 1045 * The list item must not already be part of the list. Note that this 1046 * assertion may fail if an uninitialized list item happens to have its 1047 * list pointer equal to the specified list. The chances of this 1048 * happening are acceptable in light of the value of this check. 1049 */ 1050 CL_ASSERT(p_new_item->p_list != p_list); 1051 1052 #if defined( _DEBUG_ ) 1053 p_new_item->p_list = p_list; 1054 #endif 1055 1056 __cl_primitive_insert(p_list_item, p_new_item); 1057 1058 p_list->count++; 1059 } 1060 1061 /* 1062 * PARAMETERS 1063 * p_list 1064 * [in] Pointer to a cl_qlist_t structure into which to add the new item. 1065 * 1066 * p_list_item 1067 * [in] Pointer to a cl_list_item_t structure. 1068 * 1069 * p_new_item 1070 * [in] Pointer to a cl_list_item_t structure to add to the quick list. 1071 * 1072 * RETURN VALUE 1073 * This function does not return a value. 1074 * 1075 * NOTES 1076 * Inserts the new list item before the list item specified by p_list_item. 1077 * 1078 * SEE ALSO 1079 * Quick List, cl_qlist_insert_next, cl_qlist_insert_head, 1080 * cl_qlist_insert_tail, cl_qlist_insert_list_head, cl_qlist_insert_list_tail, 1081 * cl_qlist_insert_array_head, cl_qlist_insert_array_tail, cl_list_item_t 1082 *********/ 1083 1084 /****f* Component Library: Quick List/cl_qlist_insert_next 1085 * NAME 1086 * cl_qlist_insert_next 1087 * 1088 * DESCRIPTION 1089 * The cl_qlist_insert_next function inserts a list item after a specified 1090 * list item in a quick list. 1091 * 1092 * SYNOPSIS 1093 */ 1094 static inline void 1095 cl_qlist_insert_next(IN cl_qlist_t * const p_list, 1096 IN cl_list_item_t * const p_list_item, 1097 IN cl_list_item_t * const p_new_item) 1098 { 1099 /* CL_ASSERT that a non-null pointer is provided. */ 1100 CL_ASSERT(p_list); 1101 /* CL_ASSERT that a non-null pointer is provided. */ 1102 CL_ASSERT(p_list_item); 1103 /* CL_ASSERT that a non-null pointer is provided. */ 1104 CL_ASSERT(p_new_item); 1105 /* CL_ASSERT that the list was initialized. */ 1106 CL_ASSERT(p_list->state == CL_INITIALIZED); 1107 1108 /* 1109 * The list item must not already be part of the list. Note that this 1110 * assertion may fail if an uninitialized list item happens to have its 1111 * list pointer equal to the specified list. The chances of this 1112 * happening are acceptable in light of the value of this check. 1113 */ 1114 CL_ASSERT(p_new_item->p_list != p_list); 1115 1116 #if defined( _DEBUG_ ) 1117 p_new_item->p_list = p_list; 1118 #endif 1119 1120 __cl_primitive_insert(cl_qlist_next(p_list_item), p_new_item); 1121 1122 p_list->count++; 1123 } 1124 1125 /* 1126 * PARAMETERS 1127 * p_list 1128 * [in] Pointer to a cl_qlist_t structure into which to add the new item. 1129 * 1130 * p_list_item 1131 * [in] Pointer to a cl_list_item_t structure. 1132 * 1133 * p_new_item 1134 * [in] Pointer to a cl_list_item_t structure to add to the quick list. 1135 * 1136 * RETURN VALUE 1137 * This function does not return a value. 1138 * 1139 * NOTES 1140 * Inserts the new list item after the list item specified by p_list_item. 1141 * The list item specified by p_list_item must be in the quick list. 1142 * 1143 * SEE ALSO 1144 * Quick List, cl_qlist_insert_prev, cl_qlist_insert_head, 1145 * cl_qlist_insert_tail, cl_qlist_insert_list_head, cl_qlist_insert_list_tail, 1146 * cl_qlist_insert_array_head, cl_qlist_insert_array_tail, cl_list_item_t 1147 *********/ 1148 1149 /****f* Component Library: Quick List/cl_qlist_remove_head 1150 * NAME 1151 * cl_qlist_remove_head 1152 * 1153 * DESCRIPTION 1154 * The cl_qlist_remove_head function removes and returns the list item 1155 * at the head of a quick list. 1156 * 1157 * SYNOPSIS 1158 */ 1159 static inline cl_list_item_t *cl_qlist_remove_head(IN cl_qlist_t * const p_list) 1160 { 1161 cl_list_item_t *p_item; 1162 1163 /* CL_ASSERT that a non-null pointer is provided. */ 1164 CL_ASSERT(p_list); 1165 /* CL_ASSERT that the list was initialized. */ 1166 CL_ASSERT(p_list->state == CL_INITIALIZED); 1167 1168 p_item = cl_qlist_head(p_list); 1169 /* CL_ASSERT that the list item is part of the list. */ 1170 CL_ASSERT(p_item->p_list == p_list); 1171 1172 if (p_item == cl_qlist_end(p_list)) 1173 return (p_item); 1174 1175 #if defined( _DEBUG_ ) 1176 /* Clear the item's link to the list. */ 1177 p_item->p_list = NULL; 1178 #endif 1179 1180 __cl_primitive_remove(p_item); 1181 1182 p_list->count--; 1183 1184 return (p_item); 1185 } 1186 1187 /* 1188 * PARAMETERS 1189 * p_list 1190 * [in] Pointer to a cl_qlist_t structure. 1191 * 1192 * RETURN VALUES 1193 * Returns a pointer to the list item formerly at the head of the quick list. 1194 * 1195 * Pointer to the list end if the list was empty. 1196 * 1197 * SEE ALSO 1198 * Quick List, cl_qlist_remove_tail, cl_qlist_remove_all, cl_qlist_remove_item, 1199 * cl_qlist_end, cl_qlist_head, cl_list_item_t 1200 *********/ 1201 1202 /****f* Component Library: Quick List/cl_qlist_remove_tail 1203 * NAME 1204 * cl_qlist_remove_tail 1205 * 1206 * DESCRIPTION 1207 * The cl_qlist_remove_tail function removes and returns the list item 1208 * at the tail of a quick list. 1209 * 1210 * SYNOPSIS 1211 */ 1212 static inline cl_list_item_t *cl_qlist_remove_tail(IN cl_qlist_t * const p_list) 1213 { 1214 cl_list_item_t *p_item; 1215 1216 /* CL_ASSERT that a non-null pointer is provided. */ 1217 CL_ASSERT(p_list); 1218 /* CL_ASSERT that the list was initialized. */ 1219 CL_ASSERT(p_list->state == CL_INITIALIZED); 1220 1221 p_item = cl_qlist_tail(p_list); 1222 /* CL_ASSERT that the list item is part of the list. */ 1223 CL_ASSERT(p_item->p_list == p_list); 1224 1225 if (p_item == cl_qlist_end(p_list)) 1226 return (p_item); 1227 1228 #if defined( _DEBUG_ ) 1229 /* Clear the item's link to the list. */ 1230 p_item->p_list = NULL; 1231 #endif 1232 1233 __cl_primitive_remove(p_item); 1234 1235 p_list->count--; 1236 1237 return (p_item); 1238 } 1239 1240 /* 1241 * PARAMETERS 1242 * p_list 1243 * [in] Pointer to a cl_qlist_t structure. 1244 * 1245 * RETURN VALUES 1246 * Returns a pointer to the list item formerly at the tail of the quick list. 1247 * 1248 * Pointer to the list end if the list was empty. 1249 * 1250 * SEE ALSO 1251 * Quick List, cl_qlist_remove_head, cl_qlist_remove_all, cl_qlist_remove_item, 1252 * cl_qlist_end, cl_qlist_tail, cl_list_item_t 1253 *********/ 1254 1255 /****f* Component Library: Quick List/cl_qlist_remove_item 1256 * NAME 1257 * cl_qlist_remove_item 1258 * 1259 * DESCRIPTION 1260 * The cl_qlist_remove_item function removes a specific list item from a quick list. 1261 * 1262 * SYNOPSIS 1263 */ 1264 static inline void 1265 cl_qlist_remove_item(IN cl_qlist_t * const p_list, 1266 IN cl_list_item_t * const p_list_item) 1267 { 1268 /* CL_ASSERT that a non-null pointer is provided. */ 1269 CL_ASSERT(p_list); 1270 /* CL_ASSERT that a non-null pointer is provided. */ 1271 CL_ASSERT(p_list_item); 1272 /* CL_ASSERT that the list was initialized. */ 1273 CL_ASSERT(p_list->state == CL_INITIALIZED); 1274 /* CL_ASSERT that the list item is part of the list. */ 1275 CL_ASSERT(p_list_item->p_list == p_list); 1276 1277 if (p_list_item == cl_qlist_end(p_list)) 1278 return; 1279 1280 #if defined( _DEBUG_ ) 1281 /* Clear the item's link to the list. */ 1282 p_list_item->p_list = NULL; 1283 #endif 1284 1285 __cl_primitive_remove(p_list_item); 1286 1287 p_list->count--; 1288 } 1289 1290 /* 1291 * PARAMETERS 1292 * p_list 1293 * [in] Pointer to a cl_qlist_t structure from which to remove the item. 1294 * 1295 * p_list_item 1296 * [in] Pointer to a cl_list_item_t structure to remove. 1297 * 1298 * RETURN VALUE 1299 * This function does not return a value. 1300 * 1301 * NOTES 1302 * Removes the list item pointed to by the p_list_item parameter from 1303 * its list. 1304 * 1305 * SEE ALSO 1306 * Quick List, cl_qlist_remove_head, cl_qlist_remove_tail, cl_qlist_remove_all, 1307 * cl_list_item_t 1308 *********/ 1309 1310 /****f* Component Library: Quick List/cl_qlist_remove_all 1311 * NAME 1312 * cl_qlist_remove_all 1313 * 1314 * DESCRIPTION 1315 * The cl_qlist_remove_all function removes all items from a quick list. 1316 * 1317 * SYNOPSIS 1318 */ 1319 static inline void cl_qlist_remove_all(IN cl_qlist_t * const p_list) 1320 { 1321 #if defined( _DEBUG_ ) 1322 cl_list_item_t *p_list_item; 1323 1324 /* CL_ASSERT that a non-null pointer is provided. */ 1325 CL_ASSERT(p_list); 1326 /* CL_ASSERT that the list was initialized. */ 1327 CL_ASSERT(p_list->state == CL_INITIALIZED); 1328 p_list_item = cl_qlist_head(p_list); 1329 while (p_list_item != cl_qlist_end(p_list)) { 1330 p_list_item = cl_qlist_next(p_list_item); 1331 cl_qlist_prev(p_list_item)->p_list = NULL; 1332 } 1333 #endif 1334 1335 __cl_qlist_reset(p_list); 1336 } 1337 1338 /* 1339 * PARAMETERS 1340 * p_list 1341 * [in] Pointer to a cl_qlist_t structure. 1342 * 1343 * RETURN VALUE 1344 * This function does not return a value. 1345 * 1346 * SEE ALSO 1347 * Quick List, cl_qlist_remove_head, cl_qlist_remove_tail, 1348 * cl_qlist_remove_item, cl_list_item_t 1349 *********/ 1350 1351 /****f* Component Library: Quick List/cl_is_item_in_qlist 1352 * NAME 1353 * cl_is_item_in_qlist 1354 * 1355 * DESCRIPTION 1356 * The cl_is_item_in_qlist function checks for the presence of a 1357 * list item in a quick list. 1358 * 1359 * SYNOPSIS 1360 */ 1361 boolean_t 1362 cl_is_item_in_qlist(IN const cl_qlist_t * const p_list, 1363 IN const cl_list_item_t * const p_list_item); 1364 /* 1365 * PARAMETERS 1366 * p_list 1367 * [in] Pointer to a cl_qlist_t structure. 1368 * 1369 * p_list_item 1370 * [in] Pointer to the cl_list_item_t to find. 1371 * 1372 * RETURN VALUES 1373 * TRUE if the list item was found in the quick list. 1374 * 1375 * FALSE otherwise. 1376 * 1377 * SEE ALSO 1378 * Quick List, cl_qlist_remove_item, cl_list_item_t 1379 *********/ 1380 1381 /****f* Component Library: Quick List/cl_qlist_find_next 1382 * NAME 1383 * cl_qlist_find_next 1384 * 1385 * DESCRIPTION 1386 * The cl_qlist_find_next function invokes a specified function to 1387 * search for an item, starting from a given list item. 1388 * 1389 * SYNOPSIS 1390 */ 1391 cl_list_item_t *cl_qlist_find_next(IN const cl_qlist_t * const p_list, 1392 IN const cl_list_item_t * const p_list_item, 1393 IN cl_pfn_qlist_find_t pfn_func, 1394 IN const void *const context); 1395 /* 1396 * PARAMETERS 1397 * p_list 1398 * [in] Pointer to a cl_qlist_t structure in which to search. 1399 * 1400 * p_list_item 1401 * [in] Pointer to a cl_list_item_t structure from which to start the search. 1402 * 1403 * pfn_func 1404 * [in] Function invoked to determine if a match was found. 1405 * See the cl_pfn_qlist_find_t function type declaration for details 1406 * about the callback function. 1407 * 1408 * context 1409 * [in] Value to pass to the callback functions to provide context if a 1410 * callback function is provided, or value compared to the quick list's 1411 * list items. 1412 * 1413 * Returns: 1414 * Pointer to the list item, if found. 1415 * 1416 * p_list_item if not found. 1417 * 1418 * NOTES 1419 * cl_qlist_find_next does not remove list items from the list. 1420 * The list item is returned when the function specified by the pfn_func 1421 * parameter returns CL_SUCCESS. The list item from which the search starts is 1422 * excluded from the search. 1423 * 1424 * The function provided by the pfn_func must not perform any list operations, 1425 * as these would corrupt the list. 1426 * 1427 * SEE ALSO 1428 * Quick List, cl_qlist_find_prev, cl_qlist_find_from_head, 1429 * cl_qlist_find_from_tail, cl_qlist_end, cl_qlist_apply_func, 1430 * cl_qlist_move_items, cl_list_item_t, cl_pfn_qlist_find_t 1431 *********/ 1432 1433 /****f* Component Library: Quick List/cl_qlist_find_prev 1434 * NAME 1435 * cl_qlist_find_prev 1436 * 1437 * DESCRIPTION 1438 * The cl_qlist_find_prev function invokes a specified function to 1439 * search backward for an item, starting from a given list item. 1440 * 1441 * SYNOPSIS 1442 */ 1443 cl_list_item_t *cl_qlist_find_prev(IN const cl_qlist_t * const p_list, 1444 IN const cl_list_item_t * const p_list_item, 1445 IN cl_pfn_qlist_find_t pfn_func, 1446 IN const void *const context); 1447 /* 1448 * PARAMETERS 1449 * p_list 1450 * [in] Pointer to a cl_qlist_t structure in which to search. 1451 * 1452 * p_list_item 1453 * [in] Pointer to a cl_list_item_t structure from which to start the search. 1454 * 1455 * pfn_func 1456 * [in] Function invoked to determine if a match was found. 1457 * See the cl_pfn_qlist_find_t function type declaration for details 1458 * about the callback function. 1459 * 1460 * context 1461 * [in] Value to pass to the callback functions to provide context if a 1462 * callback function is provided, or value compared to the quick list's 1463 * list items. 1464 * 1465 * Returns: 1466 * Pointer to the list item, if found. 1467 * 1468 * p_list_item if not found. 1469 * 1470 * NOTES 1471 * cl_qlist_find_prev does not remove list items from the list. 1472 * The list item is returned when the function specified by the pfn_func 1473 * parameter returns CL_SUCCESS. The list item from which the search starts is 1474 * excluded from the search. 1475 * 1476 * The function provided by the pfn_func must not perform any list operations, 1477 * as these would corrupt the list. 1478 * 1479 * SEE ALSO 1480 * Quick List, cl_qlist_find_next, cl_qlist_find_from_head, 1481 * cl_qlist_find_from_tail, cl_qlist_end, cl_qlist_apply_func, 1482 * cl_qlist_move_items, cl_list_item_t, cl_pfn_qlist_find_t 1483 *********/ 1484 1485 /****f* Component Library: Quick List/cl_qlist_find_from_head 1486 * NAME 1487 * cl_qlist_find_from_head 1488 * 1489 * DESCRIPTION 1490 * The cl_qlist_find_from_head function invokes a specified function to 1491 * search for an item, starting at the head of a quick list. 1492 * 1493 * SYNOPSIS 1494 */ 1495 static inline cl_list_item_t *cl_qlist_find_from_head(IN const cl_qlist_t * 1496 const p_list, 1497 IN cl_pfn_qlist_find_t 1498 pfn_func, 1499 IN const void *const 1500 context) 1501 { 1502 /* CL_ASSERT that a non-null pointer is provided. */ 1503 CL_ASSERT(p_list); 1504 /* CL_ASSERT that the list was initialized. */ 1505 CL_ASSERT(p_list->state == CL_INITIALIZED); 1506 /* CL_ASSERT that a find function is provided. */ 1507 CL_ASSERT(pfn_func); 1508 1509 return (cl_qlist_find_next(p_list, cl_qlist_end(p_list), pfn_func, 1510 context)); 1511 } 1512 1513 /* 1514 * PARAMETERS 1515 * p_list 1516 * [in] Pointer to a cl_qlist_t structure. 1517 * 1518 * pfn_func 1519 * [in] Function invoked to determine if a match was found. 1520 * See the cl_pfn_qlist_find_t function type declaration for details 1521 * about the callback function. 1522 * 1523 * context 1524 * [in] Value to pass to the callback functions to provide context if a 1525 * callback function is provided, or value compared to the quick list's 1526 * list items. 1527 * 1528 * Returns: 1529 * Pointer to the list item, if found. 1530 * 1531 * Pointer to the list end otherwise 1532 * 1533 * NOTES 1534 * cl_qlist_find_from_head does not remove list items from the list. 1535 * The list item is returned when the function specified by the pfn_func 1536 * parameter returns CL_SUCCESS. 1537 * 1538 * The function provided by the pfn_func parameter must not perform any list 1539 * operations, as these would corrupt the list. 1540 * 1541 * SEE ALSO 1542 * Quick List, cl_qlist_find_from_tail, cl_qlist_find_next, cl_qlist_find_prev, 1543 * cl_qlist_end, cl_qlist_apply_func, cl_qlist_move_items, cl_list_item_t, 1544 * cl_pfn_qlist_find_t 1545 *********/ 1546 1547 /****f* Component Library: Quick List/cl_qlist_find_from_tail 1548 * NAME 1549 * cl_qlist_find_from_tail 1550 * 1551 * DESCRIPTION 1552 * The cl_qlist_find_from_tail function invokes a specified function to 1553 * search for an item, starting at the tail of a quick list. 1554 * 1555 * SYNOPSIS 1556 */ 1557 static inline cl_list_item_t *cl_qlist_find_from_tail(IN const cl_qlist_t * 1558 const p_list, 1559 IN cl_pfn_qlist_find_t 1560 pfn_func, 1561 IN const void *const 1562 context) 1563 { 1564 /* CL_ASSERT that a non-null pointer is provided. */ 1565 CL_ASSERT(p_list); 1566 /* CL_ASSERT that the list was initialized. */ 1567 CL_ASSERT(p_list->state == CL_INITIALIZED); 1568 /* CL_ASSERT that a find function is provided. */ 1569 CL_ASSERT(pfn_func); 1570 1571 return (cl_qlist_find_prev(p_list, cl_qlist_end(p_list), pfn_func, 1572 context)); 1573 } 1574 1575 /* 1576 * PARAMETERS 1577 * p_list 1578 * [in] Pointer to a cl_qlist_t structure. 1579 * 1580 * pfn_func 1581 * [in] Function invoked to determine if a match was found. 1582 * See the cl_pfn_qlist_find_t function type declaration for details 1583 * about the callback function. 1584 * 1585 * context 1586 * [in] Value to pass to the callback functions to provide context if a 1587 * callback function is provided, or value compared to the quick list's 1588 * list items. 1589 * 1590 * Returns: 1591 * Pointer to the list item, if found. 1592 * 1593 * Pointer to the list end otherwise 1594 * 1595 * NOTES 1596 * cl_qlist_find_from_tail does not remove list items from the list. 1597 * The list item is returned when the function specified by the pfn_func 1598 * parameter returns CL_SUCCESS. 1599 * 1600 * The function provided by the pfn_func parameter must not perform any list 1601 * operations, as these would corrupt the list. 1602 * 1603 * SEE ALSO 1604 * Quick List, cl_qlist_find_from_head, cl_qlist_find_next, cl_qlist_find_prev, 1605 * cl_qlist_apply_func, cl_qlist_end, cl_qlist_move_items, cl_list_item_t, 1606 * cl_pfn_qlist_find_t 1607 *********/ 1608 1609 /****f* Component Library: Quick List/cl_qlist_apply_func 1610 * NAME 1611 * cl_qlist_apply_func 1612 * 1613 * DESCRIPTION 1614 * The cl_qlist_apply_func function executes a specified function 1615 * for every list item stored in a quick list. 1616 * 1617 * SYNOPSIS 1618 */ 1619 void 1620 cl_qlist_apply_func(IN const cl_qlist_t * const p_list, 1621 IN cl_pfn_qlist_apply_t pfn_func, 1622 IN const void *const context); 1623 /* 1624 * PARAMETERS 1625 * p_list 1626 * [in] Pointer to a cl_qlist_t structure. 1627 * 1628 * pfn_func 1629 * [in] Function invoked for every item in the quick list. 1630 * See the cl_pfn_qlist_apply_t function type declaration for details 1631 * about the callback function. 1632 * 1633 * context 1634 * [in] Value to pass to the callback functions to provide context. 1635 * 1636 * RETURN VALUE 1637 * This function does not return a value. 1638 * 1639 * NOTES 1640 * The function provided must not perform any list operations, as these 1641 * would corrupt the quick list. 1642 * 1643 * SEE ALSO 1644 * Quick List, cl_qlist_find_from_head, cl_qlist_find_from_tail, 1645 * cl_qlist_move_items, cl_pfn_qlist_apply_t 1646 *********/ 1647 1648 /****f* Component Library: Quick List/cl_qlist_move_items 1649 * NAME 1650 * cl_qlist_move_items 1651 * 1652 * DESCRIPTION 1653 * The cl_qlist_move_items function moves list items from one list to 1654 * another based on the return value of a user supplied function. 1655 * 1656 * SYNOPSIS 1657 */ 1658 void 1659 cl_qlist_move_items(IN cl_qlist_t * const p_src_list, 1660 IN cl_qlist_t * const p_dest_list, 1661 IN cl_pfn_qlist_find_t pfn_func, 1662 IN const void *const context); 1663 /* 1664 * PARAMETERS 1665 * p_src_list 1666 * [in] Pointer to a cl_qlist_t structure from which 1667 * list items are removed. 1668 * 1669 * p_dest_list 1670 * [in] Pointer to a cl_qlist_t structure to which the source 1671 * list items are added. 1672 * 1673 * pfn_func 1674 * [in] Function invoked to determine if a match was found. 1675 * See the cl_pfn_qlist_find_t function type declaration for details 1676 * about the callback function. 1677 * 1678 * context 1679 * [in] Value to pass to the callback functions to provide context. 1680 * 1681 * RETURN VALUE 1682 * This function does not return a value. 1683 * 1684 * NOTES 1685 * If the function specified by the pfn_func parameter returns CL_SUCCESS, 1686 * the related list item is removed from p_src_list and inserted at the tail 1687 * of the p_dest_list. 1688 * 1689 * The cl_qlist_move_items function continues iterating through p_src_list 1690 * from the last item moved, allowing multiple items to be located and moved 1691 * in a single list iteration. 1692 * 1693 * The function specified by pfn_func must not perform any list operations, 1694 * as these would corrupt the list. 1695 * 1696 * SEE ALSO 1697 * Quick List, cl_qlist_find_from_head, cl_qlist_find_from_tail, 1698 * cl_qlist_apply_func, cl_pfn_qlist_find_t 1699 *********/ 1700 1701 END_C_DECLS 1702 #endif /* _CL_QUICK_LIST_H_ */ 1703