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
54BEGIN_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*/
116typedef 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*/
148typedef 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*/
182typedef 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*/
212typedef 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*/
245typedef 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*/
282static inline void
283__cl_primitive_insert(IN cl_list_item_t * const p_list_item,
284		      IN cl_list_item_t * const p_new_item)
285{
286	/* CL_ASSERT that a non-null pointer is provided. */
287	CL_ASSERT(p_list_item);
288	/* CL_ASSERT that a non-null pointer is provided. */
289	CL_ASSERT(p_new_item);
290
291	p_new_item->p_next = p_list_item;
292	p_new_item->p_prev = p_list_item->p_prev;
293	p_list_item->p_prev = p_new_item;
294	p_new_item->p_prev->p_next = p_new_item;
295}
296
297/*
298* PARAMETERS
299*	p_list_item
300*		[in] Pointer to cl_list_item_t to insert in front of
301*
302*	p_new_item
303*		[in] Pointer to cl_list_item_t to add
304*
305* RETURN VALUE
306*	This function does not return a value.
307*********/
308
309/****i* Component Library: Quick List/__cl_primitive_remove
310* NAME
311*	__cl_primitive_remove
312*
313* DESCRIPTION
314*	Remove an item from a list.  This is a low level routine
315*	for use internally by the queuing routines.
316*
317* SYNOPSIS
318*/
319static 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*/
360static inline void
361cl_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*/
393static 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
413static 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*/
435static 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*/
472static 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*/
504static 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*/
538static 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*/
576static 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*/
614static 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*/
652static 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*/
689static 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*/
731static inline void
732cl_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*/
792static inline void
793cl_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*/
856void
857cl_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*/
894void
895cl_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*/
932void
933cl_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*/
981void
982cl_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*/
1030static inline void
1031cl_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*/
1094static inline void
1095cl_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*/
1159static 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*/
1212static 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*/
1264static inline void
1265cl_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*/
1319static 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*/
1361boolean_t
1362cl_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*/
1391cl_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*/
1443cl_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*/
1495static 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*/
1557static 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*/
1619void
1620cl_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*/
1658void
1659cl_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
1701END_C_DECLS
1702#endif				/* _CL_QUICK_LIST_H_ */
1703