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.
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:
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
16 * - Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
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.
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
38 * Declaration of quick list.
41 #ifndef _CL_QUICK_LIST_H_
42 #define _CL_QUICK_LIST_H_
44 #include <complib/cl_types.h>
47 # define BEGIN_C_DECLS extern "C" {
48 # define END_C_DECLS }
49 #else /* !__cplusplus */
50 # define BEGIN_C_DECLS
52 #endif /* __cplusplus */
55 /****h* Component Library/Quick List
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
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.
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
76 * cl_qlist_t, cl_list_item_t, cl_list_obj_t
79 * cl_pfn_qlist_apply_t, cl_pfn_qlist_find_t
82 * cl_qlist_set_obj, cl_qlist_obj
88 * cl_qlist_next, cl_qlist_prev, cl_qlist_head, cl_qlist_tail,
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
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
105 * cl_qlist_count, cl_is_qlist_empty
107 /****s* Component Library: Quick List/cl_list_item_t
112 * The cl_list_item_t structure is used by lists to store objects.
116 typedef struct _cl_list_item {
117 struct _cl_list_item *p_next;
118 struct _cl_list_item *p_prev;
120 struct _cl_qlist *p_list;
126 * Used internally by the list. Users should not use this field.
129 * Used internally by the list. Users should not use this field.
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)
139 /****s* Component Library: Quick List/cl_list_obj_t
144 * The cl_list_obj_t structure is used by lists to store objects.
148 typedef struct _cl_list_obj {
149 cl_list_item_t list_item;
150 const void *p_object; /* User's context */
155 * Used internally by the list. Users should not use this field.
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
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.
167 * Quick List, cl_qlist_set_obj, cl_qlist_obj, cl_list_item_t
170 /****s* Component Library: Quick List/cl_qlist_t
175 * Quick list structure.
177 * The cl_qlist_t structure should be treated as opaque and should be
178 * manipulated only through the provided functions.
182 typedef struct _cl_qlist {
190 * List item used to mark the end of the list.
193 * Number of items in the list.
196 * State of the quick list.
202 /****d* Component Library: Quick List/cl_pfn_qlist_apply_t
204 * cl_pfn_qlist_apply_t
207 * The cl_pfn_qlist_apply_t function type defines the prototype for functions
208 * used to iterate items in a quick list.
213 (*cl_pfn_qlist_apply_t) (IN cl_list_item_t * const p_list_item,
218 * [in] Pointer to a cl_list_item_t structure.
221 * [in] Value passed to the callback function.
224 * This function does not return a value.
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
232 * Quick List, cl_qlist_apply_func
235 /****d* Component Library: Quick List/cl_pfn_qlist_find_t
237 * cl_pfn_qlist_find_t
240 * The cl_pfn_qlist_find_t function type defines the prototype for functions
241 * used to find items in a quick list.
246 (*cl_pfn_qlist_find_t) (IN const cl_list_item_t * const p_list_item,
251 * [in] Pointer to a cl_list_item_t.
254 * [in] Value passed to the callback function.
257 * Return CL_SUCCESS if the desired item was found. This stops list iteration.
259 * Return CL_NOT_FOUND to continue list iteration.
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
268 * Quick List, cl_qlist_find_from_head, cl_qlist_find_from_tail,
269 * cl_qlist_find_next, cl_qlist_find_prev
272 /****i* Component Library: Quick List/__cl_primitive_insert
274 * __cl_primitive_insert
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.
283 __cl_primitive_insert(IN cl_list_item_t * const p_list_item,
284 IN cl_list_item_t * const p_new_item)
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);
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;
300 * [in] Pointer to cl_list_item_t to insert in front of
303 * [in] Pointer to cl_list_item_t to add
306 * This function does not return a value.
309 /****i* Component Library: Quick List/__cl_primitive_remove
311 * __cl_primitive_remove
314 * Remove an item from a list. This is a low level routine
315 * for use internally by the queuing routines.
319 static inline void __cl_primitive_remove(IN cl_list_item_t * const p_list_item)
321 /* CL_ASSERT that a non-null pointer is provided. */
322 CL_ASSERT(p_list_item);
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;
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;
335 #endif /* defined( _DEBUG_ ) */
341 * [in] Pointer to cl_list_item_t to remove
344 * This function does not return a value.
348 * Declaration of quick list functions
351 /****f* Component Library: Quick List/cl_qlist_set_obj
356 * The cl_qlist_set_obj function sets the object stored in a list object.
361 cl_qlist_set_obj(IN cl_list_obj_t * const p_list_obj,
362 IN const void *const p_object)
364 /* CL_ASSERT that a non-null pointer is provided. */
365 CL_ASSERT(p_list_obj);
366 p_list_obj->p_object = p_object;
372 * [in] Pointer to a cl_list_obj_t structure.
375 * [in] User defined context.
378 * This function does not return a value.
381 * Quick List, cl_qlist_obj
384 /****f* Component Library: Quick List/cl_qlist_obj
389 * The cl_qlist_set_obj function returns the object stored in a list object.
393 static inline void *cl_qlist_obj(IN const cl_list_obj_t * const p_list_obj)
395 /* CL_ASSERT that a non-null pointer is provided. */
396 CL_ASSERT(p_list_obj);
398 return ((void *)p_list_obj->p_object);
404 * [in] Pointer to a cl_list_obj_t structure.
407 * Returns the value of the object pointer stored in the list object.
410 * Quick List, cl_qlist_set_obj
413 static inline void __cl_qlist_reset(IN cl_qlist_t * const p_list)
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;
422 /* Clear the count. */
426 /****f* Component Library: Quick List/cl_qlist_init
431 * The cl_qlist_init function initializes a quick list.
435 static inline void cl_qlist_init(IN cl_qlist_t * const p_list)
437 /* CL_ASSERT that a non-null pointer is provided. */
440 p_list->state = CL_INITIALIZED;
442 /* Reset the quick list data structure. */
443 __cl_qlist_reset(p_list);
449 * [in] Pointer to a cl_qlist_t structure to initialize.
452 * This function does not return a value.
455 * Allows calling quick list manipulation functions.
458 * Quick List, cl_qlist_insert_head, cl_qlist_insert_tail,
459 * cl_qlist_remove_head, cl_qlist_remove_tail
462 /****f* Component Library: Quick List/cl_qlist_count
467 * The cl_qlist_count function returns the number of list items stored
472 static inline uint32_t cl_qlist_count(IN const cl_qlist_t * const p_list)
474 /* CL_ASSERT that a non-null pointer is provided. */
476 /* CL_ASSERT that the list was initialized. */
477 CL_ASSERT(p_list->state == CL_INITIALIZED);
478 return ((uint32_t) p_list->count);
485 * [in] Pointer to a cl_qlist_t structure.
488 * Number of items in the list. This function iterates though the quick
489 * list to count the items.
492 * Quick List, cl_is_qlist_empty
495 /****f* Component Library: Quick List/cl_is_qlist_empty
500 * The cl_is_qlist_empty function returns whether a quick list is empty.
504 static inline boolean_t cl_is_qlist_empty(IN const cl_qlist_t * const p_list)
506 /* CL_ASSERT that a non-null pointer is provided. */
508 /* CL_ASSERT that the list was initialized. */
509 CL_ASSERT(p_list->state == CL_INITIALIZED);
511 return (!cl_qlist_count(p_list));
517 * [in] Pointer to a cl_qlist_t structure.
520 * TRUE if the specified quick list is empty.
525 * Quick List, cl_qlist_count, cl_qlist_remove_all
528 /****f* Component Library: Quick List/cl_qlist_next
533 * The cl_qlist_next function returns a pointer to the list item following
534 * a given list item in a quick list.
538 static inline cl_list_item_t *cl_qlist_next(IN const cl_list_item_t *
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);
546 /* Return the next item. */
547 return (p_list_item->p_next);
553 * [in] Pointer to the cl_list_item_t whose successor to return.
556 * Pointer to the list item following the list item specified by
557 * the p_list_item parameter in the quick list.
559 * Pointer to the list end if p_list_item was at the tail of the list.
562 * Quick List, cl_qlist_head, cl_qlist_tail, cl_qlist_prev, cl_qlist_end,
566 /****f* Component Library: Quick List/cl_qlist_prev
571 * The cl_qlist_prev function returns a poirter to the list item preceding
572 * a given list item in a quick list.
576 static inline cl_list_item_t *cl_qlist_prev(IN const cl_list_item_t *
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);
584 /* Return the previous item. */
585 return (p_list_item->p_prev);
591 * [in] Pointer to the cl_list_item_t whose predecessor to return.
594 * Pointer to the list item preceding the list item specified by
595 * the p_list_item parameter in the quick list.
597 * Pointer to the list end if p_list_item was at the tail of the list.
600 * Quick List, cl_qlist_head, cl_qlist_tail, cl_qlist_next, cl_qlist_end,
604 /****f* Component Library: Quick List/cl_qlist_head
609 * The cl_qlist_head function returns the list item at
610 * the head of a quick list.
614 static inline cl_list_item_t *cl_qlist_head(IN const cl_qlist_t * const p_list)
616 /* CL_ASSERT that a non-null pointer is provided. */
618 /* CL_ASSERT that the list was initialized. */
619 CL_ASSERT(p_list->state == CL_INITIALIZED);
621 return (cl_qlist_next(&p_list->end));
627 * [in] Pointer to a cl_qlist_t structure.
630 * Pointer to the list item at the head of the quick list.
632 * Pointer to the list end if the list was empty.
635 * cl_qlist_head does not remove the item from the list.
638 * Quick List, cl_qlist_tail, cl_qlist_next, cl_qlist_prev, cl_qlist_end,
642 /****f* Component Library: Quick List/cl_qlist_tail
647 * The cl_qlist_tail function returns the list item at
648 * the tail of a quick list.
652 static inline cl_list_item_t *cl_qlist_tail(IN const cl_qlist_t * const p_list)
654 /* CL_ASSERT that a non-null pointer is provided. */
656 /* CL_ASSERT that the list was initialized. */
657 CL_ASSERT(p_list->state == CL_INITIALIZED);
659 return (cl_qlist_prev(&p_list->end));
665 * [in] Pointer to a cl_qlist_t structure.
668 * Pointer to the list item at the tail of the quick list.
670 * Pointer to the list end if the list was empty.
673 * cl_qlist_tail does not remove the item from the list.
676 * Quick List, cl_qlist_head, cl_qlist_next, cl_qlist_prev, cl_qlist_end,
680 /****f* Component Library: Quick List/cl_qlist_end
685 * The cl_qlist_end function returns the end of a quick list.
689 static inline const cl_list_item_t *cl_qlist_end(IN const cl_qlist_t *
692 /* CL_ASSERT that a non-null pointer is provided. */
694 /* CL_ASSERT that the list was initialized. */
695 CL_ASSERT(p_list->state == CL_INITIALIZED);
697 return (&p_list->end);
703 * [in] Pointer to a cl_qlist_t structure.
706 * Pointer to the end of the list.
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
717 * Quick List, cl_qlist_head, cl_qlist_tail, cl_qlist_next, cl_qlist_prev,
721 /****f* Component Library: Quick List/cl_qlist_insert_head
723 * cl_qlist_insert_head
726 * The cl_qlist_insert_head function inserts a list item at the
727 * head of a quick list.
732 cl_qlist_insert_head(IN cl_qlist_t * const p_list,
733 IN cl_list_item_t * const p_list_item)
735 /* CL_ASSERT that a non-null pointer is provided. */
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);
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.
748 CL_ASSERT(p_list_item->p_list != p_list);
750 #if defined( _DEBUG_ )
751 p_list_item->p_list = p_list;
754 /* Insert before the head. */
755 __cl_primitive_insert(cl_qlist_head(p_list), p_list_item);
763 * [in] Pointer to a cl_qlist_t structure into which to insert the object.
766 * [in] Pointer to a cl_list_item_t structure to add.
769 * This function does not return a value.
772 * In debug builds, cl_qlist_insert_head asserts that the specified list item
773 * is not already in the list.
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
782 /****f* Component Library: Quick List/cl_qlist_insert_tail
784 * cl_qlist_insert_tail
787 * The cl_qlist_insert_tail function inserts a list item at the tail
793 cl_qlist_insert_tail(IN cl_qlist_t * const p_list,
794 IN cl_list_item_t * const p_list_item)
796 /* CL_ASSERT that a non-null pointer is provided. */
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);
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.
809 CL_ASSERT(p_list_item->p_list != p_list);
811 #if defined( _DEBUG_ )
812 p_list_item->p_list = p_list;
816 * Put the new element in front of the end which is the same
817 * as being at the tail
819 __cl_primitive_insert(&p_list->end, p_list_item);
827 * [in] Pointer to a cl_qlist_t structure into which to insert the object.
830 * [in] Pointer to cl_list_item_t structure to add.
833 * This function does not return a value.
836 * In debug builds, cl_qlist_insert_tail asserts that the specified list item
837 * is not already in the list.
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
846 /****f* Component Library: Quick List/cl_qlist_insert_list_head
848 * cl_qlist_insert_list_head
851 * The cl_qlist_insert_list_head function merges two quick lists by
852 * inserting one at the head of the other.
857 cl_qlist_insert_list_head(IN cl_qlist_t * const p_dest_list,
858 IN cl_qlist_t * const p_src_list);
862 * [in] Pointer to destination quicklist object.
865 * [in] Pointer to quicklist to add.
868 * This function does not return a value.
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.
874 * The list pointed to by the p_src_list parameter is empty when
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,
884 /****f* Component Library: Quick List/cl_qlist_insert_list_tail
886 * cl_qlist_insert_list_tail
889 * The cl_qlist_insert_list_tail function merges two quick lists by
890 * inserting one at the tail of the other.
895 cl_qlist_insert_list_tail(IN cl_qlist_t * const p_dest_list,
896 IN cl_qlist_t * const p_src_list);
900 * [in] Pointer to destination quicklist object
903 * [in] Pointer to quicklist to add
906 * This function does not return a value.
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.
912 * The list pointed to by the p_src_list parameter is empty when
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,
922 /****f* Component Library: Quick List/cl_qlist_insert_array_head
924 * cl_qlist_insert_array_head
927 * The cl_qlist_insert_array_head function inserts an array of list items
928 * at the head of a quick list.
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);
939 * [in] Pointer to a cl_qlist_t structure into which to insert
943 * [in] Pointer to the first list item in an array of cl_list_item_t
947 * [in] Number of cl_list_item_t structures in the array.
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.
954 * This function does not return a value.
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.
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.
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
971 /****f* Component Library: Quick List/cl_qlist_insert_array_tail
973 * cl_qlist_insert_array_tail
976 * The cl_qlist_insert_array_tail function inserts an array of list items
977 * at the tail of a quick list.
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);
988 * [in] Pointer to a cl_qlist_t structure into which to insert
992 * [in] Pointer to the first list item in an array of cl_list_item_t
996 * [in] Number of cl_list_item_t structures in the array.
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.
1003 * This function does not return a value.
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.
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.
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
1020 /****f* Component Library: Quick List/cl_qlist_insert_prev
1022 * cl_qlist_insert_prev
1025 * The cl_qlist_insert_prev function inserts a list item before a
1026 * specified list item in a quick list.
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)
1035 /* CL_ASSERT that a non-null pointer is provided. */
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);
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.
1050 CL_ASSERT(p_new_item->p_list != p_list);
1052 #if defined( _DEBUG_ )
1053 p_new_item->p_list = p_list;
1056 __cl_primitive_insert(p_list_item, p_new_item);
1064 * [in] Pointer to a cl_qlist_t structure into which to add the new item.
1067 * [in] Pointer to a cl_list_item_t structure.
1070 * [in] Pointer to a cl_list_item_t structure to add to the quick list.
1073 * This function does not return a value.
1076 * Inserts the new list item before the list item specified by p_list_item.
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
1084 /****f* Component Library: Quick List/cl_qlist_insert_next
1086 * cl_qlist_insert_next
1089 * The cl_qlist_insert_next function inserts a list item after a specified
1090 * list item in a quick list.
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)
1099 /* CL_ASSERT that a non-null pointer is provided. */
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);
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.
1114 CL_ASSERT(p_new_item->p_list != p_list);
1116 #if defined( _DEBUG_ )
1117 p_new_item->p_list = p_list;
1120 __cl_primitive_insert(cl_qlist_next(p_list_item), p_new_item);
1128 * [in] Pointer to a cl_qlist_t structure into which to add the new item.
1131 * [in] Pointer to a cl_list_item_t structure.
1134 * [in] Pointer to a cl_list_item_t structure to add to the quick list.
1137 * This function does not return a value.
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.
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
1149 /****f* Component Library: Quick List/cl_qlist_remove_head
1151 * cl_qlist_remove_head
1154 * The cl_qlist_remove_head function removes and returns the list item
1155 * at the head of a quick list.
1159 static inline cl_list_item_t *cl_qlist_remove_head(IN cl_qlist_t * const p_list)
1161 cl_list_item_t *p_item;
1163 /* CL_ASSERT that a non-null pointer is provided. */
1165 /* CL_ASSERT that the list was initialized. */
1166 CL_ASSERT(p_list->state == CL_INITIALIZED);
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);
1172 if (p_item == cl_qlist_end(p_list))
1175 #if defined( _DEBUG_ )
1176 /* Clear the item's link to the list. */
1177 p_item->p_list = NULL;
1180 __cl_primitive_remove(p_item);
1190 * [in] Pointer to a cl_qlist_t structure.
1193 * Returns a pointer to the list item formerly at the head of the quick list.
1195 * Pointer to the list end if the list was empty.
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
1202 /****f* Component Library: Quick List/cl_qlist_remove_tail
1204 * cl_qlist_remove_tail
1207 * The cl_qlist_remove_tail function removes and returns the list item
1208 * at the tail of a quick list.
1212 static inline cl_list_item_t *cl_qlist_remove_tail(IN cl_qlist_t * const p_list)
1214 cl_list_item_t *p_item;
1216 /* CL_ASSERT that a non-null pointer is provided. */
1218 /* CL_ASSERT that the list was initialized. */
1219 CL_ASSERT(p_list->state == CL_INITIALIZED);
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);
1225 if (p_item == cl_qlist_end(p_list))
1228 #if defined( _DEBUG_ )
1229 /* Clear the item's link to the list. */
1230 p_item->p_list = NULL;
1233 __cl_primitive_remove(p_item);
1243 * [in] Pointer to a cl_qlist_t structure.
1246 * Returns a pointer to the list item formerly at the tail of the quick list.
1248 * Pointer to the list end if the list was empty.
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
1255 /****f* Component Library: Quick List/cl_qlist_remove_item
1257 * cl_qlist_remove_item
1260 * The cl_qlist_remove_item function removes a specific list item from a quick list.
1265 cl_qlist_remove_item(IN cl_qlist_t * const p_list,
1266 IN cl_list_item_t * const p_list_item)
1268 /* CL_ASSERT that a non-null pointer is provided. */
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);
1277 if (p_list_item == cl_qlist_end(p_list))
1280 #if defined( _DEBUG_ )
1281 /* Clear the item's link to the list. */
1282 p_list_item->p_list = NULL;
1285 __cl_primitive_remove(p_list_item);
1293 * [in] Pointer to a cl_qlist_t structure from which to remove the item.
1296 * [in] Pointer to a cl_list_item_t structure to remove.
1299 * This function does not return a value.
1302 * Removes the list item pointed to by the p_list_item parameter from
1306 * Quick List, cl_qlist_remove_head, cl_qlist_remove_tail, cl_qlist_remove_all,
1310 /****f* Component Library: Quick List/cl_qlist_remove_all
1312 * cl_qlist_remove_all
1315 * The cl_qlist_remove_all function removes all items from a quick list.
1319 static inline void cl_qlist_remove_all(IN cl_qlist_t * const p_list)
1321 #if defined( _DEBUG_ )
1322 cl_list_item_t *p_list_item;
1324 /* CL_ASSERT that a non-null pointer is provided. */
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;
1335 __cl_qlist_reset(p_list);
1341 * [in] Pointer to a cl_qlist_t structure.
1344 * This function does not return a value.
1347 * Quick List, cl_qlist_remove_head, cl_qlist_remove_tail,
1348 * cl_qlist_remove_item, cl_list_item_t
1351 /****f* Component Library: Quick List/cl_is_item_in_qlist
1353 * cl_is_item_in_qlist
1356 * The cl_is_item_in_qlist function checks for the presence of a
1357 * list item in a quick list.
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);
1367 * [in] Pointer to a cl_qlist_t structure.
1370 * [in] Pointer to the cl_list_item_t to find.
1373 * TRUE if the list item was found in the quick list.
1378 * Quick List, cl_qlist_remove_item, cl_list_item_t
1381 /****f* Component Library: Quick List/cl_qlist_find_next
1383 * cl_qlist_find_next
1386 * The cl_qlist_find_next function invokes a specified function to
1387 * search for an item, starting from a given list item.
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);
1398 * [in] Pointer to a cl_qlist_t structure in which to search.
1401 * [in] Pointer to a cl_list_item_t structure from which to start the search.
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.
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
1414 * Pointer to the list item, if found.
1416 * p_list_item if not found.
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.
1424 * The function provided by the pfn_func must not perform any list operations,
1425 * as these would corrupt the list.
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
1433 /****f* Component Library: Quick List/cl_qlist_find_prev
1435 * cl_qlist_find_prev
1438 * The cl_qlist_find_prev function invokes a specified function to
1439 * search backward for an item, starting from a given list item.
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);
1450 * [in] Pointer to a cl_qlist_t structure in which to search.
1453 * [in] Pointer to a cl_list_item_t structure from which to start the search.
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.
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
1466 * Pointer to the list item, if found.
1468 * p_list_item if not found.
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.
1476 * The function provided by the pfn_func must not perform any list operations,
1477 * as these would corrupt the list.
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
1485 /****f* Component Library: Quick List/cl_qlist_find_from_head
1487 * cl_qlist_find_from_head
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.
1495 static inline cl_list_item_t *cl_qlist_find_from_head(IN const cl_qlist_t *
1497 IN cl_pfn_qlist_find_t
1499 IN const void *const
1502 /* CL_ASSERT that a non-null pointer is provided. */
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);
1509 return (cl_qlist_find_next(p_list, cl_qlist_end(p_list), pfn_func,
1516 * [in] Pointer to a cl_qlist_t structure.
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.
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
1529 * Pointer to the list item, if found.
1531 * Pointer to the list end otherwise
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.
1538 * The function provided by the pfn_func parameter must not perform any list
1539 * operations, as these would corrupt the list.
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
1547 /****f* Component Library: Quick List/cl_qlist_find_from_tail
1549 * cl_qlist_find_from_tail
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.
1557 static inline cl_list_item_t *cl_qlist_find_from_tail(IN const cl_qlist_t *
1559 IN cl_pfn_qlist_find_t
1561 IN const void *const
1564 /* CL_ASSERT that a non-null pointer is provided. */
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);
1571 return (cl_qlist_find_prev(p_list, cl_qlist_end(p_list), pfn_func,
1578 * [in] Pointer to a cl_qlist_t structure.
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.
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
1591 * Pointer to the list item, if found.
1593 * Pointer to the list end otherwise
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.
1600 * The function provided by the pfn_func parameter must not perform any list
1601 * operations, as these would corrupt the list.
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
1609 /****f* Component Library: Quick List/cl_qlist_apply_func
1611 * cl_qlist_apply_func
1614 * The cl_qlist_apply_func function executes a specified function
1615 * for every list item stored in a quick list.
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);
1626 * [in] Pointer to a cl_qlist_t structure.
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.
1634 * [in] Value to pass to the callback functions to provide context.
1637 * This function does not return a value.
1640 * The function provided must not perform any list operations, as these
1641 * would corrupt the quick list.
1644 * Quick List, cl_qlist_find_from_head, cl_qlist_find_from_tail,
1645 * cl_qlist_move_items, cl_pfn_qlist_apply_t
1648 /****f* Component Library: Quick List/cl_qlist_move_items
1650 * cl_qlist_move_items
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.
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);
1666 * [in] Pointer to a cl_qlist_t structure from which
1667 * list items are removed.
1670 * [in] Pointer to a cl_qlist_t structure to which the source
1671 * list items are added.
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.
1679 * [in] Value to pass to the callback functions to provide context.
1682 * This function does not return a value.
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.
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.
1693 * The function specified by pfn_func must not perform any list operations,
1694 * as these would corrupt the list.
1697 * Quick List, cl_qlist_find_from_head, cl_qlist_find_from_tail,
1698 * cl_qlist_apply_func, cl_pfn_qlist_find_t
1702 #endif /* _CL_QUICK_LIST_H_ */