2 .\" The Regents of the University of California. All rights reserved.
4 .\" Redistribution and use in source and binary forms, with or without
5 .\" modification, are permitted provided that the following conditions
7 .\" 1. Redistributions of source code must retain the above copyright
8 .\" notice, this list of conditions and the following disclaimer.
9 .\" 2. Redistributions in binary form must reproduce the above copyright
10 .\" notice, this list of conditions and the following disclaimer in the
11 .\" documentation and/or other materials provided with the distribution.
12 .\" 3. All advertising materials mentioning features or use of this software
13 .\" must display the following acknowledgement:
14 .\" This product includes software developed by the University of
15 .\" California, Berkeley and its contributors.
16 .\" 4. Neither the name of the University nor the names of its contributors
17 .\" may be used to endorse or promote products derived from this software
18 .\" without specific prior written permission.
20 .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 .\" @(#)queue.3 8.2 (Berkeley) 1/24/94
43 .Nm SLIST_FOREACH_SAFE ,
45 .Nm SLIST_HEAD_INITIALIZER ,
47 .Nm SLIST_INSERT_AFTER ,
48 .Nm SLIST_INSERT_HEAD ,
50 .Nm SLIST_REMOVE_HEAD ,
57 .Nm STAILQ_FOREACH_SAFE ,
59 .Nm STAILQ_HEAD_INITIALIZER ,
61 .Nm STAILQ_INSERT_AFTER ,
62 .Nm STAILQ_INSERT_HEAD ,
63 .Nm STAILQ_INSERT_TAIL ,
66 .Nm STAILQ_REMOVE_HEAD ,
72 .Nm LIST_FOREACH_SAFE ,
74 .Nm LIST_HEAD_INITIALIZER ,
76 .Nm LIST_INSERT_AFTER ,
77 .Nm LIST_INSERT_BEFORE ,
78 .Nm LIST_INSERT_HEAD ,
86 .Nm TAILQ_FOREACH_SAFE ,
87 .Nm TAILQ_FOREACH_REVERSE ,
88 .Nm TAILQ_FOREACH_REVERSE_SAFE ,
90 .Nm TAILQ_HEAD_INITIALIZER ,
92 .Nm TAILQ_INSERT_AFTER ,
93 .Nm TAILQ_INSERT_BEFORE ,
94 .Nm TAILQ_INSERT_HEAD ,
95 .Nm TAILQ_INSERT_TAIL ,
100 .Nd implementations of singly-linked lists, singly-linked tail queues,
101 lists and tail queues
105 .Fn SLIST_EMPTY "SLIST_HEAD *head"
106 .Fn SLIST_ENTRY "TYPE"
107 .Fn SLIST_FIRST "SLIST_HEAD *head"
108 .Fn SLIST_FOREACH "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME"
109 .Fn SLIST_FOREACH_SAFE "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME" "TYPE *temp_var"
110 .Fn SLIST_HEAD "HEADNAME" "TYPE"
111 .Fn SLIST_HEAD_INITIALIZER "SLIST_HEAD head"
112 .Fn SLIST_INIT "SLIST_HEAD *head"
113 .Fn SLIST_INSERT_AFTER "TYPE *listelm" "TYPE *elm" "SLIST_ENTRY NAME"
114 .Fn SLIST_INSERT_HEAD "SLIST_HEAD *head" "TYPE *elm" "SLIST_ENTRY NAME"
115 .Fn SLIST_NEXT "TYPE *elm" "SLIST_ENTRY NAME"
116 .Fn SLIST_REMOVE_HEAD "SLIST_HEAD *head" "SLIST_ENTRY NAME"
117 .Fn SLIST_REMOVE "SLIST_HEAD *head" "TYPE *elm" "TYPE" "SLIST_ENTRY NAME"
119 .Fn STAILQ_CONCAT "STAILQ_HEAD *head1" "STAILQ_HEAD *head2"
120 .Fn STAILQ_EMPTY "STAILQ_HEAD *head"
121 .Fn STAILQ_ENTRY "TYPE"
122 .Fn STAILQ_FIRST "STAILQ_HEAD *head"
123 .Fn STAILQ_FOREACH "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME"
124 .Fn STAILQ_FOREACH_SAFE "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" "TYPE *temp_var"
125 .Fn STAILQ_HEAD "HEADNAME" "TYPE"
126 .Fn STAILQ_HEAD_INITIALIZER "STAILQ_HEAD head"
127 .Fn STAILQ_INIT "STAILQ_HEAD *head"
128 .Fn STAILQ_INSERT_AFTER "STAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "STAILQ_ENTRY NAME"
129 .Fn STAILQ_INSERT_HEAD "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
130 .Fn STAILQ_INSERT_TAIL "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
131 .Fn STAILQ_LAST "STAILQ_HEAD *head" "TYPE" "STAILQ_ENTRY NAME"
132 .Fn STAILQ_NEXT "TYPE *elm" "STAILQ_ENTRY NAME"
133 .Fn STAILQ_REMOVE_HEAD "STAILQ_HEAD *head" "STAILQ_ENTRY NAME"
134 .Fn STAILQ_REMOVE "STAILQ_HEAD *head" "TYPE *elm" "TYPE" "STAILQ_ENTRY NAME"
136 .Fn LIST_EMPTY "LIST_HEAD *head"
137 .Fn LIST_ENTRY "TYPE"
138 .Fn LIST_FIRST "LIST_HEAD *head"
139 .Fn LIST_FOREACH "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME"
140 .Fn LIST_FOREACH_SAFE "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME" "TYPE *temp_var"
141 .Fn LIST_HEAD "HEADNAME" "TYPE"
142 .Fn LIST_HEAD_INITIALIZER "LIST_HEAD head"
143 .Fn LIST_INIT "LIST_HEAD *head"
144 .Fn LIST_INSERT_AFTER "TYPE *listelm" "TYPE *elm" "LIST_ENTRY NAME"
145 .Fn LIST_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "LIST_ENTRY NAME"
146 .Fn LIST_INSERT_HEAD "LIST_HEAD *head" "TYPE *elm" "LIST_ENTRY NAME"
147 .Fn LIST_NEXT "TYPE *elm" "LIST_ENTRY NAME"
148 .Fn LIST_REMOVE "TYPE *elm" "LIST_ENTRY NAME"
150 .Fn TAILQ_CONCAT "TAILQ_HEAD *head1" "TAILQ_HEAD *head2" "TAILQ_ENTRY NAME"
151 .Fn TAILQ_EMPTY "TAILQ_HEAD *head"
152 .Fn TAILQ_ENTRY "TYPE"
153 .Fn TAILQ_FIRST "TAILQ_HEAD *head"
154 .Fn TAILQ_FOREACH "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME"
155 .Fn TAILQ_FOREACH_SAFE "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME" "TYPE *temp_var"
156 .Fn TAILQ_FOREACH_REVERSE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME"
157 .Fn TAILQ_FOREACH_REVERSE_SAFE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME" "TYPE *temp_var"
158 .Fn TAILQ_HEAD "HEADNAME" "TYPE"
159 .Fn TAILQ_HEAD_INITIALIZER "TAILQ_HEAD head"
160 .Fn TAILQ_INIT "TAILQ_HEAD *head"
161 .Fn TAILQ_INSERT_AFTER "TAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME"
162 .Fn TAILQ_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME"
163 .Fn TAILQ_INSERT_HEAD "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
164 .Fn TAILQ_INSERT_TAIL "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
165 .Fn TAILQ_LAST "TAILQ_HEAD *head" "HEADNAME"
166 .Fn TAILQ_NEXT "TYPE *elm" "TAILQ_ENTRY NAME"
167 .Fn TAILQ_PREV "TYPE *elm" "HEADNAME" "TAILQ_ENTRY NAME"
168 .Fn TAILQ_REMOVE "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
171 These macros define and operate on four types of data structures:
172 singly-linked lists, singly-linked tail queues, lists, and tail queues.
173 All four structures support the following functionality:
174 .Bl -enum -compact -offset indent
176 Insertion of a new entry at the head of the list.
178 Insertion of a new entry after any element in the list.
180 O(1) removal of an entry from the head of the list.
182 Forward traversal through the list.
185 O(n) removal of any entry in the list.
186 Singly-linked lists are the simplest of the four data structures
187 and support only the above functionality.
188 Singly-linked lists are ideal for applications with large datasets
189 and few or no removals,
190 or for implementing a LIFO queue.
191 Singly-linked lists add the following functionality:
192 .Bl -enum -compact -offset indent
194 O(n) removal of any entry in the list.
197 Singly-linked tail queues add the following functionality:
198 .Bl -enum -compact -offset indent
200 Entries can be added at the end of a list.
202 O(n) removal of any entry in the list.
204 They may be concatenated.
207 .Bl -enum -compact -offset indent
209 All list insertions must specify the head of the list.
211 Each head entry requires two pointers rather than one.
213 Code size is about 15% greater and operations run about 20% slower
214 than singly-linked lists.
217 Singly-linked tailqs are ideal for applications with large datasets and
219 or for implementing a FIFO queue.
221 All doubly linked types of data structures (lists and tail queues)
223 .Bl -enum -compact -offset indent
225 Insertion of a new entry before any element in the list.
227 O(1) removal of any entry in the list.
230 .Bl -enum -compact -offset indent
232 Each elements requires two pointers rather than one.
234 Code size and execution time of operations (except for removal) is about
235 twice that of the singly-linked data-structures.
238 Linked lists are the simplest of the doubly linked data structures and support
239 only the above functionality over singly-linked lists.
241 Tail queues add the following functionality:
242 .Bl -enum -compact -offset indent
244 Entries can be added at the end of a list.
246 They may be traversed backwards, from tail to head.
248 They may be concatenated.
251 .Bl -enum -compact -offset indent
253 All list insertions and removals must specify the head of the list.
255 Each head entry requires two pointers rather than one.
257 Code size is about 15% greater and operations run about 20% slower
258 than singly-linked lists.
261 In the macro definitions,
263 is the name of a user defined structure,
264 that must contain a field of type
274 is the name of a user defined structure that must be declared
281 See the examples below for further explanation of how these
283 .Sh SINGLY-LINKED LISTS
284 A singly-linked list is headed by a structure defined by the
287 This structure contains a single pointer to the first element
289 The elements are singly linked for minimum space and pointer manipulation
290 overhead at the expense of O(n) removal for arbitrary elements.
291 New elements can be added to the list after an existing element or
292 at the head of the list.
295 structure is declared as follows:
296 .Bd -literal -offset indent
297 SLIST_HEAD(HEADNAME, TYPE) head;
302 is the name of the structure to be defined, and
304 is the type of the elements to be linked into the list.
305 A pointer to the head of the list can later be declared as:
306 .Bd -literal -offset indent
307 struct HEADNAME *headp;
314 are user selectable.)
317 .Nm SLIST_HEAD_INITIALIZER
318 evaluates to an initializer for the list
323 evaluates to true if there are no elements in the list.
327 declares a structure that connects the elements in
332 returns the first element in the list or NULL if the list is empty.
336 traverses the list referenced by
338 in the forward direction, assigning each element in
343 .Nm SLIST_FOREACH_SAFE
344 traverses the list referenced by
346 in the forward direction, assigning each element in
351 here it is permitted to both remove
353 as well as free it from within the loop safely without interfering with the
358 initializes the list referenced by
362 .Nm SLIST_INSERT_HEAD
363 inserts the new element
365 at the head of the list.
368 .Nm SLIST_INSERT_AFTER
369 inserts the new element
376 returns the next element in the list.
379 .Nm SLIST_REMOVE_HEAD
382 from the head of the list.
383 For optimum efficiency,
384 elements being removed from the head of the list should explicitly use
385 this macro instead of the generic
394 .Sh SINGLY-LINKED LIST EXAMPLE
396 SLIST_HEAD(slisthead, entry) head =
397 SLIST_HEAD_INITIALIZER(head);
398 struct slisthead *headp; /* Singly-linked List head. */
401 SLIST_ENTRY(entry) entries; /* Singly-linked List. */
403 } *n1, *n2, *n3, *np;
405 SLIST_INIT(&head); /* Initialize the list. */
407 n1 = malloc(sizeof(struct entry)); /* Insert at the head. */
408 SLIST_INSERT_HEAD(&head, n1, entries);
410 n2 = malloc(sizeof(struct entry)); /* Insert after. */
411 SLIST_INSERT_AFTER(n1, n2, entries);
413 SLIST_REMOVE(&head, n2, entry, entries);/* Deletion. */
416 n3 = SLIST_FIRST(&head);
417 SLIST_REMOVE_HEAD(&head, entries); /* Deletion from the head. */
419 /* Forward traversal. */
420 SLIST_FOREACH(np, &head, entries)
422 /* Safe forward traversal. */
423 SLIST_FOREACH_SAFE(np, &head, entries, np_temp) {
426 SLIST_REMOVE(&head, np, entry, entries);
430 while (!SLIST_EMPTY(&head)) { /* List Deletion. */
431 n1 = SLIST_FIRST(&head);
432 SLIST_REMOVE_HEAD(&head, entries);
436 .Sh SINGLY-LINKED TAIL QUEUES
437 A singly-linked tail queue is headed by a structure defined by the
440 This structure contains a pair of pointers,
441 one to the first element in the tail queue and the other to
442 the last element in the tail queue.
443 The elements are singly linked for minimum space and pointer
444 manipulation overhead at the expense of O(n) removal for arbitrary
446 New elements can be added to the tail queue after an existing element,
447 at the head of the tail queue, or at the end of the tail queue.
450 structure is declared as follows:
451 .Bd -literal -offset indent
452 STAILQ_HEAD(HEADNAME, TYPE) head;
457 is the name of the structure to be defined, and
459 is the type of the elements to be linked into the tail queue.
460 A pointer to the head of the tail queue can later be declared as:
461 .Bd -literal -offset indent
462 struct HEADNAME *headp;
469 are user selectable.)
472 .Nm STAILQ_HEAD_INITIALIZER
473 evaluates to an initializer for the tail queue
478 concatenates the tail queue headed by
480 onto the end of the one headed by
482 removing all entries from the former.
486 evaluates to true if there are no items on the tail queue.
490 declares a structure that connects the elements in
495 returns the first item on the tail queue or NULL if the tail queue
500 traverses the tail queue referenced by
502 in the forward direction, assigning each element
507 .Nm STAILQ_FOREACH_SAFE
508 traverses the tail queue referenced by
510 in the forward direction, assigning each element
515 here it is permitted to both remove
517 as well as free it from within the loop safely without interfering with the
522 initializes the tail queue referenced by
526 .Nm STAILQ_INSERT_HEAD
527 inserts the new element
529 at the head of the tail queue.
532 .Nm STAILQ_INSERT_TAIL
533 inserts the new element
535 at the end of the tail queue.
538 .Nm STAILQ_INSERT_AFTER
539 inserts the new element
546 returns the last item on the tail queue.
547 If the tail queue is empty the return value is
552 returns the next item on the tail queue, or NULL this item is the last.
555 .Nm STAILQ_REMOVE_HEAD
556 removes the element at the head of the tail queue.
557 For optimum efficiency,
558 elements being removed from the head of the tail queue should
559 use this macro explicitly rather than the generic
568 .Sh SINGLY-LINKED TAIL QUEUE EXAMPLE
570 STAILQ_HEAD(stailhead, entry) head =
571 STAILQ_HEAD_INITIALIZER(head);
572 struct stailhead *headp; /* Singly-linked tail queue head. */
575 STAILQ_ENTRY(entry) entries; /* Tail queue. */
577 } *n1, *n2, *n3, *np;
579 STAILQ_INIT(&head); /* Initialize the queue. */
581 n1 = malloc(sizeof(struct entry)); /* Insert at the head. */
582 STAILQ_INSERT_HEAD(&head, n1, entries);
584 n1 = malloc(sizeof(struct entry)); /* Insert at the tail. */
585 STAILQ_INSERT_TAIL(&head, n1, entries);
587 n2 = malloc(sizeof(struct entry)); /* Insert after. */
588 STAILQ_INSERT_AFTER(&head, n1, n2, entries);
590 STAILQ_REMOVE(&head, n2, entry, entries);
592 /* Deletion from the head. */
593 n3 = STAILQ_FIRST(&head);
594 STAILQ_REMOVE_HEAD(&head, entries);
596 /* Forward traversal. */
597 STAILQ_FOREACH(np, &head, entries)
599 /* Safe forward traversal. */
600 STAILQ_FOREACH_SAFE(np, &head, entries, np_temp) {
603 STAILQ_REMOVE(&head, np, entry, entries);
606 /* TailQ Deletion. */
607 while (!STAILQ_EMPTY(&head)) {
608 n1 = STAILQ_FIRST(&head);
609 STAILQ_REMOVE_HEAD(&head, entries);
612 /* Faster TailQ Deletion. */
613 n1 = STAILQ_FIRST(&head);
615 n2 = STAILQ_NEXT(n1, entries);
622 A list is headed by a structure defined by the
625 This structure contains a single pointer to the first element
627 The elements are doubly linked so that an arbitrary element can be
628 removed without traversing the list.
629 New elements can be added to the list after an existing element,
630 before an existing element, or at the head of the list.
633 structure is declared as follows:
634 .Bd -literal -offset indent
635 LIST_HEAD(HEADNAME, TYPE) head;
640 is the name of the structure to be defined, and
642 is the type of the elements to be linked into the list.
643 A pointer to the head of the list can later be declared as:
644 .Bd -literal -offset indent
645 struct HEADNAME *headp;
652 are user selectable.)
655 .Nm LIST_HEAD_INITIALIZER
656 evaluates to an initializer for the list
661 evaluates to true if there are no elements in the list.
665 declares a structure that connects the elements in
670 returns the first element in the list or NULL if the list
675 traverses the list referenced by
677 in the forward direction, assigning each element in turn to
681 .Nm LIST_FOREACH_SAFE
682 traverses the list referenced by
684 in the forward direction, assigning each element in turn to
688 here it is permitted to both remove
690 as well as free it from within the loop safely without interfering with the
695 initializes the list referenced by
700 inserts the new element
702 at the head of the list.
705 .Nm LIST_INSERT_AFTER
706 inserts the new element
712 .Nm LIST_INSERT_BEFORE
713 inserts the new element
720 returns the next element in the list, or NULL if this is the last.
729 LIST_HEAD(listhead, entry) head =
730 LIST_HEAD_INITIALIZER(head);
731 struct listhead *headp; /* List head. */
734 LIST_ENTRY(entry) entries; /* List. */
736 } *n1, *n2, *n3, *np, *np_temp;
738 LIST_INIT(&head); /* Initialize the list. */
740 n1 = malloc(sizeof(struct entry)); /* Insert at the head. */
741 LIST_INSERT_HEAD(&head, n1, entries);
743 n2 = malloc(sizeof(struct entry)); /* Insert after. */
744 LIST_INSERT_AFTER(n1, n2, entries);
746 n3 = malloc(sizeof(struct entry)); /* Insert before. */
747 LIST_INSERT_BEFORE(n2, n3, entries);
749 LIST_REMOVE(n2, entries); /* Deletion. */
751 /* Forward traversal. */
752 LIST_FOREACH(np, &head, entries)
755 /* Safe forward traversal. */
756 LIST_FOREACH_SAFE(np, &head, entries, np_temp) {
759 LIST_REMOVE(np, entries);
763 while (!LIST_EMPTY(&head)) { /* List Deletion. */
764 n1 = LIST_FIRST(&head);
765 LIST_REMOVE(n1, entries);
769 n1 = LIST_FIRST(&head); /* Faster List Deletion. */
771 n2 = LIST_NEXT(n1, entries);
778 A tail queue is headed by a structure defined by the
781 This structure contains a pair of pointers,
782 one to the first element in the tail queue and the other to
783 the last element in the tail queue.
784 The elements are doubly linked so that an arbitrary element can be
785 removed without traversing the tail queue.
786 New elements can be added to the tail queue after an existing element,
787 before an existing element, at the head of the tail queue,
788 or at the end of the tail queue.
791 structure is declared as follows:
792 .Bd -literal -offset indent
793 TAILQ_HEAD(HEADNAME, TYPE) head;
798 is the name of the structure to be defined, and
800 is the type of the elements to be linked into the tail queue.
801 A pointer to the head of the tail queue can later be declared as:
802 .Bd -literal -offset indent
803 struct HEADNAME *headp;
810 are user selectable.)
813 .Nm TAILQ_HEAD_INITIALIZER
814 evaluates to an initializer for the tail queue
819 concatenates the tail queue headed by
821 onto the end of the one headed by
823 removing all entries from the former.
827 evaluates to true if there are no items on the tail queue.
831 declares a structure that connects the elements in
836 returns the first item on the tail queue or NULL if the tail queue
841 traverses the tail queue referenced by
843 in the forward direction, assigning each element in turn to
848 if the loop completes normally, or if there were no elements.
851 .Nm TAILQ_FOREACH_REVERSE
852 traverses the tail queue referenced by
854 in the reverse direction, assigning each element in turn to
858 .Nm TAILQ_FOREACH_SAFE
860 .Nm TAILQ_FOREACH_REVERSE_SAFE
861 traverse the list referenced by
863 in the forward or reverse direction respectively,
864 assigning each element in turn to
866 However, unlike their unsafe counterparts,
869 .Nm TAILQ_FOREACH_REVERSE
870 permit to both remove
872 as well as free it from within the loop safely without interfering with the
877 initializes the tail queue referenced by
881 .Nm TAILQ_INSERT_HEAD
882 inserts the new element
884 at the head of the tail queue.
887 .Nm TAILQ_INSERT_TAIL
888 inserts the new element
890 at the end of the tail queue.
893 .Nm TAILQ_INSERT_AFTER
894 inserts the new element
900 .Nm TAILQ_INSERT_BEFORE
901 inserts the new element
908 returns the last item on the tail queue.
909 If the tail queue is empty the return value is
914 returns the next item on the tail queue, or NULL if this item is the last.
918 returns the previous item on the tail queue, or NULL if this item
926 .Sh TAIL QUEUE EXAMPLE
928 TAILQ_HEAD(tailhead, entry) head =
929 TAILQ_HEAD_INITIALIZER(head);
930 struct tailhead *headp; /* Tail queue head. */
933 TAILQ_ENTRY(entry) entries; /* Tail queue. */
935 } *n1, *n2, *n3, *np;
937 TAILQ_INIT(&head); /* Initialize the queue. */
939 n1 = malloc(sizeof(struct entry)); /* Insert at the head. */
940 TAILQ_INSERT_HEAD(&head, n1, entries);
942 n1 = malloc(sizeof(struct entry)); /* Insert at the tail. */
943 TAILQ_INSERT_TAIL(&head, n1, entries);
945 n2 = malloc(sizeof(struct entry)); /* Insert after. */
946 TAILQ_INSERT_AFTER(&head, n1, n2, entries);
948 n3 = malloc(sizeof(struct entry)); /* Insert before. */
949 TAILQ_INSERT_BEFORE(n2, n3, entries);
951 TAILQ_REMOVE(&head, n2, entries); /* Deletion. */
953 /* Forward traversal. */
954 TAILQ_FOREACH(np, &head, entries)
956 /* Safe forward traversal. */
957 TAILQ_FOREACH_SAFE(np, &head, entries, np_temp) {
960 TAILQ_REMOVE(&head, np, entries);
963 /* Reverse traversal. */
964 TAILQ_FOREACH_REVERSE(np, &head, tailhead, entries)
966 /* TailQ Deletion. */
967 while (!TAILQ_EMPTY(&head)) {
968 n1 = TAILQ_FIRST(&head);
969 TAILQ_REMOVE(&head, n1, entries);
972 /* Faster TailQ Deletion. */
973 n1 = TAILQ_FIRST(&head);
975 n2 = TAILQ_NEXT(n1, entries);
984 functions first appeared in