1/*
2 * Copyright (c) 2004, 2005 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 list.
39 */
40
41#ifndef _CL_LIST_H_
42#define _CL_LIST_H_
43
44#include <complib/cl_qlist.h>
45#include <complib/cl_qpool.h>
46
47#ifdef __cplusplus
48#  define BEGIN_C_DECLS extern "C" {
49#  define END_C_DECLS   }
50#else				/* !__cplusplus */
51#  define BEGIN_C_DECLS
52#  define END_C_DECLS
53#endif				/* __cplusplus */
54
55BEGIN_C_DECLS
56/****h* Component Library/List
57* NAME
58*	List
59*
60* DESCRIPTION
61*	List stores objects in a doubly linked list.
62*
63*	Unlike quick list, users pass pointers to the object being stored, rather
64*	than to a cl_list_item_t structure.  Insertion operations on a list can
65*	fail, and callers should trap for such failures.
66*
67*	Use quick list in situations where insertion failures cannot be tolerated.
68*
69*	List is not thread safe, and users must provide serialization.
70*
71*	The list functions operates on a cl_list_t structure which should be
72*	treated as opaque and should be manipulated only through the provided
73*	functions.
74*
75* SEE ALSO
76*	Types:
77*		cl_list_iterator_t
78*
79*	Structures:
80*		cl_list_t
81*
82*	Callbacks:
83*		cl_pfn_list_apply_t, cl_pfn_list_find_t
84*
85*	Initialization/Destruction:
86*		cl_list_construct, cl_list_init, cl_list_destroy
87*
88*	Iteration:
89*		cl_list_next, cl_list_prev, cl_list_head, cl_list_tail,
90*		cl_list_end
91*
92*	Manipulation:
93*		cl_list_insert_head, cl_list_insert_tail,
94*		cl_list_insert_array_head, cl_list_insert_array_tail,
95*		cl_list_insert_prev, cl_list_insert_next,
96*		cl_list_remove_head, cl_list_remove_tail,
97*		cl_list_remove_object, cl_list_remove_item, cl_list_remove_all
98*
99*	Search:
100*		cl_is_object_in_list, cl_list_find_from_head, cl_list_find_from_tail,
101*		cl_list_apply_func
102*
103*	Attributes:
104*		cl_list_count, cl_is_list_empty, cl_is_list_inited
105*********/
106/****s* Component Library: List/cl_list_t
107* NAME
108*	cl_list_t
109*
110* DESCRIPTION
111*	List structure.
112*
113*	The cl_list_t structure should be treated as opaque and should be
114*	manipulated only through the provided functions.
115*
116* SYNOPSIS
117*/
118typedef struct _cl_list {
119	cl_qlist_t list;
120	cl_qpool_t list_item_pool;
121} cl_list_t;
122/*
123* FIELDS
124*	list
125*		Quick list of items stored in the list.
126*
127*	list_item_pool
128*		Quick pool of list objects for storing objects in the quick list.
129*
130* SEE ALSO
131*	List
132*********/
133
134/****d* Component Library: List/cl_list_iterator_t
135* NAME
136*	cl_list_iterator_t
137*
138* DESCRIPTION
139*	Iterator type used to walk a list.
140*
141* SYNOPSIS
142*/
143typedef const cl_list_item_t *cl_list_iterator_t;
144/*
145* NOTES
146*	The iterator should be treated as opaque to prevent corrupting the list.
147*
148* SEE ALSO
149*	List, cl_list_head, cl_list_tail, cl_list_next, cl_list_prev,
150*	cl_list_obj
151*********/
152
153/****d* Component Library: List/cl_pfn_list_apply_t
154* NAME
155*	cl_pfn_list_apply_t
156*
157* DESCRIPTION
158*	The cl_pfn_list_apply_t function type defines the prototype for functions
159*	used to iterate objects in a list.
160*
161* SYNOPSIS
162*/
163typedef void
164 (*cl_pfn_list_apply_t) (IN void *const p_object, IN void *context);
165/*
166* PARAMETERS
167*	p_object
168*		[in] Pointer to an object stored in a list.
169*
170*	context
171*		[in] Context provided in a call to cl_list_apply_func.
172*
173* RETURN VALUE
174*	This function does not return a value.
175*
176* NOTES
177*	This function type is provided as function prototype reference for the
178*	function provided by users as a parameter to the cl_list_apply_func
179*	function.
180*
181* SEE ALSO
182*	List, cl_list_apply_func
183*********/
184
185/****d* Component Library: List/cl_pfn_list_find_t
186* NAME
187*	cl_pfn_list_find_t
188*
189* DESCRIPTION
190*	The cl_pfn_list_find_t function type defines the prototype for functions
191*	used to find objects in a list.
192*
193* SYNOPSIS
194*/
195typedef cl_status_t
196    (*cl_pfn_list_find_t) (IN const void *const p_object, IN void *context);
197/*
198* PARAMETERS
199*	p_object
200*		[in] Pointer to an object stored in a list.
201*
202*	context
203*		[in] Context provided in a call to ListFindFromHead or ListFindFromTail.
204*
205* RETURN VALUES
206*	Return CL_SUCCESS if the desired item was found.  This stops list iteration.
207*
208*	Return CL_NOT_FOUND to continue the list iteration.
209*
210* NOTES
211*	This function type is provided as function prototype reference for the
212*	function provided by users as a parameter to the cl_list_find_from_head
213*	and cl_list_find_from_tail functions.
214*
215* SEE ALSO
216*	List, cl_list_find_from_head, cl_list_find_from_tail
217*********/
218
219/****f* Component Library: List/cl_list_construct
220* NAME
221*	cl_list_construct
222*
223* DESCRIPTION
224*	The cl_list_construct function constructs a list.
225*
226* SYNOPSIS
227*/
228void cl_list_construct(IN cl_list_t * const p_list);
229/*
230* PARAMETERS
231*	p_list
232*		[in] Pointer to cl_list_t object whose state to initialize.
233*
234* RETURN VALUE
235*	This function does not return a value.
236*
237* NOTES
238*	Allows calling cl_list_init, cl_list_destroy and cl_is_list_inited.
239*
240*	Calling cl_list_construct is a prerequisite to calling any other
241*	list function except cl_list_init.
242*
243* SEE ALSO
244*	List, cl_list_init, cl_list_destroy, cl_is_list_inited
245*********/
246
247/****f* Component Library: List/cl_is_list_inited
248* NAME
249*	cl_is_list_inited
250*
251* DESCRIPTION
252*	The cl_is_list_inited function returns whether a list was
253*	initialized successfully.
254*
255* SYNOPSIS
256*/
257static inline boolean_t cl_is_list_inited(IN const cl_list_t * const p_list)
258{
259	/* CL_ASSERT that a non-null pointer is provided. */
260	CL_ASSERT(p_list);
261	/*
262	 * The pool is the last thing initialized.  If it is initialized, the
263	 * list is initialized too.
264	 */
265	return (cl_is_qpool_inited(&p_list->list_item_pool));
266}
267
268/*
269* PARAMETERS
270*	p_list
271*		[in] Pointer to a cl_list_t structure whose initilization state
272*		to check.
273*
274* RETURN VALUES
275*	TRUE if the list was initialized successfully.
276*
277*	FALSE otherwise.
278*
279* NOTES
280*	Allows checking the state of a list to determine if invoking
281*	member functions is appropriate.
282*
283* SEE ALSO
284*	List
285*********/
286
287/****f* Component Library: List/cl_list_init
288* NAME
289*	cl_list_init
290*
291* DESCRIPTION
292*	The cl_list_init function initializes a list for use.
293*
294* SYNOPSIS
295*/
296cl_status_t
297cl_list_init(IN cl_list_t * const p_list, IN const size_t min_items);
298/*
299* PARAMETERS
300*	p_list
301*		[in] Pointer to cl_list_t structure to initialize.
302*
303*	min_items
304*		[in] Minimum number of items that can be stored.  All necessary
305*		allocations to allow storing the minimum number of items is performed
306*		at initialization time.
307*
308* RETURN VALUES
309*	CL_SUCCESS if the list was initialized successfully.
310*
311*	CL_INSUFFICIENT_MEMORY if there was not enough memory for initialization.
312*
313* NOTES
314*	The list will always be able to store at least as many items as specified
315*	by the min_items parameter.
316*
317* SEE ALSO
318*	List, cl_list_construct, cl_list_destroy, cl_list_insert_head,
319*	cl_list_insert_tail, cl_list_remove_head, cl_list_remove_tail
320*********/
321
322/****f* Component Library: List/cl_list_destroy
323* NAME
324*	cl_list_destroy
325*
326* DESCRIPTION
327*	The cl_list_destroy function destroys a list.
328*
329* SYNOPSIS
330*/
331void cl_list_destroy(IN cl_list_t * const p_list);
332/*
333* PARAMETERS
334*	p_list
335*		[in] Pointer to cl_list_t structure to destroy.
336*
337* RETURN VALUE
338*	This function does not return a value.
339*
340* NOTES
341*	cl_list_destroy does not affect any of the objects stored in the list,
342*	but does release all memory allocated internally.  Further operations
343*	should not be attempted on the list after cl_list_destroy is invoked.
344*
345*	This function should only be called after a call to cl_list_construct
346*	or cl_list_init.
347*
348*	In debug builds, cl_list_destroy asserts if the list is not empty.
349*
350* SEE ALSO
351*	List, cl_list_construct, cl_list_init
352*********/
353
354/****f* Component Library: List/cl_is_list_empty
355* NAME
356*	cl_is_list_empty
357*
358* DESCRIPTION
359*	The cl_is_list_empty function returns whether a list is empty.
360*
361* SYNOPSIS
362*/
363static inline boolean_t cl_is_list_empty(IN const cl_list_t * const p_list)
364{
365	CL_ASSERT(p_list);
366	CL_ASSERT(cl_is_qpool_inited(&p_list->list_item_pool));
367	return (cl_is_qlist_empty(&p_list->list));
368}
369
370/*
371* PARAMETERS
372*	p_list
373*		[in] Pointer to a cl_list_t structure.
374*
375* RETURN VALUES
376*	TRUE if the specified list is empty.
377*
378*	FALSE otherwise.
379*
380* SEE ALSO
381*	List, cl_list_count, cl_list_remove_all
382*********/
383
384/****f* Component Library: List/cl_list_insert_head
385* NAME
386*	cl_list_insert_head
387*
388* DESCRIPTION
389*	The cl_list_insert_head function inserts an object at the head of a list.
390*
391* SYNOPSIS
392*/
393static inline cl_status_t
394cl_list_insert_head(IN cl_list_t * const p_list, IN const void *const p_object)
395{
396	cl_pool_obj_t *p_pool_obj;
397
398	CL_ASSERT(p_list);
399	CL_ASSERT(cl_is_qpool_inited(&p_list->list_item_pool));
400
401	/* Get a list item to add to the list. */
402	p_pool_obj = (cl_pool_obj_t *) cl_qpool_get(&p_list->list_item_pool);
403	if (!p_pool_obj)
404		return (CL_INSUFFICIENT_MEMORY);
405
406	p_pool_obj->p_object = p_object;
407	cl_qlist_insert_head(&p_list->list, &p_pool_obj->pool_item.list_item);
408	return (CL_SUCCESS);
409}
410
411/*
412* PARAMETERS
413*	p_list
414*		[in] Pointer to a cl_list_t structure into which to insert the object.
415*
416*	p_object
417*		[in] Pointer to an object to insert into the list.
418*
419* RETURN VALUES
420*	CL_SUCCESS if the insertion was successful.
421*
422*	CL_INSUFFICIENT_MEMORY if there was not enough memory for the insertion.
423*
424* NOTES
425*	Inserts the specified object at the head of the list.  List insertion
426*	operations are guaranteed to work for the minimum number of items as
427*	specified in cl_list_init by the min_items parameter.
428*
429* SEE ALSO
430*	List, cl_list_insert_tail, cl_list_insert_array_head,
431*	cl_list_insert_array_tail, cl_list_insert_prev, cl_list_insert_next,
432*	cl_list_remove_head
433*********/
434
435/****f* Component Library: List/cl_list_insert_tail
436* NAME
437*	cl_list_insert_tail
438*
439* DESCRIPTION
440*	The cl_list_insert_tail function inserts an object at the tail of a list.
441*
442* SYNOPSIS
443*/
444static inline cl_status_t
445cl_list_insert_tail(IN cl_list_t * const p_list, IN const void *const p_object)
446{
447	cl_pool_obj_t *p_pool_obj;
448
449	CL_ASSERT(p_list);
450	CL_ASSERT(cl_is_qpool_inited(&p_list->list_item_pool));
451
452	/* Get a list item to add to the list. */
453	p_pool_obj = (cl_pool_obj_t *) cl_qpool_get(&p_list->list_item_pool);
454	if (!p_pool_obj)
455		return (CL_INSUFFICIENT_MEMORY);
456
457	p_pool_obj->p_object = p_object;
458	cl_qlist_insert_tail(&p_list->list, &p_pool_obj->pool_item.list_item);
459	return (CL_SUCCESS);
460}
461
462/*
463* PARAMETERS
464*	p_list
465*		[in] Pointer to a cl_list_t structure into which to insert the object.
466*
467*	p_object
468*		[in] Pointer to an object to insert into the list.
469*
470* RETURN VALUES
471*	CL_SUCCESS if the insertion was successful.
472*
473*	CL_INSUFFICIENT_MEMORY if there was not enough memory for the insertion.
474*
475* NOTES
476*	Inserts the specified object at the tail of the list.  List insertion
477*	operations are guaranteed to work for the minimum number of items as
478*	specified in cl_list_init by the min_items parameter.
479*
480* SEE ALSO
481*	List, cl_list_insert_head, cl_list_insert_array_head,
482*	cl_list_insert_array_tail, cl_list_insert_prev, cl_list_insert_next,
483*	cl_list_remove_tail
484*********/
485
486/****f* Component Library: List/cl_list_insert_array_head
487* NAME
488*	cl_list_insert_array_head
489*
490* DESCRIPTION:
491*	The cl_list_insert_array_head function inserts an array of objects
492*	at the head of a list.
493*
494* SYNOPSIS
495*/
496cl_status_t
497cl_list_insert_array_head(IN cl_list_t * const p_list,
498			  IN const void *const p_array,
499			  IN uint32_t item_count, IN const uint32_t item_size);
500/*
501* PARAMETERS
502*	p_list
503*		[in] Pointer to a cl_list_t structure into which to insert the objects.
504*
505*	p_array
506*		[in] Pointer to the first object in an array.
507*
508*	item_count
509*		[in] Number of objects in the array.
510*
511*	item_size
512*		[in] Size of the objects added to the list.  This is the stride in the
513*		array from one object to the next.
514*
515* RETURN VALUES
516*	CL_SUCCESS if the insertion was successful.
517*
518*	CL_INSUFFICIENT_MEMORY if there was not enough memory for the insertion.
519*
520* NOTES
521*	Inserts all objects in the array to the head of the list, preserving the
522*	ordering of the objects.  If not successful, no items are added.
523*	List insertion operations are guaranteed to work for the minimum number
524*	of items as specified in cl_list_init by the min_items parameter.
525*
526* SEE ALSO
527*	List, cl_list_insert_array_tail, cl_list_insert_head, cl_list_insert_tail,
528*	cl_list_insert_prev, cl_list_insert_next
529*********/
530
531/****f* Component Library: List/cl_list_insert_array_tail
532* NAME
533*	cl_list_insert_array_tail
534*
535* DESCRIPTION
536*	The cl_list_insert_array_tail function inserts an array of objects
537*	at the tail of a list.
538*
539* SYNOPSIS
540*/
541cl_status_t
542cl_list_insert_array_tail(IN cl_list_t * const p_list,
543			  IN const void *const p_array,
544			  IN uint32_t item_count, IN const uint32_t item_size);
545/*
546* PARAMETERS
547*	p_list
548*		[in] Pointer to a cl_list_t structure into which to insert the objects.
549*
550*	p_array
551*		[in] Pointer to the first object in an array.
552*
553*	item_count
554*		[in] Number of objects in the array.
555*
556*	item_size
557*		[in] Size of the objects added to the list.  This is the stride in the
558*		array from one object to the next.
559*
560* RETURN VALUES
561*	CL_SUCCESS if the insertion was successful.
562*
563*	CL_INSUFFICIENT_MEMORY if there was not enough memory for the insertion.
564*
565* NOTES
566*	Inserts all objects in the array to the tail of the list, preserving the
567*	ordering of the objects.  If not successful, no items are added.
568*	List insertion operations are guaranteed to work for the minimum number
569*	of items as specified in cl_list_init by the min_items parameter.
570*
571* SEE ALSO
572*	List, cl_list_insert_array_head, cl_list_insert_head, cl_list_insert_tail,
573*	cl_list_insert_prev, cl_list_insert_next
574*********/
575
576/****f* Component Library: List/cl_list_insert_next
577* NAME
578*	cl_list_insert_next
579*
580* DESCRIPTION
581*	The cl_list_insert_next function inserts an object in a list after
582*	the object associated with a given iterator.
583*
584* SYNOPSIS
585*/
586static inline cl_status_t
587cl_list_insert_next(IN cl_list_t * const p_list,
588		    IN cl_list_iterator_t iterator,
589		    IN const void *const p_object)
590{
591	cl_pool_obj_t *p_pool_obj;
592
593	CL_ASSERT(p_list);
594	CL_ASSERT(cl_is_qpool_inited(&p_list->list_item_pool));
595
596	/* Get a list item to add to the list. */
597	p_pool_obj = (cl_pool_obj_t *) cl_qpool_get(&p_list->list_item_pool);
598	if (!p_pool_obj)
599		return (CL_INSUFFICIENT_MEMORY);
600
601	p_pool_obj->p_object = p_object;
602	cl_qlist_insert_next(&p_list->list, (cl_list_item_t *) iterator,
603			     &p_pool_obj->pool_item.list_item);
604	return (CL_SUCCESS);
605}
606
607/*
608* PARAMETERS
609*	p_list
610*		[in] Pointer to a cl_list_t structure into which to insert the object.
611*
612*	iterator
613*		[in] cl_list_iterator_t returned by a previous call to cl_list_head,
614*		cl_list_tail, cl_list_next, or cl_list_prev.
615*
616*	p_object
617*		[in] Pointer to an object to insert into the list.
618*
619* RETURN VALUES
620*	CL_SUCCESS if the insertion was successful.
621*
622*	CL_INSUFFICIENT_MEMORY if there was not enough memory for the insertion.
623*
624* SEE ALSO
625*	List, cl_list_insert_prev, cl_list_insert_head, cl_list_insert_tail,
626*	cl_list_insert_array_head, cl_list_insert_array_tail
627*********/
628
629/****f* Component Library: List/cl_list_insert_prev
630* NAME
631*	cl_list_insert_prev
632*
633* DESCRIPTION
634*	The cl_list_insert_prev function inserts an object in a list before
635*	the object associated with a given iterator.
636*
637* SYNOPSIS
638*/
639static inline cl_status_t
640cl_list_insert_prev(IN cl_list_t * const p_list,
641		    IN cl_list_iterator_t iterator,
642		    IN const void *const p_object)
643{
644	cl_pool_obj_t *p_pool_obj;
645
646	CL_ASSERT(p_list);
647	CL_ASSERT(cl_is_qpool_inited(&p_list->list_item_pool));
648
649	/* Get a list item to add to the list. */
650	p_pool_obj = (cl_pool_obj_t *) cl_qpool_get(&p_list->list_item_pool);
651	if (!p_pool_obj)
652		return (CL_INSUFFICIENT_MEMORY);
653
654	p_pool_obj->p_object = p_object;
655	cl_qlist_insert_prev(&p_list->list, (cl_list_item_t *) iterator,
656			     &p_pool_obj->pool_item.list_item);
657	return (CL_SUCCESS);
658}
659
660/*
661* PARAMETERS
662*	p_list
663*		[in] Pointer to a cl_list_t structure into which to insert the object.
664*
665*	iterator
666*		[in] cl_list_iterator_t returned by a previous call to cl_list_head,
667*		cl_list_tail, cl_list_next, or cl_list_prev.
668*
669*	p_object
670*		[in] Pointer to an object to insert into the list.
671*
672* RETURN VALUES
673*	CL_SUCCESS if the insertion was successful.
674*
675*	CL_INSUFFICIENT_MEMORY if there was not enough memory for the insertion.
676*
677* SEE ALSO
678*	List, cl_list_insert_next, cl_list_insert_head, cl_list_insert_tail,
679*	cl_list_insert_array_head, cl_list_insert_array_tail
680*********/
681
682/****f* Component Library: List/cl_list_remove_head
683* NAME
684*	cl_list_remove_head
685*
686* DESCRIPTION
687*	The cl_list_remove_head function removes an object from the head of a list.
688*
689* SYNOPSIS
690*/
691static inline void *cl_list_remove_head(IN cl_list_t * const p_list)
692{
693	cl_pool_obj_t *p_pool_obj;
694	void *p_obj;
695
696	CL_ASSERT(p_list);
697	CL_ASSERT(cl_is_qpool_inited(&p_list->list_item_pool));
698
699	/* See if the list is empty. */
700	if (cl_is_qlist_empty(&p_list->list))
701		return (NULL);
702
703	/* Get the item at the head of the list. */
704	p_pool_obj = (cl_pool_obj_t *) cl_qlist_remove_head(&p_list->list);
705
706	p_obj = (void *)p_pool_obj->p_object;
707	/* Place the pool item back into the pool. */
708	cl_qpool_put(&p_list->list_item_pool, &p_pool_obj->pool_item);
709
710	return (p_obj);
711}
712
713/*
714* PARAMETERS
715*	p_list
716*		[in] Pointer to a cl_list_t structure from which to remove an object.
717*
718* RETURN VALUES
719*	Returns the pointer to the object formerly at the head of the list.
720*
721*	NULL if the list was empty.
722*
723* SEE ALSO
724*	List, cl_list_remove_tail, cl_list_remove_all, cl_list_remove_object,
725*	cl_list_remove_item, cl_list_insert_head
726*********/
727
728/****f* Component Library: List/cl_list_remove_tail
729* NAME
730*	cl_list_remove_tail
731*
732* DESCRIPTION
733*	The cl_list_remove_tail function removes an object from the tail of a list.
734*
735* SYNOPSIS
736*/
737static inline void *cl_list_remove_tail(IN cl_list_t * const p_list)
738{
739	cl_pool_obj_t *p_pool_obj;
740
741	CL_ASSERT(p_list);
742	CL_ASSERT(cl_is_qpool_inited(&p_list->list_item_pool));
743
744	/* See if the list is empty. */
745	if (cl_is_qlist_empty(&p_list->list))
746		return (NULL);
747
748	/* Get the item at the head of the list. */
749	p_pool_obj = (cl_pool_obj_t *) cl_qlist_remove_tail(&p_list->list);
750
751	/* Place the list item back into the pool. */
752	cl_qpool_put(&p_list->list_item_pool, &p_pool_obj->pool_item);
753
754	return ((void *)p_pool_obj->p_object);
755}
756
757/*
758* PARAMETERS
759*	p_list
760*		[in] Pointer to a cl_list_t structure from which to remove an object.
761*
762* RETURN VALUES
763*	Returns the pointer to the object formerly at the tail of the list.
764*
765*	NULL if the list was empty.
766*
767* SEE ALSO
768*	List, cl_list_remove_head, cl_list_remove_all, cl_list_remove_object,
769*	cl_list_remove_item, cl_list_insert_head
770*********/
771
772/****f* Component Library: List/cl_list_remove_all
773* NAME
774*	cl_list_remove_all
775*
776* DESCRIPTION
777*	The cl_list_remove_all function removes all objects from a list,
778*	leaving it empty.
779*
780* SYNOPSIS
781*/
782static inline void cl_list_remove_all(IN cl_list_t * const p_list)
783{
784	CL_ASSERT(p_list);
785	CL_ASSERT(cl_is_qpool_inited(&p_list->list_item_pool));
786
787	/* Return all the list items to the pool. */
788	cl_qpool_put_list(&p_list->list_item_pool, &p_list->list);
789}
790
791/*
792* PARAMETERS
793*	p_list
794*		[in] Pointer to a cl_list_t structure from which to remove all objects.
795*
796* RETURN VALUE
797*	This function does not return a value.
798*
799* SEE ALSO
800*	List, cl_list_remove_head, cl_list_remove_tail, cl_list_remove_object,
801*	cl_list_remove_item
802*********/
803
804/****f* Component Library: List/cl_list_remove_object
805* NAME
806*	cl_list_remove_object
807*
808* DESCRIPTION
809*	The cl_list_remove_object function removes a specific object from a list.
810*
811* SYNOPSIS
812*/
813cl_status_t
814cl_list_remove_object(IN cl_list_t * const p_list,
815		      IN const void *const p_object);
816/*
817* PARAMETERS
818*	p_list
819*		[in] Pointer to a cl_list_t structure from which to remove the object.
820*
821*	p_object
822*		[in] Pointer to an object to remove from the list.
823*
824* RETURN VALUES
825*	CL_SUCCESS if the object was removed.
826*
827*	CL_NOT_FOUND if the object was not found in the list.
828*
829* NOTES
830*	Removes the first occurrence of an object from a list.
831*
832* SEE ALSO
833*	List, cl_list_remove_item, cl_list_remove_head, cl_list_remove_tail,
834*	cl_list_remove_all
835*********/
836
837/****f* Component Library: List/cl_list_remove_item
838* NAME
839*	cl_list_remove_item
840*
841* DESCRIPTION
842*	The cl_list_remove_item function removes an object from the head of a list.
843*
844* SYNOPSIS
845*/
846static inline void
847cl_list_remove_item(IN cl_list_t * const p_list, IN cl_list_iterator_t iterator)
848{
849	CL_ASSERT(p_list);
850	CL_ASSERT(cl_is_qpool_inited(&p_list->list_item_pool));
851
852	cl_qlist_remove_item(&p_list->list, (cl_list_item_t *) iterator);
853
854	/* Place the list item back into the pool. */
855	cl_qpool_put(&p_list->list_item_pool, (cl_pool_item_t *) iterator);
856}
857
858/*
859* PARAMETERS
860*	p_list
861*		[in] Pointer to a cl_list_t structure from which to remove the item.
862*
863*	iterator
864*		[in] cl_list_iterator_t returned by a previous call to cl_list_head,
865*		cl_list_tail, cl_list_next, or cl_list_prev.
866*
867* RETURN VALUE
868*	This function does not return a value.
869*
870* SEE ALSO
871*	List, cl_list_remove_object, cl_list_remove_head, cl_list_remove_tail,
872*	cl_list_remove_all
873*********/
874
875/****f* Component Library: List/cl_is_object_in_list
876* NAME
877*	cl_is_object_in_list
878*
879* DESCRIPTION
880*	The cl_is_object_in_list function returns whether an object
881*	is stored in a list.
882*
883* SYNOPSIS
884*/
885boolean_t
886cl_is_object_in_list(IN const cl_list_t * const p_list,
887		     IN const void *const p_object);
888/*
889* PARAMETERS
890*	p_list
891*		[in] Pointer to a cl_list_t structure in which to look for the object.
892*
893*	p_object
894*		[in] Pointer to an object stored in a list.
895*
896* RETURN VALUES
897*	TRUE if p_object was found in the list.
898*
899*	FALSE otherwise.
900*
901* SEE ALSO
902*	List
903*********/
904
905/****f* Component Library: List/cl_list_end
906* NAME
907*	cl_list_end
908*
909* DESCRIPTION
910*	The cl_list_end function returns returns the list iterator for
911*	the end of a list.
912*
913* SYNOPSIS
914*/
915static inline cl_list_iterator_t cl_list_end(IN const cl_list_t * const p_list)
916{
917	CL_ASSERT(p_list);
918	CL_ASSERT(cl_is_qpool_inited(&p_list->list_item_pool));
919
920	return (cl_qlist_end(&p_list->list));
921}
922
923/*
924* PARAMETERS
925*	p_list
926*		[in] Pointer to a cl_list_t structure for which the iterator for the
927*		object at the head is to be returned.
928*
929* RETURN VALUE
930*	cl_list_iterator_t for the end of the list.
931*
932* NOTES
933*	Use cl_list_obj to retrieve the object associated with the
934*	returned cl_list_iterator_t.
935*
936* SEE ALSO
937*	List, cl_list_head, cl_list_tail, cl_list_next, cl_list_prev,
938*	cl_list_obj
939*********/
940
941/****f* Component Library: List/cl_list_head
942* NAME
943*	cl_list_head
944*
945* DESCRIPTION
946*	The cl_list_head function returns returns a list iterator for
947*	the head of a list.
948*
949* SYNOPSIS
950*/
951static inline cl_list_iterator_t cl_list_head(IN const cl_list_t * const p_list)
952{
953	CL_ASSERT(p_list);
954	CL_ASSERT(cl_is_qpool_inited(&p_list->list_item_pool));
955
956	return (cl_qlist_head(&p_list->list));
957}
958
959/*
960* PARAMETERS
961*	p_list
962*		[in] Pointer to a cl_list_t structure for which the iterator for the
963*		object at the head is to be returned.
964*
965* RETURN VALUES
966*	cl_list_iterator_t for the head of the list.
967*
968*	cl_list_iterator_t for the end of the list if the list is empty.
969*
970* NOTES
971*	Use cl_list_obj to retrieve the object associated with the
972*	returned cl_list_iterator_t.
973*
974* SEE ALSO
975*	List, cl_list_tail, cl_list_next, cl_list_prev, cl_list_end,
976*	cl_list_obj
977*********/
978
979/****f* Component Library: List/cl_list_tail
980* NAME
981*	cl_list_tail
982*
983* DESCRIPTION
984*	The cl_list_tail function returns returns a list iterator for
985*	the tail of a list.
986*
987* SYNOPSIS
988*/
989static inline cl_list_iterator_t cl_list_tail(IN const cl_list_t * const p_list)
990{
991	CL_ASSERT(p_list);
992	CL_ASSERT(cl_is_qpool_inited(&p_list->list_item_pool));
993
994	return (cl_qlist_tail(&p_list->list));
995}
996
997/*
998* PARAMETERS
999*	p_list
1000*		[in] Pointer to a cl_list_t structure for which the iterator for the
1001*		object at the tail is to be returned.
1002*
1003* RETURN VALUES
1004*	cl_list_iterator_t for the tail of the list.
1005*
1006*	cl_list_iterator_t for the end of the list if the list is empty.
1007*
1008* NOTES
1009*	Use cl_list_obj to retrieve the object associated with the
1010*
1011*	returned cl_list_iterator_t.
1012*
1013* SEE ALSO
1014*	List, cl_list_head, cl_list_next, cl_list_prev, cl_list_end,
1015*	cl_list_obj
1016*********/
1017
1018/****f* Component Library: List/cl_list_next
1019* NAME
1020*	cl_list_next
1021*
1022* DESCRIPTION
1023*	The cl_list_next function returns a list iterator for the object stored
1024*	in a list after the object associated with a given list iterator.
1025*
1026* SYNOPSIS
1027*/
1028static inline cl_list_iterator_t cl_list_next(IN cl_list_iterator_t iterator)
1029{
1030	CL_ASSERT(iterator);
1031
1032	return (cl_qlist_next(iterator));
1033}
1034
1035/*
1036* PARAMETERS
1037*	p_list
1038*		[in] Pointer to a cl_list_t structure for which the iterator for the
1039*		next object is to be returned.
1040*
1041*	iterator
1042*		[in] cl_list_iterator_t returned by a previous call to cl_list_head,
1043*		cl_list_tail, cl_list_next, or cl_list_prev.
1044*
1045* RETURN VALUES
1046*	cl_list_iterator_t for the object following the object associated with
1047*	the list iterator specified by the iterator parameter.
1048*
1049*	cl_list_iterator_t for the end of the list if the list is empty.
1050*
1051* NOTES
1052*	Use cl_list_obj to retrieve the object associated with the
1053*	returned cl_list_iterator_t.
1054*
1055* SEE ALSO
1056*	List, cl_list_prev, cl_list_head, cl_list_tail, cl_list_end,
1057*	cl_list_obj
1058*********/
1059
1060/****f* Component Library: List/cl_list_prev
1061* NAME
1062*	cl_list_prev
1063*
1064* DESCRIPTION
1065*	The cl_list_prev function returns a list iterator for the object stored
1066*	in a list before the object associated with a given list iterator.
1067*
1068* SYNOPSIS
1069*/
1070static inline cl_list_iterator_t cl_list_prev(IN cl_list_iterator_t iterator)
1071{
1072	CL_ASSERT(iterator);
1073
1074	return (cl_qlist_prev(iterator));
1075}
1076
1077/*
1078* PARAMETERS
1079*	p_list
1080*		[in] Pointer to a cl_list_t structure for which the iterator for the
1081*		next object is to be returned.
1082*
1083*	iterator
1084*		[in] cl_list_iterator_t returned by a previous call to cl_list_head,
1085*		cl_list_tail, cl_list_next, or cl_list_prev.
1086*
1087* RETURN VALUES
1088*	cl_list_iterator_t for the object preceding the object associated with
1089*	the list iterator specified by the iterator parameter.
1090*
1091*	cl_list_iterator_t for the end of the list if the list is empty.
1092*
1093* NOTES
1094*	Use cl_list_obj to retrieve the object associated with the
1095*	returned cl_list_iterator_t.
1096*
1097* SEE ALSO
1098*	List, cl_list_next, cl_list_head, cl_list_tail, cl_list_end,
1099*	cl_list_obj
1100*********/
1101
1102/****f* Component Library: List/cl_list_obj
1103* NAME
1104*	cl_list_obj
1105*
1106* DESCRIPTION
1107*	The cl_list_obj function returns the object associated
1108*	with a list iterator.
1109*
1110* SYNOPSIS
1111*/
1112static inline void *cl_list_obj(IN cl_list_iterator_t iterator)
1113{
1114	CL_ASSERT(iterator);
1115
1116	return ((void *)((cl_pool_obj_t *) iterator)->p_object);
1117}
1118
1119/*
1120* PARAMETERS
1121*	iterator
1122*		[in] cl_list_iterator_t returned by a previous call to cl_list_head,
1123*		cl_list_tail, cl_list_next, or cl_list_prev whose object is requested.
1124*
1125* RETURN VALUE
1126*	Pointer to the object associated with the list iterator specified
1127*	by the iterator parameter.
1128*
1129* SEE ALSO
1130*	List, cl_list_head, cl_list_tail, cl_list_next, cl_list_prev
1131*********/
1132
1133/****f* Component Library: List/cl_list_find_from_head
1134* NAME
1135*	cl_list_find_from_head
1136*
1137* DESCRIPTION
1138*	The cl_list_find_from_head function uses a specified function
1139*	to search for an object starting from the head of a list.
1140*
1141* SYNOPSIS
1142*/
1143cl_list_iterator_t
1144cl_list_find_from_head(IN const cl_list_t * const p_list,
1145		       IN cl_pfn_list_find_t pfn_func,
1146		       IN const void *const context);
1147/*
1148* PARAMETERS
1149*	p_list
1150*		[in] Pointer to a cl_list_t structure to search.
1151*
1152*	pfn_func
1153*		[in] Function invoked to determine if a match was found.
1154*		See the cl_pfn_list_find_t function type declaration for details
1155*		about the callback function.
1156*
1157*	context
1158*		[in] Value to pass to the callback functions to provide context.
1159*
1160* RETURN VALUES
1161*	Returns the iterator for the object if found.
1162*
1163*	Returns the iterator for the list end otherwise.
1164*
1165* NOTES
1166*	cl_list_find_from_head does not remove the found object from
1167*	the list.  The iterator for the object is returned when the function
1168*	provided by the pfn_func parameter returns CL_SUCCESS.  The function
1169*	specified by the pfn_func parameter must not perform any list
1170*	operations as these would corrupt the list.
1171*
1172* SEE ALSO
1173*	List, cl_list_find_from_tail, cl_list_apply_func_t,
1174*	cl_pfn_list_find_t
1175*********/
1176
1177/****f* Component Library: List/cl_list_find_from_tail
1178* NAME
1179*	cl_list_find_from_tail
1180*
1181* DESCRIPTION
1182*	The cl_list_find_from_tail function uses a specified function
1183*	to search for an object starting from the tail of a list.
1184*
1185* SYNOPSIS
1186*/
1187cl_list_iterator_t
1188cl_list_find_from_tail(IN const cl_list_t * const p_list,
1189		       IN cl_pfn_list_find_t pfn_func,
1190		       IN const void *const context);
1191/*
1192* PARAMETERS
1193*	p_list
1194*		[in] Pointer to a cl_list_t structure to search.
1195*
1196*	pfn_func
1197*		[in] Function invoked to determine if a match was found.
1198*		See the cl_pfn_list_find_t function type declaration for details
1199*		about the callback function.
1200*
1201*	context
1202*		[in] Value to pass to the callback functions to provide context.
1203*
1204* RETURN VALUES
1205*	Returns the iterator for the object if found.
1206*
1207*	Returns the iterator for the list end otherwise.
1208*
1209* NOTES
1210*	cl_list_find_from_tail does not remove the found object from
1211*	the list.  The iterator for the object is returned when the function
1212*	provided by the pfn_func parameter returns CL_SUCCESS.  The function
1213*	specified by the pfn_func parameter must not perform any list
1214*	operations as these would corrupt the list.
1215*
1216* SEE ALSO
1217*	List, cl_list_find_from_head, cl_list_apply_func_t,
1218*	cl_pfn_list_find_t
1219*********/
1220
1221/****f* Component Library: List/cl_list_apply_func
1222* NAME
1223*	cl_list_apply_func
1224*
1225* DESCRIPTION
1226*	The cl_list_apply_func function executes a specified function for every
1227*	object stored in a list.
1228*
1229* SYNOPSIS
1230*/
1231void
1232cl_list_apply_func(IN const cl_list_t * const p_list,
1233		   IN cl_pfn_list_apply_t pfn_func,
1234		   IN const void *const context);
1235/*
1236* PARAMETERS
1237*	p_list
1238*		[in] Pointer to a cl_list_t structure to iterate.
1239*
1240*	pfn_func
1241*		[in] Function invoked for every item in a list.
1242*		See the cl_pfn_list_apply_t function type declaration for details
1243*		about the callback function.
1244*
1245*	context
1246*		[in] Value to pass to the callback functions to provide context.
1247*
1248* RETURN VALUE
1249*	This function does not return a value.
1250*
1251* NOTES
1252*	cl_list_apply_func invokes the specified callback function for every
1253*	object stored in the list, starting from the head.  The function specified
1254*	by the pfn_func parameter must not perform any list operations as these
1255*	would corrupt the list.
1256*
1257* SEE ALSO
1258*	List, cl_list_find_from_head, cl_list_find_from_tail,
1259*	cl_pfn_list_apply_t
1260*********/
1261
1262/****f* Component Library: List/cl_list_count
1263* NAME
1264*	cl_list_count
1265*
1266* DESCRIPTION
1267*	The cl_list_count function returns the number of objects stored in a list.
1268*
1269* SYNOPSIS
1270*/
1271static inline size_t cl_list_count(IN const cl_list_t * const p_list)
1272{
1273	CL_ASSERT(p_list);
1274	CL_ASSERT(cl_is_qpool_inited(&p_list->list_item_pool));
1275
1276	return (cl_qlist_count(&p_list->list));
1277}
1278
1279/*
1280* PARAMETERS
1281*	p_list
1282*		[in] Pointer to a cl_list_t structure whose object to count.
1283*
1284* RETURN VALUES
1285*	Number of objects stored in the specified list.
1286*
1287* SEE ALSO
1288*	List
1289*********/
1290
1291END_C_DECLS
1292#endif				/* _CL_LIST_H_ */
1293