]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/ofed/management/opensm/include/complib/cl_qlist.h
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / ofed / management / opensm / include / complib / cl_qlist.h
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_ */