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
__cl_primitive_insert(IN cl_list_item_t * const p_list_item,IN cl_list_item_t * const p_new_item)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 */
__cl_primitive_remove(IN cl_list_item_t * const p_list_item)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
cl_qlist_set_obj(IN cl_list_obj_t * const p_list_obj,IN const void * const p_object)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 */
cl_qlist_obj(IN const cl_list_obj_t * const p_list_obj)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
__cl_qlist_reset(IN cl_qlist_t * const p_list)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 */
cl_qlist_init(IN cl_qlist_t * const p_list)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 */
cl_qlist_count(IN const cl_qlist_t * const p_list)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 */
cl_is_qlist_empty(IN const cl_qlist_t * const p_list)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 */
cl_qlist_next(IN const cl_list_item_t * const p_list_item)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 */
cl_qlist_prev(IN const cl_list_item_t * const p_list_item)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 */
cl_qlist_head(IN const cl_qlist_t * const p_list)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 */
cl_qlist_tail(IN const cl_qlist_t * const p_list)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 */
cl_qlist_end(IN const cl_qlist_t * const p_list)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
cl_qlist_insert_head(IN cl_qlist_t * const p_list,IN cl_list_item_t * const p_list_item)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
cl_qlist_insert_tail(IN cl_qlist_t * const p_list,IN cl_list_item_t * const p_list_item)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
cl_qlist_insert_prev(IN cl_qlist_t * const p_list,IN cl_list_item_t * const p_list_item,IN cl_list_item_t * const p_new_item)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
cl_qlist_insert_next(IN cl_qlist_t * const p_list,IN cl_list_item_t * const p_list_item,IN cl_list_item_t * const p_new_item)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 */
cl_qlist_remove_head(IN cl_qlist_t * const p_list)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 */
cl_qlist_remove_tail(IN cl_qlist_t * const p_list)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
cl_qlist_remove_item(IN cl_qlist_t * const p_list,IN cl_list_item_t * const p_list_item)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 */
cl_qlist_remove_all(IN cl_qlist_t * const p_list)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 */
cl_qlist_find_from_head(IN const cl_qlist_t * const p_list,IN cl_pfn_qlist_find_t pfn_func,IN const void * const context)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 */
cl_qlist_find_from_tail(IN const cl_qlist_t * const p_list,IN cl_pfn_qlist_find_t pfn_func,IN const void * const context)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