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 */
cl_is_list_inited(IN const cl_list_t * const p_list)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 */
cl_is_list_empty(IN const cl_list_t * const p_list)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
cl_list_insert_head(IN cl_list_t * const p_list,IN const void * const p_object)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
cl_list_insert_tail(IN cl_list_t * const p_list,IN const void * const p_object)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
cl_list_insert_next(IN cl_list_t * const p_list,IN cl_list_iterator_t iterator,IN const void * const p_object)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
cl_list_insert_prev(IN cl_list_t * const p_list,IN cl_list_iterator_t iterator,IN const void * const p_object)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 */
cl_list_remove_head(IN cl_list_t * const p_list)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 */
cl_list_remove_tail(IN cl_list_t * const p_list)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 */
cl_list_remove_all(IN cl_list_t * const p_list)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
cl_list_remove_item(IN cl_list_t * const p_list,IN cl_list_iterator_t iterator)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 */
cl_list_end(IN const cl_list_t * const p_list)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 */
cl_list_head(IN const cl_list_t * const p_list)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 */
cl_list_tail(IN const cl_list_t * const p_list)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 */
cl_list_next(IN cl_list_iterator_t iterator)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 */
cl_list_prev(IN cl_list_iterator_t iterator)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 */
cl_list_obj(IN cl_list_iterator_t iterator)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 */
cl_list_count(IN const cl_list_t * const p_list)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_ */
1293