xref: /illumos-gate/usr/src/man/man3head/queue.h.3head (revision 45ede40b2394db7967e59f19288fae9b62efd4aa)
1.\" Copyright (c) 1993
2.\"	The Regents of the University of California.  All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
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. Neither the name of the University nor the names of its contributors
13.\"    may be used to endorse or promote products derived from this software
14.\"    without specific prior written permission.
15.\"
16.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26.\" SUCH DAMAGE.
27.\"
28.\"	@(#)queue.3	8.2 (Berkeley) 1/24/94
29.\"
30.Dd August 6, 2018
31.Dt QUEUE.H 3HEAD
32.Os
33.Sh NAME
34.Nm SLIST_CLASS_ENTRY ,
35.Nm SLIST_CLASS_HEAD ,
36.Nm SLIST_CONCAT ,
37.Nm SLIST_EMPTY ,
38.Nm SLIST_ENTRY ,
39.Nm SLIST_FIRST ,
40.Nm SLIST_FOREACH ,
41.Nm SLIST_FOREACH_FROM ,
42.Nm SLIST_FOREACH_FROM_SAFE ,
43.Nm SLIST_FOREACH_SAFE ,
44.Nm SLIST_HEAD ,
45.Nm SLIST_HEAD_INITIALIZER ,
46.Nm SLIST_INIT ,
47.Nm SLIST_INSERT_AFTER ,
48.Nm SLIST_INSERT_HEAD ,
49.Nm SLIST_NEXT ,
50.Nm SLIST_REMOVE ,
51.Nm SLIST_REMOVE_AFTER ,
52.Nm SLIST_REMOVE_HEAD ,
53.Nm SLIST_SWAP ,
54.Nm STAILQ_CLASS_ENTRY ,
55.Nm STAILQ_CLASS_HEAD ,
56.Nm STAILQ_CONCAT ,
57.Nm STAILQ_EMPTY ,
58.Nm STAILQ_ENTRY ,
59.Nm STAILQ_FIRST ,
60.Nm STAILQ_FOREACH ,
61.Nm STAILQ_FOREACH_FROM ,
62.Nm STAILQ_FOREACH_FROM_SAFE ,
63.Nm STAILQ_FOREACH_SAFE ,
64.Nm STAILQ_HEAD ,
65.Nm STAILQ_HEAD_INITIALIZER ,
66.Nm STAILQ_INIT ,
67.Nm STAILQ_INSERT_AFTER ,
68.Nm STAILQ_INSERT_HEAD ,
69.Nm STAILQ_INSERT_TAIL ,
70.Nm STAILQ_LAST ,
71.Nm STAILQ_NEXT ,
72.Nm STAILQ_REMOVE ,
73.Nm STAILQ_REMOVE_AFTER ,
74.Nm STAILQ_REMOVE_HEAD ,
75.Nm STAILQ_SWAP ,
76.Nm LIST_CLASS_ENTRY ,
77.Nm LIST_CLASS_HEAD ,
78.Nm LIST_CONCAT ,
79.Nm LIST_EMPTY ,
80.Nm LIST_ENTRY ,
81.Nm LIST_FIRST ,
82.Nm LIST_FOREACH ,
83.Nm LIST_FOREACH_FROM ,
84.Nm LIST_FOREACH_FROM_SAFE ,
85.Nm LIST_FOREACH_SAFE ,
86.Nm LIST_HEAD ,
87.Nm LIST_HEAD_INITIALIZER ,
88.Nm LIST_INIT ,
89.Nm LIST_INSERT_AFTER ,
90.Nm LIST_INSERT_BEFORE ,
91.Nm LIST_INSERT_HEAD ,
92.Nm LIST_NEXT ,
93.Nm LIST_PREV ,
94.Nm LIST_REMOVE ,
95.Nm LIST_SWAP ,
96.Nm TAILQ_CLASS_ENTRY ,
97.Nm TAILQ_CLASS_HEAD ,
98.Nm TAILQ_CONCAT ,
99.Nm TAILQ_EMPTY ,
100.Nm TAILQ_ENTRY ,
101.Nm TAILQ_FIRST ,
102.Nm TAILQ_FOREACH ,
103.Nm TAILQ_FOREACH_FROM ,
104.Nm TAILQ_FOREACH_FROM_SAFE ,
105.Nm TAILQ_FOREACH_REVERSE ,
106.Nm TAILQ_FOREACH_REVERSE_FROM ,
107.Nm TAILQ_FOREACH_REVERSE_FROM_SAFE ,
108.Nm TAILQ_FOREACH_REVERSE_SAFE ,
109.Nm TAILQ_FOREACH_SAFE ,
110.Nm TAILQ_HEAD ,
111.Nm TAILQ_HEAD_INITIALIZER ,
112.Nm TAILQ_INIT ,
113.Nm TAILQ_INSERT_AFTER ,
114.Nm TAILQ_INSERT_BEFORE ,
115.Nm TAILQ_INSERT_HEAD ,
116.Nm TAILQ_INSERT_TAIL ,
117.Nm TAILQ_LAST ,
118.Nm TAILQ_NEXT ,
119.Nm TAILQ_PREV ,
120.Nm TAILQ_REMOVE ,
121.Nm TAILQ_SWAP
122.Nd implementations of singly-linked lists, singly-linked tail queues,
123lists and tail queues
124.Sh SYNOPSIS
125.In sys/queue.h
126.\"
127.Fn SLIST_CLASS_ENTRY "CLASSTYPE"
128.Fn SLIST_CLASS_HEAD "HEADNAME" "CLASSTYPE"
129.Fn SLIST_CONCAT "SLIST_HEAD *head1" "SLIST_HEAD *head2" "TYPE" "SLIST_ENTRY NAME"
130.Fn SLIST_EMPTY "SLIST_HEAD *head"
131.Fn SLIST_ENTRY "TYPE"
132.Fn SLIST_FIRST "SLIST_HEAD *head"
133.Fn SLIST_FOREACH "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME"
134.Fn SLIST_FOREACH_FROM "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME"
135.Fn SLIST_FOREACH_FROM_SAFE "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME" "TYPE *temp_var"
136.Fn SLIST_FOREACH_SAFE "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME" "TYPE *temp_var"
137.Fn SLIST_HEAD "HEADNAME" "TYPE"
138.Fn SLIST_HEAD_INITIALIZER "SLIST_HEAD head"
139.Fn SLIST_INIT "SLIST_HEAD *head"
140.Fn SLIST_INSERT_AFTER "TYPE *listelm" "TYPE *elm" "SLIST_ENTRY NAME"
141.Fn SLIST_INSERT_HEAD "SLIST_HEAD *head" "TYPE *elm" "SLIST_ENTRY NAME"
142.Fn SLIST_NEXT "TYPE *elm" "SLIST_ENTRY NAME"
143.Fn SLIST_REMOVE "SLIST_HEAD *head" "TYPE *elm" "TYPE" "SLIST_ENTRY NAME"
144.Fn SLIST_REMOVE_AFTER "TYPE *elm" "SLIST_ENTRY NAME"
145.Fn SLIST_REMOVE_HEAD "SLIST_HEAD *head" "SLIST_ENTRY NAME"
146.Fn SLIST_SWAP "SLIST_HEAD *head1" "SLIST_HEAD *head2" "TYPE"
147.\"
148.Fn STAILQ_CLASS_ENTRY "CLASSTYPE"
149.Fn STAILQ_CLASS_HEAD "HEADNAME" "CLASSTYPE"
150.Fn STAILQ_CONCAT "STAILQ_HEAD *head1" "STAILQ_HEAD *head2"
151.Fn STAILQ_EMPTY "STAILQ_HEAD *head"
152.Fn STAILQ_ENTRY "TYPE"
153.Fn STAILQ_FIRST "STAILQ_HEAD *head"
154.Fn STAILQ_FOREACH "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME"
155.Fn STAILQ_FOREACH_FROM "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME"
156.Fn STAILQ_FOREACH_FROM_SAFE "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" "TYPE *temp_var"
157.Fn STAILQ_FOREACH_SAFE "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" "TYPE *temp_var"
158.Fn STAILQ_HEAD "HEADNAME" "TYPE"
159.Fn STAILQ_HEAD_INITIALIZER "STAILQ_HEAD head"
160.Fn STAILQ_INIT "STAILQ_HEAD *head"
161.Fn STAILQ_INSERT_AFTER "STAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "STAILQ_ENTRY NAME"
162.Fn STAILQ_INSERT_HEAD "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
163.Fn STAILQ_INSERT_TAIL "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
164.Fn STAILQ_LAST "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
165.Fn STAILQ_NEXT "TYPE *elm" "STAILQ_ENTRY NAME"
166.Fn STAILQ_REMOVE "STAILQ_HEAD *head" "TYPE *elm" "TYPE" "STAILQ_ENTRY NAME"
167.Fn STAILQ_REMOVE_AFTER "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
168.Fn STAILQ_REMOVE_HEAD "STAILQ_HEAD *head" "STAILQ_ENTRY NAME"
169.Fn STAILQ_SWAP "STAILQ_HEAD *head1" "STAILQ_HEAD *head2" "TYPE"
170.\"
171.Fn LIST_CLASS_ENTRY "CLASSTYPE"
172.Fn LIST_CLASS_HEAD "HEADNAME" "CLASSTYPE"
173.Fn LIST_CONCAT "LIST_HEAD *head1" "LIST_HEAD *head2" "TYPE" "LIST_ENTRY NAME"
174.Fn LIST_EMPTY "LIST_HEAD *head"
175.Fn LIST_ENTRY "TYPE"
176.Fn LIST_FIRST "LIST_HEAD *head"
177.Fn LIST_FOREACH "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME"
178.Fn LIST_FOREACH_FROM "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME"
179.Fn LIST_FOREACH_FROM_SAFE "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME" "TYPE *temp_var"
180.Fn LIST_FOREACH_SAFE "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME" "TYPE *temp_var"
181.Fn LIST_HEAD "HEADNAME" "TYPE"
182.Fn LIST_HEAD_INITIALIZER "LIST_HEAD head"
183.Fn LIST_INIT "LIST_HEAD *head"
184.Fn LIST_INSERT_AFTER "TYPE *listelm" "TYPE *elm" "LIST_ENTRY NAME"
185.Fn LIST_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "LIST_ENTRY NAME"
186.Fn LIST_INSERT_HEAD "LIST_HEAD *head" "TYPE *elm" "LIST_ENTRY NAME"
187.Fn LIST_NEXT "TYPE *elm" "LIST_ENTRY NAME"
188.Fn LIST_PREV "TYPE *elm" "LIST_HEAD *head" "TYPE" "LIST_ENTRY NAME"
189.Fn LIST_REMOVE "TYPE *elm" "LIST_ENTRY NAME"
190.Fn LIST_SWAP "LIST_HEAD *head1" "LIST_HEAD *head2" "TYPE" "LIST_ENTRY NAME"
191.\"
192.Fn TAILQ_CLASS_ENTRY "CLASSTYPE"
193.Fn TAILQ_CLASS_HEAD "HEADNAME" "CLASSTYPE"
194.Fn TAILQ_CONCAT "TAILQ_HEAD *head1" "TAILQ_HEAD *head2" "TAILQ_ENTRY NAME"
195.Fn TAILQ_EMPTY "TAILQ_HEAD *head"
196.Fn TAILQ_ENTRY "TYPE"
197.Fn TAILQ_FIRST "TAILQ_HEAD *head"
198.Fn TAILQ_FOREACH "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME"
199.Fn TAILQ_FOREACH_FROM "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME"
200.Fn TAILQ_FOREACH_FROM_SAFE "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME" "TYPE *temp_var"
201.Fn TAILQ_FOREACH_REVERSE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME"
202.Fn TAILQ_FOREACH_REVERSE_FROM "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME"
203.Fn TAILQ_FOREACH_REVERSE_FROM_SAFE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME" "TYPE *temp_var"
204.Fn TAILQ_FOREACH_REVERSE_SAFE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME" "TYPE *temp_var"
205.Fn TAILQ_FOREACH_SAFE "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME" "TYPE *temp_var"
206.Fn TAILQ_HEAD "HEADNAME" "TYPE"
207.Fn TAILQ_HEAD_INITIALIZER "TAILQ_HEAD head"
208.Fn TAILQ_INIT "TAILQ_HEAD *head"
209.Fn TAILQ_INSERT_AFTER "TAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME"
210.Fn TAILQ_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME"
211.Fn TAILQ_INSERT_HEAD "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
212.Fn TAILQ_INSERT_TAIL "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
213.Fn TAILQ_LAST "TAILQ_HEAD *head" "HEADNAME"
214.Fn TAILQ_NEXT "TYPE *elm" "TAILQ_ENTRY NAME"
215.Fn TAILQ_PREV "TYPE *elm" "HEADNAME" "TAILQ_ENTRY NAME"
216.Fn TAILQ_REMOVE "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
217.Fn TAILQ_SWAP "TAILQ_HEAD *head1" "TAILQ_HEAD *head2" "TYPE" "TAILQ_ENTRY NAME"
218.\"
219.Sh DESCRIPTION
220These macros define and operate on four types of data structures which
221can be used in both C and C++ source code:
222.Bl -enum -compact -offset indent
223.It
224Lists
225.It
226Singly-linked lists
227.It
228Singly-linked tail queues
229.It
230Tail queues
231.El
232All four structures support the following functionality:
233.Bl -enum -compact -offset indent
234.It
235Insertion of a new entry at the head of the list.
236.It
237Insertion of a new entry after any element in the list.
238.It
239O(1) removal of an entry from the head of the list.
240.It
241Forward traversal through the list.
242.It
243Swapping the contents of two lists.
244.El
245.Pp
246Singly-linked lists are the simplest of the four data structures
247and support only the above functionality.
248Singly-linked lists are ideal for applications with large datasets
249and few or no removals,
250or for implementing a LIFO queue.
251Singly-linked lists add the following functionality:
252.Bl -enum -compact -offset indent
253.It
254O(n) removal of any entry in the list.
255.It
256O(n) concatenation of two lists.
257.El
258.Pp
259Singly-linked tail queues add the following functionality:
260.Bl -enum -compact -offset indent
261.It
262Entries can be added at the end of a list.
263.It
264O(n) removal of any entry in the list.
265.It
266They may be concatenated.
267.El
268However:
269.Bl -enum -compact -offset indent
270.It
271All list insertions must specify the head of the list.
272.It
273Each head entry requires two pointers rather than one.
274.It
275Code size is about 15% greater and operations run about 20% slower
276than singly-linked lists.
277.El
278.Pp
279Singly-linked tail queues are ideal for applications with large datasets and
280few or no removals,
281or for implementing a FIFO queue.
282.Pp
283All doubly linked types of data structures (lists and tail queues)
284additionally allow:
285.Bl -enum -compact -offset indent
286.It
287Insertion of a new entry before any element in the list.
288.It
289O(1) removal of any entry in the list.
290.El
291However:
292.Bl -enum -compact -offset indent
293.It
294Each element requires two pointers rather than one.
295.It
296Code size and execution time of operations (except for removal) is about
297twice that of the singly-linked data-structures.
298.El
299.Pp
300Linked lists are the simplest of the doubly linked data structures.
301They add the following functionality over the above:
302.Bl -enum -compact -offset indent
303.It
304O(n) concatenation of two lists.
305.It
306They may be traversed backwards.
307.El
308However:
309.Bl -enum -compact -offset indent
310.It
311To traverse backwards, an entry to begin the traversal and the list in
312which it is contained must be specified.
313.El
314.Pp
315Tail queues add the following functionality:
316.Bl -enum -compact -offset indent
317.It
318Entries can be added at the end of a list.
319.It
320They may be traversed backwards, from tail to head.
321.It
322They may be concatenated.
323.El
324However:
325.Bl -enum -compact -offset indent
326.It
327All list insertions and removals must specify the head of the list.
328.It
329Each head entry requires two pointers rather than one.
330.It
331Code size is about 15% greater and operations run about 20% slower
332than singly-linked lists.
333.El
334.Pp
335In the macro definitions,
336.Fa TYPE
337is the name of a user defined structure.
338The structure must contain a field called
339.Fa NAME
340which is of type
341.Li SLIST_ENTRY ,
342.Li STAILQ_ENTRY ,
343.Li LIST_ENTRY ,
344or
345.Li TAILQ_ENTRY .
346In the macro definitions,
347.Fa CLASSTYPE
348is the name of a user defined class.
349The class must contain a field called
350.Fa NAME
351which is of type
352.Li SLIST_CLASS_ENTRY ,
353.Li STAILQ_CLASS_ENTRY ,
354.Li LIST_CLASS_ENTRY ,
355or
356.Li TAILQ_CLASS_ENTRY .
357The argument
358.Fa HEADNAME
359is the name of a user defined structure that must be declared
360using the macros
361.Li SLIST_HEAD ,
362.Li SLIST_CLASS_HEAD ,
363.Li STAILQ_HEAD ,
364.Li STAILQ_CLASS_HEAD ,
365.Li LIST_HEAD ,
366.Li LIST_CLASS_HEAD ,
367.Li TAILQ_HEAD ,
368or
369.Li TAILQ_CLASS_HEAD .
370See the examples below for further explanation of how these
371macros are used.
372.Sh SINGLY-LINKED LISTS
373A singly-linked list is headed by a structure defined by the
374.Nm SLIST_HEAD
375macro.
376This structure contains a single pointer to the first element
377on the list.
378The elements are singly linked for minimum space and pointer manipulation
379overhead at the expense of O(n) removal for arbitrary elements.
380New elements can be added to the list after an existing element or
381at the head of the list.
382An
383.Fa SLIST_HEAD
384structure is declared as follows:
385.Bd -literal -offset indent
386SLIST_HEAD(HEADNAME, TYPE) head;
387.Ed
388.Pp
389where
390.Fa HEADNAME
391is the name of the structure to be defined, and
392.Fa TYPE
393is the type of the elements to be linked into the list.
394A pointer to the head of the list can later be declared as:
395.Bd -literal -offset indent
396struct HEADNAME *headp;
397.Ed
398.Pp
399(The names
400.Li head
401and
402.Li headp
403are user selectable.)
404.Pp
405The macro
406.Nm SLIST_HEAD_INITIALIZER
407evaluates to an initializer for the list
408.Fa head .
409.Pp
410The macro
411.Nm SLIST_CONCAT
412concatenates the list headed by
413.Fa head2
414onto the end of the one headed by
415.Fa head1
416removing all entries from the former.
417Use of this macro should be avoided as it traverses the entirety of the
418.Fa head1
419list.
420A singly-linked tail queue should be used if this macro is needed in
421high-usage code paths or to operate on long lists.
422.Pp
423The macro
424.Nm SLIST_EMPTY
425evaluates to true if there are no elements in the list.
426.Pp
427The macro
428.Nm SLIST_ENTRY
429declares a structure that connects the elements in
430the list.
431.Pp
432The macro
433.Nm SLIST_FIRST
434returns the first element in the list or NULL if the list is empty.
435.Pp
436The macro
437.Nm SLIST_FOREACH
438traverses the list referenced by
439.Fa head
440in the forward direction, assigning each element in
441turn to
442.Fa var .
443.Pp
444The macro
445.Nm SLIST_FOREACH_FROM
446behaves identically to
447.Nm SLIST_FOREACH
448when
449.Fa var
450is NULL, else it treats
451.Fa var
452as a previously found SLIST element and begins the loop at
453.Fa var
454instead of the first element in the SLIST referenced by
455.Fa head .
456.Pp
457The macro
458.Nm SLIST_FOREACH_SAFE
459traverses the list referenced by
460.Fa head
461in the forward direction, assigning each element in
462turn to
463.Fa var .
464However, unlike
465.Fn SLIST_FOREACH
466here it is permitted to both remove
467.Fa var
468as well as free it from within the loop safely without interfering with the
469traversal.
470.Pp
471The macro
472.Nm SLIST_FOREACH_FROM_SAFE
473behaves identically to
474.Nm SLIST_FOREACH_SAFE
475when
476.Fa var
477is NULL, else it treats
478.Fa var
479as a previously found SLIST element and begins the loop at
480.Fa var
481instead of the first element in the SLIST referenced by
482.Fa head .
483.Pp
484The macro
485.Nm SLIST_INIT
486initializes the list referenced by
487.Fa head .
488.Pp
489The macro
490.Nm SLIST_INSERT_HEAD
491inserts the new element
492.Fa elm
493at the head of the list.
494.Pp
495The macro
496.Nm SLIST_INSERT_AFTER
497inserts the new element
498.Fa elm
499after the element
500.Fa listelm .
501.Pp
502The macro
503.Nm SLIST_NEXT
504returns the next element in the list.
505.Pp
506The macro
507.Nm SLIST_REMOVE_AFTER
508removes the element after
509.Fa elm
510from the list.
511Unlike
512.Fa SLIST_REMOVE ,
513this macro does not traverse the entire list.
514.Pp
515The macro
516.Nm SLIST_REMOVE_HEAD
517removes the element
518.Fa elm
519from the head of the list.
520For optimum efficiency,
521elements being removed from the head of the list should explicitly use
522this macro instead of the generic
523.Fa SLIST_REMOVE
524macro.
525.Pp
526The macro
527.Nm SLIST_REMOVE
528removes the element
529.Fa elm
530from the list.
531Use of this macro should be avoided as it traverses the entire list.
532A doubly-linked list should be used if this macro is needed in
533high-usage code paths or to operate on long lists.
534.Pp
535The macro
536.Nm SLIST_SWAP
537swaps the contents of
538.Fa head1
539and
540.Fa head2 .
541.Sh SINGLY-LINKED TAIL QUEUES
542A singly-linked tail queue is headed by a structure defined by the
543.Nm STAILQ_HEAD
544macro.
545This structure contains a pair of pointers,
546one to the first element in the tail queue and the other to
547the last element in the tail queue.
548The elements are singly linked for minimum space and pointer
549manipulation overhead at the expense of O(n) removal for arbitrary
550elements.
551New elements can be added to the tail queue after an existing element,
552at the head of the tail queue, or at the end of the tail queue.
553A
554.Fa STAILQ_HEAD
555structure is declared as follows:
556.Bd -literal -offset indent
557STAILQ_HEAD(HEADNAME, TYPE) head;
558.Ed
559.Pp
560where
561.Li HEADNAME
562is the name of the structure to be defined, and
563.Li TYPE
564is the type of the elements to be linked into the tail queue.
565A pointer to the head of the tail queue can later be declared as:
566.Bd -literal -offset indent
567struct HEADNAME *headp;
568.Ed
569.Pp
570(The names
571.Li head
572and
573.Li headp
574are user selectable.)
575.Pp
576The macro
577.Nm STAILQ_HEAD_INITIALIZER
578evaluates to an initializer for the tail queue
579.Fa head .
580.Pp
581The macro
582.Nm STAILQ_CONCAT
583concatenates the tail queue headed by
584.Fa head2
585onto the end of the one headed by
586.Fa head1
587removing all entries from the former.
588.Pp
589The macro
590.Nm STAILQ_EMPTY
591evaluates to true if there are no items on the tail queue.
592.Pp
593The macro
594.Nm STAILQ_ENTRY
595declares a structure that connects the elements in
596the tail queue.
597.Pp
598The macro
599.Nm STAILQ_FIRST
600returns the first item on the tail queue or NULL if the tail queue
601is empty.
602.Pp
603The macro
604.Nm STAILQ_FOREACH
605traverses the tail queue referenced by
606.Fa head
607in the forward direction, assigning each element
608in turn to
609.Fa var .
610.Pp
611The macro
612.Nm STAILQ_FOREACH_FROM
613behaves identically to
614.Nm STAILQ_FOREACH
615when
616.Fa var
617is NULL, else it treats
618.Fa var
619as a previously found STAILQ element and begins the loop at
620.Fa var
621instead of the first element in the STAILQ referenced by
622.Fa head .
623.Pp
624The macro
625.Nm STAILQ_FOREACH_SAFE
626traverses the tail queue referenced by
627.Fa head
628in the forward direction, assigning each element
629in turn to
630.Fa var .
631However, unlike
632.Fn STAILQ_FOREACH
633here it is permitted to both remove
634.Fa var
635as well as free it from within the loop safely without interfering with the
636traversal.
637.Pp
638The macro
639.Nm STAILQ_FOREACH_FROM_SAFE
640behaves identically to
641.Nm STAILQ_FOREACH_SAFE
642when
643.Fa var
644is NULL, else it treats
645.Fa var
646as a previously found STAILQ element and begins the loop at
647.Fa var
648instead of the first element in the STAILQ referenced by
649.Fa head .
650.Pp
651The macro
652.Nm STAILQ_INIT
653initializes the tail queue referenced by
654.Fa head .
655.Pp
656The macro
657.Nm STAILQ_INSERT_HEAD
658inserts the new element
659.Fa elm
660at the head of the tail queue.
661.Pp
662The macro
663.Nm STAILQ_INSERT_TAIL
664inserts the new element
665.Fa elm
666at the end of the tail queue.
667.Pp
668The macro
669.Nm STAILQ_INSERT_AFTER
670inserts the new element
671.Fa elm
672after the element
673.Fa listelm .
674.Pp
675The macro
676.Nm STAILQ_LAST
677returns the last item on the tail queue.
678If the tail queue is empty the return value is
679.Dv NULL .
680.Pp
681The macro
682.Nm STAILQ_NEXT
683returns the next item on the tail queue, or NULL this item is the last.
684.Pp
685The macro
686.Nm STAILQ_REMOVE_AFTER
687removes the element after
688.Fa elm
689from the tail queue.
690Unlike
691.Fa STAILQ_REMOVE ,
692this macro does not traverse the entire tail queue.
693.Pp
694The macro
695.Nm STAILQ_REMOVE_HEAD
696removes the element at the head of the tail queue.
697For optimum efficiency,
698elements being removed from the head of the tail queue should
699use this macro explicitly rather than the generic
700.Fa STAILQ_REMOVE
701macro.
702.Pp
703The macro
704.Nm STAILQ_REMOVE
705removes the element
706.Fa elm
707from the tail queue.
708Use of this macro should be avoided as it traverses the entire list.
709A doubly-linked tail queue should be used if this macro is needed in
710high-usage code paths or to operate on long tail queues.
711.Pp
712The macro
713.Nm STAILQ_SWAP
714swaps the contents of
715.Fa head1
716and
717.Fa head2 .
718.Sh LISTS
719A list is headed by a structure defined by the
720.Nm LIST_HEAD
721macro.
722This structure contains a single pointer to the first element
723on the list.
724The elements are doubly linked so that an arbitrary element can be
725removed without traversing the list.
726New elements can be added to the list after an existing element,
727before an existing element, or at the head of the list.
728A
729.Fa LIST_HEAD
730structure is declared as follows:
731.Bd -literal -offset indent
732LIST_HEAD(HEADNAME, TYPE) head;
733.Ed
734.Pp
735where
736.Fa HEADNAME
737is the name of the structure to be defined, and
738.Fa TYPE
739is the type of the elements to be linked into the list.
740A pointer to the head of the list can later be declared as:
741.Bd -literal -offset indent
742struct HEADNAME *headp;
743.Ed
744.Pp
745(The names
746.Li head
747and
748.Li headp
749are user selectable.)
750.Pp
751The macro
752.Nm LIST_HEAD_INITIALIZER
753evaluates to an initializer for the list
754.Fa head .
755.Pp
756The macro
757.Nm LIST_CONCAT
758concatenates the list headed by
759.Fa head2
760onto the end of the one headed by
761.Fa head1
762removing all entries from the former.
763Use of this macro should be avoided as it traverses the entirety of the
764.Fa head1
765list.
766A tail queue should be used if this macro is needed in
767high-usage code paths or to operate on long lists.
768.Pp
769The macro
770.Nm LIST_EMPTY
771evaluates to true if there are no elements in the list.
772.Pp
773The macro
774.Nm LIST_ENTRY
775declares a structure that connects the elements in
776the list.
777.Pp
778The macro
779.Nm LIST_FIRST
780returns the first element in the list or NULL if the list
781is empty.
782.Pp
783The macro
784.Nm LIST_FOREACH
785traverses the list referenced by
786.Fa head
787in the forward direction, assigning each element in turn to
788.Fa var .
789.Pp
790The macro
791.Nm LIST_FOREACH_FROM
792behaves identically to
793.Nm LIST_FOREACH
794when
795.Fa var
796is NULL, else it treats
797.Fa var
798as a previously found LIST element and begins the loop at
799.Fa var
800instead of the first element in the LIST referenced by
801.Fa head .
802.Pp
803The macro
804.Nm LIST_FOREACH_SAFE
805traverses the list referenced by
806.Fa head
807in the forward direction, assigning each element in turn to
808.Fa var .
809However, unlike
810.Fn LIST_FOREACH
811here it is permitted to both remove
812.Fa var
813as well as free it from within the loop safely without interfering with the
814traversal.
815.Pp
816The macro
817.Nm LIST_FOREACH_FROM_SAFE
818behaves identically to
819.Nm LIST_FOREACH_SAFE
820when
821.Fa var
822is NULL, else it treats
823.Fa var
824as a previously found LIST element and begins the loop at
825.Fa var
826instead of the first element in the LIST referenced by
827.Fa head .
828.Pp
829The macro
830.Nm LIST_INIT
831initializes the list referenced by
832.Fa head .
833.Pp
834The macro
835.Nm LIST_INSERT_HEAD
836inserts the new element
837.Fa elm
838at the head of the list.
839.Pp
840The macro
841.Nm LIST_INSERT_AFTER
842inserts the new element
843.Fa elm
844after the element
845.Fa listelm .
846.Pp
847The macro
848.Nm LIST_INSERT_BEFORE
849inserts the new element
850.Fa elm
851before the element
852.Fa listelm .
853.Pp
854The macro
855.Nm LIST_NEXT
856returns the next element in the list, or NULL if this is the last.
857.Pp
858The macro
859.Nm LIST_PREV
860returns the previous element in the list, or NULL if this is the first.
861List
862.Fa head
863must contain element
864.Fa elm .
865.Pp
866The macro
867.Nm LIST_REMOVE
868removes the element
869.Fa elm
870from the list.
871.Pp
872The macro
873.Nm LIST_SWAP
874swaps the contents of
875.Fa head1
876and
877.Fa head2 .
878.Sh TAIL QUEUES
879A tail queue is headed by a structure defined by the
880.Nm TAILQ_HEAD
881macro.
882This structure contains a pair of pointers,
883one to the first element in the tail queue and the other to
884the last element in the tail queue.
885The elements are doubly linked so that an arbitrary element can be
886removed without traversing the tail queue.
887New elements can be added to the tail queue after an existing element,
888before an existing element, at the head of the tail queue,
889or at the end of the tail queue.
890A
891.Fa TAILQ_HEAD
892structure is declared as follows:
893.Bd -literal -offset indent
894TAILQ_HEAD(HEADNAME, TYPE) head;
895.Ed
896.Pp
897where
898.Li HEADNAME
899is the name of the structure to be defined, and
900.Li TYPE
901is the type of the elements to be linked into the tail queue.
902A pointer to the head of the tail queue can later be declared as:
903.Bd -literal -offset indent
904struct HEADNAME *headp;
905.Ed
906.Pp
907(The names
908.Li head
909and
910.Li headp
911are user selectable.)
912.Pp
913The macro
914.Nm TAILQ_HEAD_INITIALIZER
915evaluates to an initializer for the tail queue
916.Fa head .
917.Pp
918The macro
919.Nm TAILQ_CONCAT
920concatenates the tail queue headed by
921.Fa head2
922onto the end of the one headed by
923.Fa head1
924removing all entries from the former.
925.Pp
926The macro
927.Nm TAILQ_EMPTY
928evaluates to true if there are no items on the tail queue.
929.Pp
930The macro
931.Nm TAILQ_ENTRY
932declares a structure that connects the elements in
933the tail queue.
934.Pp
935The macro
936.Nm TAILQ_FIRST
937returns the first item on the tail queue or NULL if the tail queue
938is empty.
939.Pp
940The macro
941.Nm TAILQ_FOREACH
942traverses the tail queue referenced by
943.Fa head
944in the forward direction, assigning each element in turn to
945.Fa var .
946.Fa var
947is set to
948.Dv NULL
949if the loop completes normally, or if there were no elements.
950.Pp
951The macro
952.Nm TAILQ_FOREACH_FROM
953behaves identically to
954.Nm TAILQ_FOREACH
955when
956.Fa var
957is NULL, else it treats
958.Fa var
959as a previously found TAILQ element and begins the loop at
960.Fa var
961instead of the first element in the TAILQ referenced by
962.Fa head .
963.Pp
964The macro
965.Nm TAILQ_FOREACH_REVERSE
966traverses the tail queue referenced by
967.Fa head
968in the reverse direction, assigning each element in turn to
969.Fa var .
970.Pp
971The macro
972.Nm TAILQ_FOREACH_REVERSE_FROM
973behaves identically to
974.Nm TAILQ_FOREACH_REVERSE
975when
976.Fa var
977is NULL, else it treats
978.Fa var
979as a previously found TAILQ element and begins the reverse loop at
980.Fa var
981instead of the last element in the TAILQ referenced by
982.Fa head .
983.Pp
984The macros
985.Nm TAILQ_FOREACH_SAFE
986and
987.Nm TAILQ_FOREACH_REVERSE_SAFE
988traverse the list referenced by
989.Fa head
990in the forward or reverse direction respectively,
991assigning each element in turn to
992.Fa var .
993However, unlike their unsafe counterparts,
994.Nm TAILQ_FOREACH
995and
996.Nm TAILQ_FOREACH_REVERSE
997permit to both remove
998.Fa var
999as well as free it from within the loop safely without interfering with the
1000traversal.
1001.Pp
1002The macro
1003.Nm TAILQ_FOREACH_FROM_SAFE
1004behaves identically to
1005.Nm TAILQ_FOREACH_SAFE
1006when
1007.Fa var
1008is NULL, else it treats
1009.Fa var
1010as a previously found TAILQ element and begins the loop at
1011.Fa var
1012instead of the first element in the TAILQ referenced by
1013.Fa head .
1014.Pp
1015The macro
1016.Nm TAILQ_FOREACH_REVERSE_FROM_SAFE
1017behaves identically to
1018.Nm TAILQ_FOREACH_REVERSE_SAFE
1019when
1020.Fa var
1021is NULL, else it treats
1022.Fa var
1023as a previously found TAILQ element and begins the reverse loop at
1024.Fa var
1025instead of the last element in the TAILQ referenced by
1026.Fa head .
1027.Pp
1028The macro
1029.Nm TAILQ_INIT
1030initializes the tail queue referenced by
1031.Fa head .
1032.Pp
1033The macro
1034.Nm TAILQ_INSERT_HEAD
1035inserts the new element
1036.Fa elm
1037at the head of the tail queue.
1038.Pp
1039The macro
1040.Nm TAILQ_INSERT_TAIL
1041inserts the new element
1042.Fa elm
1043at the end of the tail queue.
1044.Pp
1045The macro
1046.Nm TAILQ_INSERT_AFTER
1047inserts the new element
1048.Fa elm
1049after the element
1050.Fa listelm .
1051.Pp
1052The macro
1053.Nm TAILQ_INSERT_BEFORE
1054inserts the new element
1055.Fa elm
1056before the element
1057.Fa listelm .
1058.Pp
1059The macro
1060.Nm TAILQ_LAST
1061returns the last item on the tail queue.
1062If the tail queue is empty the return value is
1063.Dv NULL .
1064.Pp
1065The macro
1066.Nm TAILQ_NEXT
1067returns the next item on the tail queue, or NULL if this item is the last.
1068.Pp
1069The macro
1070.Nm TAILQ_PREV
1071returns the previous item on the tail queue, or NULL if this item
1072is the first.
1073.Pp
1074The macro
1075.Nm TAILQ_REMOVE
1076removes the element
1077.Fa elm
1078from the tail queue.
1079.Pp
1080The macro
1081.Nm TAILQ_SWAP
1082swaps the contents of
1083.Fa head1
1084and
1085.Fa head2 .
1086.Sh EXAMPLES
1087.Ss SINGLY-LINKED LIST EXAMPLE
1088.Bd -literal
1089SLIST_HEAD(slisthead, entry) head =
1090    SLIST_HEAD_INITIALIZER(head);
1091struct slisthead *headp;		/* Singly-linked List head. */
1092struct entry {
1093	...
1094	SLIST_ENTRY(entry) entries;	/* Singly-linked List. */
1095	...
1096} *n1, *n2, *n3, *np;
1097
1098SLIST_INIT(&head);			/* Initialize the list. */
1099
1100n1 = malloc(sizeof(struct entry));	/* Insert at the head. */
1101SLIST_INSERT_HEAD(&head, n1, entries);
1102
1103n2 = malloc(sizeof(struct entry));	/* Insert after. */
1104SLIST_INSERT_AFTER(n1, n2, entries);
1105
1106SLIST_REMOVE(&head, n2, entry, entries);/* Deletion. */
1107free(n2);
1108
1109n3 = SLIST_FIRST(&head);
1110SLIST_REMOVE_HEAD(&head, entries);	/* Deletion from the head. */
1111free(n3);
1112					/* Forward traversal. */
1113SLIST_FOREACH(np, &head, entries)
1114	np-> ...
1115					/* Safe forward traversal. */
1116SLIST_FOREACH_SAFE(np, &head, entries, np_temp) {
1117	np->do_stuff();
1118	...
1119	SLIST_REMOVE(&head, np, entry, entries);
1120	free(np);
1121}
1122
1123while (!SLIST_EMPTY(&head)) {		/* List Deletion. */
1124	n1 = SLIST_FIRST(&head);
1125	SLIST_REMOVE_HEAD(&head, entries);
1126	free(n1);
1127}
1128.Ed
1129.Ss SINGLY-LINKED TAIL QUEUE EXAMPLE
1130.Bd -literal
1131STAILQ_HEAD(stailhead, entry) head =
1132    STAILQ_HEAD_INITIALIZER(head);
1133struct stailhead *headp;		/* Singly-linked tail queue head. */
1134struct entry {
1135	...
1136	STAILQ_ENTRY(entry) entries;	/* Tail queue. */
1137	...
1138} *n1, *n2, *n3, *np;
1139
1140STAILQ_INIT(&head);			/* Initialize the queue. */
1141
1142n1 = malloc(sizeof(struct entry));	/* Insert at the head. */
1143STAILQ_INSERT_HEAD(&head, n1, entries);
1144
1145n1 = malloc(sizeof(struct entry));	/* Insert at the tail. */
1146STAILQ_INSERT_TAIL(&head, n1, entries);
1147
1148n2 = malloc(sizeof(struct entry));	/* Insert after. */
1149STAILQ_INSERT_AFTER(&head, n1, n2, entries);
1150					/* Deletion. */
1151STAILQ_REMOVE(&head, n2, entry, entries);
1152free(n2);
1153					/* Deletion from the head. */
1154n3 = STAILQ_FIRST(&head);
1155STAILQ_REMOVE_HEAD(&head, entries);
1156free(n3);
1157					/* Forward traversal. */
1158STAILQ_FOREACH(np, &head, entries)
1159	np-> ...
1160					/* Safe forward traversal. */
1161STAILQ_FOREACH_SAFE(np, &head, entries, np_temp) {
1162	np->do_stuff();
1163	...
1164	STAILQ_REMOVE(&head, np, entry, entries);
1165	free(np);
1166}
1167					/* TailQ Deletion. */
1168while (!STAILQ_EMPTY(&head)) {
1169	n1 = STAILQ_FIRST(&head);
1170	STAILQ_REMOVE_HEAD(&head, entries);
1171	free(n1);
1172}
1173					/* Faster TailQ Deletion. */
1174n1 = STAILQ_FIRST(&head);
1175while (n1 != NULL) {
1176	n2 = STAILQ_NEXT(n1, entries);
1177	free(n1);
1178	n1 = n2;
1179}
1180STAILQ_INIT(&head);
1181.Ed
1182.Ss LIST EXAMPLE
1183.Bd -literal
1184LIST_HEAD(listhead, entry) head =
1185    LIST_HEAD_INITIALIZER(head);
1186struct listhead *headp;			/* List head. */
1187struct entry {
1188	...
1189	LIST_ENTRY(entry) entries;	/* List. */
1190	...
1191} *n1, *n2, *n3, *np, *np_temp;
1192
1193LIST_INIT(&head);			/* Initialize the list. */
1194
1195n1 = malloc(sizeof(struct entry));	/* Insert at the head. */
1196LIST_INSERT_HEAD(&head, n1, entries);
1197
1198n2 = malloc(sizeof(struct entry));	/* Insert after. */
1199LIST_INSERT_AFTER(n1, n2, entries);
1200
1201n3 = malloc(sizeof(struct entry));	/* Insert before. */
1202LIST_INSERT_BEFORE(n2, n3, entries);
1203
1204LIST_REMOVE(n2, entries);		/* Deletion. */
1205free(n2);
1206					/* Forward traversal. */
1207LIST_FOREACH(np, &head, entries)
1208	np-> ...
1209
1210					/* Safe forward traversal. */
1211LIST_FOREACH_SAFE(np, &head, entries, np_temp) {
1212	np->do_stuff();
1213	...
1214	LIST_REMOVE(np, entries);
1215	free(np);
1216}
1217
1218while (!LIST_EMPTY(&head)) {		/* List Deletion. */
1219	n1 = LIST_FIRST(&head);
1220	LIST_REMOVE(n1, entries);
1221	free(n1);
1222}
1223
1224n1 = LIST_FIRST(&head);			/* Faster List Deletion. */
1225while (n1 != NULL) {
1226	n2 = LIST_NEXT(n1, entries);
1227	free(n1);
1228	n1 = n2;
1229}
1230LIST_INIT(&head);
1231.Ed
1232.Ss TAIL QUEUE EXAMPLE
1233.Bd -literal
1234TAILQ_HEAD(tailhead, entry) head =
1235    TAILQ_HEAD_INITIALIZER(head);
1236struct tailhead *headp;			/* Tail queue head. */
1237struct entry {
1238	...
1239	TAILQ_ENTRY(entry) entries;	/* Tail queue. */
1240	...
1241} *n1, *n2, *n3, *np;
1242
1243TAILQ_INIT(&head);			/* Initialize the queue. */
1244
1245n1 = malloc(sizeof(struct entry));	/* Insert at the head. */
1246TAILQ_INSERT_HEAD(&head, n1, entries);
1247
1248n1 = malloc(sizeof(struct entry));	/* Insert at the tail. */
1249TAILQ_INSERT_TAIL(&head, n1, entries);
1250
1251n2 = malloc(sizeof(struct entry));	/* Insert after. */
1252TAILQ_INSERT_AFTER(&head, n1, n2, entries);
1253
1254n3 = malloc(sizeof(struct entry));	/* Insert before. */
1255TAILQ_INSERT_BEFORE(n2, n3, entries);
1256
1257TAILQ_REMOVE(&head, n2, entries);	/* Deletion. */
1258free(n2);
1259					/* Forward traversal. */
1260TAILQ_FOREACH(np, &head, entries)
1261	np-> ...
1262					/* Safe forward traversal. */
1263TAILQ_FOREACH_SAFE(np, &head, entries, np_temp) {
1264	np->do_stuff();
1265	...
1266	TAILQ_REMOVE(&head, np, entries);
1267	free(np);
1268}
1269					/* Reverse traversal. */
1270TAILQ_FOREACH_REVERSE(np, &head, tailhead, entries)
1271	np-> ...
1272					/* TailQ Deletion. */
1273while (!TAILQ_EMPTY(&head)) {
1274	n1 = TAILQ_FIRST(&head);
1275	TAILQ_REMOVE(&head, n1, entries);
1276	free(n1);
1277}
1278					/* Faster TailQ Deletion. */
1279n1 = TAILQ_FIRST(&head);
1280while (n1 != NULL) {
1281	n2 = TAILQ_NEXT(n1, entries);
1282	free(n1);
1283	n1 = n2;
1284}
1285TAILQ_INIT(&head);
1286.Ed
1287.Sh DIAGNOSTICS
1288When debugging
1289.Nm queue.h(3head) ,
1290it can be useful to trace queue changes.
1291To enable tracing, define the macro
1292.Va QUEUE_MACRO_DEBUG_TRACE
1293at compile time.
1294.Pp
1295It can also be useful to trash pointers that have been unlinked from a queue,
1296to detect use after removal.
1297To enable pointer trashing, define the macro
1298.Va QUEUE_MACRO_DEBUG_TRASH
1299at compile time.
1300The macro
1301.Fn QMD_IS_TRASHED "void *ptr"
1302returns true if
1303.Fa ptr
1304has been trashed by the
1305.Va QUEUE_MACRO_DEBUG_TRASH
1306option.
1307.Sh INTERFACE STABILITY
1308Committed
1309.Sh MT-LEVEL
1310Unsafe
1311.Sh HISTORY
1312The
1313.Nm queue
1314functions first appeared in
1315.Bx 4.4 .
1316