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