]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/ofed/management/opensm/include/complib/cl_list.h
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / ofed / management / opensm / include / complib / cl_list.h
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
55 BEGIN_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 */
118 typedef 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 */
143 typedef 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 */
163 typedef 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 */
195 typedef 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 */
228 void 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 */
257 static 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 */
296 cl_status_t
297 cl_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 */
331 void 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 */
363 static 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 */
393 static inline cl_status_t
394 cl_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 */
444 static inline cl_status_t
445 cl_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 */
496 cl_status_t
497 cl_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 */
541 cl_status_t
542 cl_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 */
586 static inline cl_status_t
587 cl_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 */
639 static inline cl_status_t
640 cl_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 */
691 static 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 */
737 static 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 */
782 static 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 */
813 cl_status_t
814 cl_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 */
846 static inline void
847 cl_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 */
885 boolean_t
886 cl_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 */
915 static 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 */
951 static 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 */
989 static 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 */
1028 static 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 */
1070 static 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 */
1112 static 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 */
1143 cl_list_iterator_t
1144 cl_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 */
1187 cl_list_iterator_t
1188 cl_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 */
1231 void
1232 cl_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 */
1271 static 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
1291 END_C_DECLS
1292 #endif                          /* _CL_LIST_H_ */