xref: /netbsd-src/share/man/man3/queue.3 (revision 7ba763594c652a243f3749f6420341718e1a8fbc)
1*7ba76359Skamil.\"	$NetBSD: queue.3,v 1.61 2020/10/20 23:27:57 kamil Exp $
2a05c7063Smycroft.\"
306de4264Slukem.\" Copyright (c) 2000, 2002 The NetBSD Foundation, Inc.
4a05c7063Smycroft.\" All rights reserved.
5a05c7063Smycroft.\"
6a05c7063Smycroft.\" Redistribution and use in source and binary forms, with or without
7a05c7063Smycroft.\" modification, are permitted provided that the following conditions
8a05c7063Smycroft.\" are met:
9a05c7063Smycroft.\" 1. Redistributions of source code must retain the above copyright
10a05c7063Smycroft.\"    notice, this list of conditions and the following disclaimer.
11a05c7063Smycroft.\" 2. Redistributions in binary form must reproduce the above copyright
12a05c7063Smycroft.\"    notice, this list of conditions and the following disclaimer in the
13a05c7063Smycroft.\"    documentation and/or other materials provided with the distribution.
14a05c7063Smycroft.\"
15a05c7063Smycroft.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
16a05c7063Smycroft.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17a05c7063Smycroft.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18a05c7063Smycroft.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
19a05c7063Smycroft.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20a05c7063Smycroft.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21a05c7063Smycroft.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22a05c7063Smycroft.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23a05c7063Smycroft.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24a05c7063Smycroft.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25a05c7063Smycroft.\" POSSIBILITY OF SUCH DAMAGE.
26ee52468aSjtc.\"
27ee52468aSjtc.\" Copyright (c) 1993 The Regents of the University of California.
28ee52468aSjtc.\" All rights reserved.
29630651b7Scgd.\"
30630651b7Scgd.\" Redistribution and use in source and binary forms, with or without
31630651b7Scgd.\" modification, are permitted provided that the following conditions
32630651b7Scgd.\" are met:
33630651b7Scgd.\" 1. Redistributions of source code must retain the above copyright
34630651b7Scgd.\"    notice, this list of conditions and the following disclaimer.
35630651b7Scgd.\" 2. Redistributions in binary form must reproduce the above copyright
36630651b7Scgd.\"    notice, this list of conditions and the following disclaimer in the
37630651b7Scgd.\"    documentation and/or other materials provided with the distribution.
38075022b3Sagc.\" 3. Neither the name of the University nor the names of its contributors
39630651b7Scgd.\"    may be used to endorse or promote products derived from this software
40630651b7Scgd.\"    without specific prior written permission.
41630651b7Scgd.\"
42630651b7Scgd.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
43630651b7Scgd.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44630651b7Scgd.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45630651b7Scgd.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
46630651b7Scgd.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47630651b7Scgd.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
48630651b7Scgd.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49630651b7Scgd.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
50630651b7Scgd.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
51630651b7Scgd.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
52630651b7Scgd.\" SUCH DAMAGE.
53630651b7Scgd.\"
54ee52468aSjtc.\"	@(#)queue.3	8.1 (Berkeley) 12/13/93
55630651b7Scgd.\"
5637871fa6Spgoyette.Dd October 1, 2017
57630651b7Scgd.Dt QUEUE 3
585b40cb57Sgarbled.Os
59630651b7Scgd.Sh NAME
604c51b74bSdeberg.Nm SLIST_HEAD ,
614c51b74bSdeberg.Nm SLIST_HEAD_INITIALIZER ,
622f6ed1a8Slukem.Nm SLIST_ENTRY ,
6382164e46Schristos.Nm SLIST_FIRST ,
6482164e46Schristos.Nm SLIST_EMPTY ,
6582164e46Schristos.Nm SLIST_NEXT ,
664c51b74bSdeberg.Nm SLIST_FOREACH ,
670d53a16dSmschuett.Nm SLIST_FOREACH_SAFE ,
6882164e46Schristos.Nm SLIST_INIT ,
6982164e46Schristos.Nm SLIST_INSERT_AFTER ,
700246bab0Swiz.Nm SLIST_INSERT_HEAD ,
7182164e46Schristos.Nm SLIST_REMOVE_AFTER ,
7282164e46Schristos.Nm SLIST_REMOVE_HEAD ,
7382164e46Schristos.Nm SLIST_REMOVE ,
7406de4264Slukem.Nm LIST_HEAD ,
7506de4264Slukem.Nm LIST_HEAD_INITIALIZER ,
762f6ed1a8Slukem.Nm LIST_ENTRY ,
7782164e46Schristos.Nm LIST_FIRST ,
7882164e46Schristos.Nm LIST_EMPTY ,
7982164e46Schristos.Nm LIST_NEXT ,
8082164e46Schristos.Nm LIST_FOREACH ,
8182164e46Schristos.Nm LIST_FOREACH_SAFE ,
8206de4264Slukem.Nm LIST_INIT ,
8306de4264Slukem.Nm LIST_INSERT_AFTER ,
8406de4264Slukem.Nm LIST_INSERT_BEFORE ,
8506de4264Slukem.Nm LIST_INSERT_HEAD ,
8606de4264Slukem.Nm LIST_REMOVE ,
8782164e46Schristos.Nm LIST_REPLACE ,
88169afaf5Srmind.Nm LIST_MOVE ,
8982164e46Schristos.Nm SIMPLEQ_HEAD ,
9082164e46Schristos.Nm SIMPLEQ_HEAD_INITIALIZER ,
9182164e46Schristos.Nm SIMPLEQ_ENTRY ,
9282164e46Schristos.Nm SIMPLEQ_FIRST ,
9382164e46Schristos.Nm SIMPLEQ_EMPTY ,
9482164e46Schristos.Nm SIMPLEQ_NEXT ,
9582164e46Schristos.Nm SIMPLEQ_LAST ,
9682164e46Schristos.Nm SIMPLEQ_FOREACH ,
9782164e46Schristos.Nm SIMPLEQ_FOREACH_SAFE ,
9882164e46Schristos.Nm SIMPLEQ_INIT ,
990246bab0Swiz.Nm SIMPLEQ_INSERT_AFTER ,
10082164e46Schristos.Nm SIMPLEQ_INSERT_HEAD ,
10182164e46Schristos.Nm SIMPLEQ_INSERT_TAIL ,
10282164e46Schristos.Nm SIMPLEQ_REMOVE_AFTER ,
1030246bab0Swiz.Nm SIMPLEQ_REMOVE_HEAD ,
10482164e46Schristos.Nm SIMPLEQ_REMOVE ,
10582164e46Schristos.Nm SIMPLEQ_CONCAT ,
106630651b7Scgd.Nm TAILQ_HEAD ,
107ed72b850Scgd.Nm TAILQ_HEAD_INITIALIZER ,
1082f6ed1a8Slukem.Nm TAILQ_ENTRY ,
10982164e46Schristos.Nm TAILQ_FIRST ,
11082164e46Schristos.Nm TAILQ_NEXT ,
11182164e46Schristos.Nm TAILQ_LAST ,
11282164e46Schristos.Nm TAILQ_PREV ,
11382164e46Schristos.Nm TAILQ_EMPTY ,
11482164e46Schristos.Nm TAILQ_FOREACH ,
11582164e46Schristos.Nm TAILQ_FOREACH_SAFE ,
11682164e46Schristos.Nm TAILQ_FOREACH_REVERSE ,
11782164e46Schristos.Nm TAILQ_FOREACH_REVERSE_SAFE ,
118630651b7Scgd.Nm TAILQ_INIT ,
1192f6ed1a8Slukem.Nm TAILQ_INSERT_AFTER ,
1202f6ed1a8Slukem.Nm TAILQ_INSERT_BEFORE ,
1210246bab0Swiz.Nm TAILQ_INSERT_HEAD ,
1220246bab0Swiz.Nm TAILQ_INSERT_TAIL ,
123630651b7Scgd.Nm TAILQ_REMOVE ,
12482164e46Schristos.Nm TAILQ_REPLACE ,
12598c50c91Selad.Nm TAILQ_CONCAT ,
12682164e46Schristos.Nm STAILQ_HEAD ,
12782164e46Schristos.Nm STAILQ_HEAD_INITIALIZER ,
12882164e46Schristos.Nm STAILQ_ENTRY ,
12982164e46Schristos.Nm STAILQ_FIRST ,
13082164e46Schristos.Nm STAILQ_EMPTY ,
13182164e46Schristos.Nm STAILQ_NEXT ,
13282164e46Schristos.Nm STAILQ_LAST ,
13382164e46Schristos.Nm STAILQ_FOREACH ,
13482164e46Schristos.Nm STAILQ_FOREACH_SAFE ,
13582164e46Schristos.Nm STAILQ_INIT ,
1360246bab0Swiz.Nm STAILQ_INSERT_AFTER ,
13782164e46Schristos.Nm STAILQ_INSERT_HEAD ,
13882164e46Schristos.Nm STAILQ_INSERT_TAIL ,
13982164e46Schristos.Nm STAILQ_REMOVE_HEAD ,
14082164e46Schristos.Nm STAILQ_REMOVE ,
1411582bbd5Sabhinav.Nm STAILQ_CONCAT
142f2155026Swiz.Nd implementations of singly-linked lists, lists, simple queues, tail queues, and singly-linked tail queues
143630651b7Scgd.Sh SYNOPSIS
144472351e1Swiz.In sys/queue.h
145ba856526Snjoly.Pp
1464c51b74bSdeberg.Fn SLIST_HEAD "HEADNAME" "TYPE"
1474c51b74bSdeberg.Fn SLIST_HEAD_INITIALIZER "head"
1482f6ed1a8Slukem.Fn SLIST_ENTRY "TYPE"
14982164e46Schristos.Ft TYPE *
15082164e46Schristos.Fn SLIST_FIRST "SLIST_HEAD *head"
1514c51b74bSdeberg.Ft int
1524c51b74bSdeberg.Fn SLIST_EMPTY "SLIST_HEAD *head"
1534c51b74bSdeberg.Ft TYPE *
1544c51b74bSdeberg.Fn SLIST_NEXT "TYPE *elm" "SLIST_ENTRY NAME"
15582164e46Schristos.Fn SLIST_FOREACH "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME"
15682164e46Schristos.Fn SLIST_FOREACH_SAFE "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME" "TYPE *tmp"
15782164e46Schristos.Fn SLIST_INIT "SLIST_HEAD *head"
15882164e46Schristos.Fn SLIST_INSERT_HEAD "SLIST_HEAD *head" "TYPE *elm" "SLIST_ENTRY NAME"
15982164e46Schristos.Fn SLIST_INSERT_AFTER "TYPE *listelm" "TYPE *elm" "SLIST_ENTRY NAME"
16082164e46Schristos.Fn SLIST_REMOVE "SLIST_HEAD *head" "TYPE *elm" "TYPE" "SLIST_ENTRY NAME"
16182164e46Schristos.Fn SLIST_REMOVE_HEAD "SLIST_HEAD *head" "SLIST_ENTRY NAME"
162ba856526Snjoly.Pp
16306de4264Slukem.Fn LIST_HEAD "HEADNAME" "TYPE"
16406de4264Slukem.Fn LIST_HEAD_INITIALIZER "head"
1652f6ed1a8Slukem.Fn LIST_ENTRY "TYPE"
16682164e46Schristos.Ft TYPE *
16782164e46Schristos.Fn LIST_FIRST "LIST_HEAD *head"
16882164e46Schristos.Ft TYPE *
16982164e46Schristos.Fn LIST_NEXT "TYPE *elm" "LIST_ENTRY NAME"
17082164e46Schristos.Ft int
17182164e46Schristos.Fn LIST_EMPTY "LIST_HEAD *head"
17282164e46Schristos.Fn LIST_FOREACH "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME"
17382164e46Schristos.Fn LIST_FOREACH_SAFE "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME" "TYPE *tmp"
17406de4264Slukem.Fn LIST_INIT "LIST_HEAD *head"
17506de4264Slukem.Fn LIST_INSERT_AFTER "TYPE *listelm" "TYPE *elm" "LIST_ENTRY NAME"
17606de4264Slukem.Fn LIST_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "LIST_ENTRY NAME"
17706de4264Slukem.Fn LIST_INSERT_HEAD "LIST_HEAD *head" "TYPE *elm" "LIST_ENTRY NAME"
17806de4264Slukem.Fn LIST_REMOVE "TYPE *elm" "LIST_ENTRY NAME"
17982164e46Schristos.Fn LIST_REPLACE "TYPE *elm" "TYPE *new" "LIST_ENTRY NAME"
18037871fa6Spgoyette.Fn LIST_MOVE "LIST_HEAD *head1" "LIST_HEAD *head2" "LIST_ENTRY NAME"
18182164e46Schristos.Pp
18282164e46Schristos.Fn SIMPLEQ_HEAD "HEADNAME" "TYPE"
18382164e46Schristos.Fn SIMPLEQ_HEAD_INITIALIZER "head"
18482164e46Schristos.Fn SIMPLEQ_ENTRY "TYPE"
18582164e46Schristos.Ft TYPE *
18682164e46Schristos.Fn SIMPLEQ_FIRST "SIMPLEQ_HEAD *head"
18706de4264Slukem.Ft int
18882164e46Schristos.Fn SIMPLEQ_EMPTY "SIMPLEQ_HEAD *head"
18906de4264Slukem.Ft TYPE *
19082164e46Schristos.Fn SIMPLEQ_NEXT "TYPE *elm" "SIMPLEQ_ENTRY NAME"
19106de4264Slukem.Ft TYPE *
19282164e46Schristos.Fn SIMPLEQ_LAST "SIMPLEQ_HEAD *head" "TYPE *elm" "SIMPLEQ_ENTRY NAME"
19382164e46Schristos.Fn SIMPLEQ_FOREACH "TYPE *var" "SIMPLEQ_HEAD *head" "SIMPLEQ_ENTRY NAME"
19482164e46Schristos.Fn SIMPLEQ_FOREACH_SAFE "TYPE *var" "SIMPLEQ_HEAD *head" "SIMPLEQ_ENTRY NAME" "TYPE *tmp"
19582164e46Schristos.Fn SIMPLEQ_INIT "SIMPLEQ_HEAD *head"
19682164e46Schristos.Fn SIMPLEQ_INSERT_HEAD "SIMPLEQ_HEAD *head" "TYPE *elm" "SIMPLEQ_ENTRY NAME"
19782164e46Schristos.Fn SIMPLEQ_INSERT_TAIL "SIMPLEQ_HEAD *head" "TYPE *elm" "SIMPLEQ_ENTRY NAME"
19882164e46Schristos.Fn SIMPLEQ_INSERT_AFTER "SIMPLEQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "SIMPLEQ_ENTRY NAME"
19982164e46Schristos.Fn SIMPLEQ_REMOVE_HEAD "SIMPLEQ_HEAD *head" "SIMPLEQ_ENTRY NAME"
20082164e46Schristos.Fn SIMPLEQ_REMOVE_AFTER "SIMPLEQ_HEAD *head" "TYPE *elm" "SIMPLEQ_ENTRY NAME"
20182164e46Schristos.Fn SIMPLEQ_REMOVE "SIMPLEQ_HEAD *head" "TYPE *elm" "TYPE" "SIMPLEQ_ENTRY NAME"
20282164e46Schristos.Fn SIMPLEQ_CONCAT "SIMPLEQ_HEAD *head1" "SIMPLEQ_HEAD *head2"
203ba856526Snjoly.Pp
204630651b7Scgd.Fn TAILQ_HEAD "HEADNAME" "TYPE"
205ed72b850Scgd.Fn TAILQ_HEAD_INITIALIZER "head"
2062f6ed1a8Slukem.Fn TAILQ_ENTRY "TYPE"
207dcbd40b7Sthorpej.Ft TYPE *
208dcbd40b7Sthorpej.Fn TAILQ_FIRST "TAILQ_HEAD *head"
209dcbd40b7Sthorpej.Ft TYPE *
210dcbd40b7Sthorpej.Fn TAILQ_NEXT "TYPE *elm" "TAILQ_ENTRY NAME"
2112f6ed1a8Slukem.Ft TYPE *
2122f6ed1a8Slukem.Fn TAILQ_LAST "TAILQ_HEAD *head" "HEADNAME"
2132f6ed1a8Slukem.Ft TYPE *
2142f6ed1a8Slukem.Fn TAILQ_PREV "TYPE *elm" "HEADNAME" "TAILQ_ENTRY NAME"
21582164e46Schristos.Ft int
21682164e46Schristos.Fn TAILQ_EMPTY "TAILQ_HEAD *head"
21782164e46Schristos.Fn TAILQ_FOREACH "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME"
21882164e46Schristos.Fn TAILQ_FOREACH_SAFE "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME" "TYPE *tmp"
21982164e46Schristos.Fn TAILQ_FOREACH_REVERSE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME"
22082164e46Schristos.Fn TAILQ_FOREACH_REVERSE_SAFE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME" "TYPE *tmp"
22182164e46Schristos.Fn TAILQ_INIT "TAILQ_HEAD *head"
22282164e46Schristos.Fn TAILQ_INSERT_HEAD "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
22382164e46Schristos.Fn TAILQ_INSERT_TAIL "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
22482164e46Schristos.Fn TAILQ_INSERT_AFTER "TAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME"
22582164e46Schristos.Fn TAILQ_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME"
22682164e46Schristos.Fn TAILQ_REMOVE "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
22782164e46Schristos.Fn TAILQ_REPLACE "TAILQ_HEAD *head" "TYPE *elm" "TYPE *new" "TAILQ_ENTRY NAME"
22898c50c91Selad.Fn TAILQ_CONCAT "TAILQ_HEAD *head1" "TAILQ_HEAD *head2" "TAILQ_ENTRY NAME"
22982164e46Schristos.Pp
23082164e46Schristos.Fn STAILQ_HEAD "HEADNAME" "TYPE"
23182164e46Schristos.Fn STAILQ_HEAD_INITIALIZER "head"
23282164e46Schristos.Fn STAILQ_ENTRY "TYPE"
23382164e46Schristos.Ft TYPE *
23482164e46Schristos.Fn STAILQ_FIRST "STAILQ_HEAD *head"
23582164e46Schristos.Ft int
23682164e46Schristos.Fn STAILQ_EMPTY "STAILQ_HEAD *head"
23782164e46Schristos.Ft TYPE *
23882164e46Schristos.Fn STAILQ_NEXT "TYPE *elm" "STAILQ_ENTRY NAME"
23982164e46Schristos.Ft TYPE *
24082164e46Schristos.Fn STAILQ_LAST "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
24182164e46Schristos.Fn STAILQ_FOREACH "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME"
24282164e46Schristos.Fn STAILQ_FOREACH_SAFE "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" "TYPE *tmp"
24382164e46Schristos.Fn STAILQ_INIT "STAILQ_HEAD *head"
24482164e46Schristos.Fn STAILQ_INSERT_HEAD "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
24582164e46Schristos.Fn STAILQ_INSERT_TAIL "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
24682164e46Schristos.Fn STAILQ_INSERT_AFTER "STAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "STAILQ_ENTRY NAME"
24782164e46Schristos.Fn STAILQ_REMOVE_HEAD "STAILQ_HEAD *head" "STAILQ_ENTRY NAME"
24882164e46Schristos.Fn STAILQ_REMOVE "STAILQ_HEAD *head" "TYPE *elm" "TYPE" "STAILQ_ENTRY NAME"
24982164e46Schristos.Fn STAILQ_CONCAT "STAILQ_HEAD *head1" "STAILQ_HEAD *head2"
250630651b7Scgd.Sh DESCRIPTION
25182164e46SchristosThese macros define and operate on five types of data structures:
2520246bab0Swizsingly-linked lists, simple queues, lists, tail queues, and singly-linked
25382164e46Schristostail queues.
25482164e46SchristosAll five structures support the following functionality:
255630651b7Scgd.Bl -enum -compact -offset indent
256630651b7Scgd.It
257630651b7ScgdInsertion of a new entry at the head of the list.
258630651b7Scgd.It
2597554718dSpgoyetteInsertion of a new entry after any element in the list.
260630651b7Scgd.It
261630651b7ScgdRemoval of any entry in the list.
262630651b7Scgd.It
263630651b7ScgdForward traversal through the list.
264630651b7Scgd.El
265630651b7Scgd.Pp
2669e7349a5SchristosSingly-linked lists are the simplest of the four data structures and
2674c51b74bSdebergsupport only the above functionality.
2684c51b74bSdebergSingly-linked lists are ideal for applications with large datasets and
2694c51b74bSdebergfew or no removals,
2704c51b74bSdebergor for implementing a LIFO queue.
271630651b7Scgd.Pp
27268727e36SchristosSimple queues add the following functionality:
27368727e36Schristos.Bl -enum -compact -offset indent
27468727e36Schristos.It
27568727e36SchristosEntries can be added at the end of a list.
27698c50c91Selad.It
27798c50c91SeladThey may be concatenated.
27868727e36Schristos.El
27968727e36SchristosHowever:
28068727e36Schristos.Bl -enum -compact -offset indent
28168727e36Schristos.It
28268727e36SchristosEntries may not be added before any element in the list.
28368727e36Schristos.It
28468727e36SchristosAll list insertions and removals must specify the head of the list.
28568727e36Schristos.It
28668727e36SchristosEach head entry requires two pointers rather than one.
28768727e36Schristos.El
28868727e36Schristos.Pp
2894c51b74bSdebergSimple queues are ideal for applications with large datasets and few or
2904c51b74bSdebergno removals, or for implementing a FIFO queue.
2914c51b74bSdeberg.Pp
29206dfe20dSwizAll doubly linked types of data structures (lists and tail queues)
2939e7349a5Schristosadditionally allow:
2944c51b74bSdeberg.Bl -enum -compact -offset indent
2954c51b74bSdeberg.It
2964c51b74bSdebergInsertion of a new entry before any element in the list.
2974c51b74bSdeberg.It
2984c51b74bSdebergO(1) removal of any entry in the list.
2994c51b74bSdeberg.El
3004c51b74bSdebergHowever:
3014c51b74bSdeberg.Bl -enum -compact -offset indent
3024c51b74bSdeberg.It
3034e4095f1SwizEach element requires two pointers rather than one.
3044c51b74bSdeberg.It
3054c51b74bSdebergCode size and execution time of operations (except for removal) is about
3064c51b74bSdebergtwice that of the singly-linked data-structures.
3074c51b74bSdeberg.El
3084c51b74bSdeberg.Pp
3094c51b74bSdebergLinked lists are the simplest of the doubly linked data structures and
3104c51b74bSdebergsupport only the above functionality over singly-linked lists.
3114c51b74bSdeberg.Pp
312630651b7ScgdTail queues add the following functionality:
313630651b7Scgd.Bl -enum -compact -offset indent
314630651b7Scgd.It
315630651b7ScgdEntries can be added at the end of a list.
31698c50c91Selad.It
31798c50c91SeladThey may be concatenated.
318630651b7Scgd.El
319630651b7ScgdHowever:
320630651b7Scgd.Bl -enum -compact -offset indent
321630651b7Scgd.It
32273a1524aSmycroftAll list insertions and removals, except insertion before another element, must
32373a1524aSmycroftspecify the head of the list.
324630651b7Scgd.It
325630651b7ScgdEach head entry requires two pointers rather than one.
326630651b7Scgd.It
327630651b7ScgdCode size is about 15% greater and operations run about 20% slower
328630651b7Scgdthan lists.
329630651b7Scgd.El
330630651b7Scgd.Pp
331630651b7ScgdCircular queues add the following functionality:
332630651b7Scgd.Bl -enum -compact -offset indent
333630651b7Scgd.It
334630651b7ScgdEntries can be added at the end of a list.
335630651b7Scgd.It
336630651b7ScgdThey may be traversed backwards, from tail to head.
337630651b7Scgd.El
338630651b7ScgdHowever:
339630651b7Scgd.Bl -enum -compact -offset indent
340630651b7Scgd.It
341630651b7ScgdAll list insertions and removals must specify the head of the list.
342630651b7Scgd.It
343630651b7ScgdEach head entry requires two pointers rather than one.
344630651b7Scgd.It
345630651b7ScgdThe termination condition for traversal is more complex.
346630651b7Scgd.It
347630651b7ScgdCode size is about 40% greater and operations run about 45% slower
348630651b7Scgdthan lists.
349630651b7Scgd.El
350630651b7Scgd.Pp
351630651b7ScgdIn the macro definitions,
352630651b7Scgd.Fa TYPE
353630651b7Scgdis the name of a user defined structure,
354630651b7Scgdthat must contain a field of type
35582164e46Schristos.Li SLIST_ENTRY ,
356630651b7Scgd.Li LIST_ENTRY ,
35768727e36Schristos.Li SIMPLEQ_ENTRY ,
3589e7349a5Schristos.Li TAILQ_ENTRY ,
35982164e46Schristosor
36082164e46Schristos.Li STAILQ_ENTRY ,
361630651b7Scgdnamed
362630651b7Scgd.Fa NAME .
363630651b7ScgdThe argument
364630651b7Scgd.Fa HEADNAME
365630651b7Scgdis the name of a user defined structure that must be declared
366630651b7Scgdusing the macros
367630651b7Scgd.Li LIST_HEAD ,
36868727e36Schristos.Li SIMPLEQ_HEAD ,
3694c51b74bSdeberg.Li SLIST_HEAD ,
370630651b7Scgdor
37162d7bff7Ssnj.Li TAILQ_HEAD .
372630651b7ScgdSee the examples below for further explanation of how these
373630651b7Scgdmacros are used.
37494e818b2Spooka.Ss Summary of Operations
37594e818b2SpookaThe following table summarizes the supported macros for each type
37694e818b2Spookaof data structure.
37794e818b2Spooka.Pp
37894e818b2Spooka.TS
37994e818b2Spookabox tab(:);
3809e7349a5Schristosl | c | c | c | c | c
3819e7349a5Schristosl | c | c | c | c | c
3829e7349a5Schristosl | c | c | c | c | c
3839e7349a5Schristosl | c | c | c | c | c
3849e7349a5Schristosl | c | c | c | c | c
3859e7349a5Schristosl | c | c | c | c | c.
38682164e46Schristos:SLIST:LIST:SIMPLEQ:TAILQ:STAILQ
38794e818b2Spooka_
3889e7349a5Schristos_FIRST:+:+:+:+:+
38982164e46Schristos_EMPTY:+:+:+:+:+
3909e7349a5Schristos_NEXT:+:+:+:+:+
39182164e46Schristos_PREV:-:-:-:+:-
39282164e46Schristos_LAST:-:-:+:+:+
39382164e46Schristos_FOREACH:+:+:+:+:+
39482164e46Schristos_FOREACH_SAFE:+:+:+:+:+
39582164e46Schristos_FOREACH_REVERSE:-:-:-:+:-
39682164e46Schristos_FOREACH_REVERSE_SAFE:-:-:-:+:-
39782164e46Schristos_INSERT_HEAD:+:+:+:+:+
39882164e46Schristos_INSERT_AFTER:+:+:+:+:+
39982164e46Schristos_INSERT_BEFORE:-:+:-:+:-
40082164e46Schristos_INSERT_TAIL:-:-:+:+:+
4019e7349a5Schristos_REMOVE:+:+:+:+:+
40282164e46Schristos_REMOVE_HEAD:+:-:+:-:+
40382164e46Schristos_REMOVE_AFTER:-:-:+:-:+
40482164e46Schristos_REPLACE:-:+:-:+:-
4059e7349a5Schristos_CONCAT:-:-:+:+:+
40694e818b2Spooka.TE
4074c51b74bSdeberg.Sh SINGLY-LINKED LISTS
4084c51b74bSdebergA singly-linked list is headed by a structure defined by the
4090604df8aSabhinav.Fn SLIST_HEAD
4104c51b74bSdebergmacro.
4114c51b74bSdebergThis structure contains a single pointer to the first element
4124c51b74bSdebergon the list.
4134c51b74bSdebergThe elements are singly linked for minimum space and pointer manipulation
4144c51b74bSdebergoverhead at the expense of O(n) removal for arbitrary elements.
4154c51b74bSdebergNew elements can be added to the list after an existing element or
4164c51b74bSdebergat the head of the list.
4174c51b74bSdebergAn
4184c51b74bSdeberg.Fa SLIST_HEAD
4194c51b74bSdebergstructure is declared as follows:
4204c51b74bSdeberg.Bd -literal -offset indent
4214c51b74bSdebergSLIST_HEAD(HEADNAME, TYPE) head;
4224c51b74bSdeberg.Ed
4234c51b74bSdeberg.Pp
4244c51b74bSdebergwhere
4254c51b74bSdeberg.Fa HEADNAME
4264c51b74bSdebergis the name of the structure to be defined, and
4274c51b74bSdeberg.Fa TYPE
4284c51b74bSdebergis the type of the elements to be linked into the list.
4294c51b74bSdebergA pointer to the head of the list can later be declared as:
4304c51b74bSdeberg.Bd -literal -offset indent
4314c51b74bSdebergstruct HEADNAME *headp;
4324c51b74bSdeberg.Ed
4334c51b74bSdeberg.Pp
4344c51b74bSdeberg(The names
4354c51b74bSdeberg.Li head
4364c51b74bSdebergand
4374c51b74bSdeberg.Li headp
4384c51b74bSdebergare user selectable.)
4394c51b74bSdeberg.Pp
4404c51b74bSdebergThe macro
4410604df8aSabhinav.Fn SLIST_HEAD_INITIALIZER
4424c51b74bSdebergevaluates to an initializer for the list
4434c51b74bSdeberg.Fa head .
4444c51b74bSdeberg.Pp
4454c51b74bSdebergThe macro
4460604df8aSabhinav.Fn SLIST_ENTRY
4474c51b74bSdebergdeclares a structure that connects the elements in
4484c51b74bSdebergthe list.
4494c51b74bSdeberg.Pp
4504c51b74bSdebergThe macro
4510604df8aSabhinav.Fn SLIST_FIRST
4524c51b74bSdebergreturns the first element in the list or NULL if the list is empty.
4534c51b74bSdeberg.Pp
4544c51b74bSdebergThe macro
4550604df8aSabhinav.Fn SLIST_EMPTY
45682164e46Schristosevaluates to true if there are no elements in the list.
45782164e46Schristos.Pp
45882164e46SchristosThe macro
4590604df8aSabhinav.Fn SLIST_NEXT
46082164e46Schristosreturns the next element in the list.
46182164e46Schristos.Pp
4620604df8aSabhinav.Fn SLIST_FOREACH
4634c51b74bSdebergtraverses the list referenced by
4644c51b74bSdeberg.Fa head
4654c51b74bSdebergin the forward direction, assigning each element in
4664c51b74bSdebergturn to
4674c51b74bSdeberg.Fa var .
4684c51b74bSdeberg.Pp
46982164e46SchristosThe SAFE version uses
4700d53a16dSmschuett.Fa tmp
4710d53a16dSmschuettto hold the next element, so
4720d53a16dSmschuett.Fa var
4730d53a16dSmschuettmay be freed or removed from the list.
4740d53a16dSmschuett.Pp
4754c51b74bSdebergThe macro
4760604df8aSabhinav.Fn SLIST_INIT
4774c51b74bSdeberginitializes the list referenced by
4784c51b74bSdeberg.Fa head .
4794c51b74bSdeberg.Pp
4804c51b74bSdebergThe macro
4810604df8aSabhinav.Fn SLIST_INSERT_HEAD
4824c51b74bSdeberginserts the new element
4834c51b74bSdeberg.Fa elm
4844c51b74bSdebergat the head of the list.
4854c51b74bSdeberg.Pp
4864c51b74bSdebergThe macro
4870604df8aSabhinav.Fn SLIST_INSERT_AFTER
4884c51b74bSdeberginserts the new element
4894c51b74bSdeberg.Fa elm
4904c51b74bSdebergafter the element
4914c51b74bSdeberg.Fa listelm .
4924c51b74bSdeberg.Pp
4934c51b74bSdebergThe macro
4940604df8aSabhinav.Fn SLIST_REMOVE
49506de4264Slukemremoves the element
49606de4264Slukem.Fa elm
49706de4264Slukemfrom the list.
49806de4264Slukem.Pp
49906de4264SlukemThe macro
5000604df8aSabhinav.Fn SLIST_REMOVE_HEAD
501874c812dSlukemremoves the first element from the head of the list.
5024c51b74bSdebergFor optimum efficiency,
5034c51b74bSdebergelements being removed from the head of the list should explicitly use
5044c51b74bSdebergthis macro instead of the generic
5050604df8aSabhinav.Fn SLIST_REMOVE
50606de4264Slukemmacro.
50782164e46Schristos.Pp
50862d7bff7SsnjThe macro
5090604df8aSabhinav.Fn SLIST_REMOVE_AFTER
51082164e46Schristosremoves the element after the one specified.
51182164e46SchristosFor optimum efficiency,
51282164e46Schristoselements being removed after a specified one should explicitly use
51382164e46Schristosthis macro instead of the generic
5140604df8aSabhinav.Fn SLIST_REMOVE
5154c51b74bSdeberg.Sh SINGLY-LINKED LIST EXAMPLE
5164c51b74bSdeberg.Bd -literal
5174c51b74bSdebergSLIST_HEAD(slisthead, entry) head =
5184c51b74bSdeberg    SLIST_HEAD_INITIALIZER(head);
5194c51b74bSdebergstruct slisthead *headp;                /* Singly-linked List head. */
5204c51b74bSdebergstruct entry {
5214c51b74bSdeberg        ...
5224c51b74bSdeberg        SLIST_ENTRY(entry) entries;     /* Singly-linked List. */
5234c51b74bSdeberg        ...
5244c51b74bSdeberg} *n1, *n2, *n3, *np;
5254c51b74bSdeberg
52601869ca4SwizSLIST_INIT(&head);                      /* Initialize the list. */
5274c51b74bSdeberg
5284c51b74bSdebergn1 = malloc(sizeof(struct entry));      /* Insert at the head. */
52901869ca4SwizSLIST_INSERT_HEAD(&head, n1, entries);
5304c51b74bSdeberg
5314c51b74bSdebergn2 = malloc(sizeof(struct entry));      /* Insert after. */
5324c51b74bSdebergSLIST_INSERT_AFTER(n1, n2, entries);
5334c51b74bSdeberg
53401869ca4SwizSLIST_REMOVE(&head, n2, entry, entries);/* Deletion. */
5354c51b74bSdebergfree(n2);
5364c51b74bSdeberg
53701869ca4Swizn3 = SLIST_FIRST(&head);
53801869ca4SwizSLIST_REMOVE_HEAD(&head, entries);      /* Deletion from the head. */
5394c51b74bSdebergfree(n3);
540318922f0Sryoon
54101869ca4SwizSLIST_FOREACH(np, &head, entries)       /* Forward traversal. */
54201869ca4Swiz        np-> ...
5434c51b74bSdeberg
54401869ca4Swizwhile (!SLIST_EMPTY(&head)) {           /* List Deletion. */
54501869ca4Swiz        n1 = SLIST_FIRST(&head);
54601869ca4Swiz        SLIST_REMOVE_HEAD(&head, entries);
5474c51b74bSdeberg        free(n1);
5484c51b74bSdeberg}
5494c51b74bSdeberg.Ed
55082164e46Schristos.Sh LISTS
55182164e46SchristosA list is headed by a structure defined by the
5520604df8aSabhinav.Fn LIST_HEAD
55382164e46Schristosmacro.
55482164e46SchristosThis structure contains a single pointer to the first element
55582164e46Schristoson the list.
55682164e46SchristosThe elements are doubly linked so that an arbitrary element can be
55782164e46Schristosremoved without traversing the list.
55882164e46SchristosNew elements can be added to the list after an existing element,
55982164e46Schristosbefore an existing element, or at the head of the list.
56082164e46SchristosA
56182164e46Schristos.Fa LIST_HEAD
56282164e46Schristosstructure is declared as follows:
56382164e46Schristos.Bd -literal -offset indent
56482164e46SchristosLIST_HEAD(HEADNAME, TYPE) head;
56582164e46Schristos.Ed
56682164e46Schristos.Pp
56782164e46Schristoswhere
56882164e46Schristos.Fa HEADNAME
56982164e46Schristosis the name of the structure to be defined, and
57082164e46Schristos.Fa TYPE
57182164e46Schristosis the type of the elements to be linked into the list.
57282164e46SchristosA pointer to the head of the list can later be declared as:
57382164e46Schristos.Bd -literal -offset indent
57482164e46Schristosstruct HEADNAME *headp;
57582164e46Schristos.Ed
57682164e46Schristos.Pp
57782164e46Schristos(The names
57882164e46Schristos.Li head
57982164e46Schristosand
58082164e46Schristos.Li headp
58182164e46Schristosare user selectable.)
58282164e46Schristos.Pp
58382164e46SchristosThe macro
5840604df8aSabhinav.Fn LIST_ENTRY
58582164e46Schristosdeclares a structure that connects the elements in
58682164e46Schristosthe list.
58782164e46Schristos.Pp
58882164e46SchristosThe macro
5890604df8aSabhinav.Fn LIST_HEAD_INITIALIZER
59082164e46Schristosprovides a value which can be used to initialize a list head at
59182164e46Schristoscompile time, and is used at the point that the list head
59282164e46Schristosvariable is declared, like:
59382164e46Schristos.Bd -literal -offset indent
59482164e46Schristosstruct HEADNAME head = LIST_HEAD_INITIALIZER(head);
59582164e46Schristos.Ed
59682164e46Schristos.Pp
59782164e46SchristosThe macro
5980604df8aSabhinav.Fn LIST_FIRST
59982164e46Schristosreturns the first element of the list
60082164e46Schristos.Fa head .
60182164e46Schristos.Pp
60282164e46SchristosThe macro
6030604df8aSabhinav.Fn LIST_EMPTY
60462d7bff7Ssnjreturns true if the list
60582164e46Schristos.Fa head
60682164e46Schristoshas no elements.
60782164e46Schristos.Pp
60882164e46SchristosThe macro
6090604df8aSabhinav.Fn LIST_NEXT
61082164e46Schristosreturns the element after the element
61182164e46Schristos.Fa elm .
61282164e46Schristos.Pp
61382164e46SchristosThe macro
6140604df8aSabhinav.Fn LIST_FOREACH
61582164e46Schristostraverses the list referenced by
61682164e46Schristos.Fa head
61782164e46Schristosin the forward direction, assigning each element in turn to
61882164e46Schristos.Fa var .
61982164e46Schristos.Pp
62082164e46SchristosThe SAFE version uses
62182164e46Schristos.Fa tmp
62282164e46Schristosto hold the next element, so
62382164e46Schristos.Fa var
62482164e46Schristosmay be freed or removed from the list.
62582164e46Schristos.Pp
62682164e46SchristosThe macro
6270604df8aSabhinav.Fn LIST_INIT
62882164e46Schristosinitializes the list referenced by
62982164e46Schristos.Fa head .
63082164e46Schristos.Pp
63182164e46SchristosThe macro
6320604df8aSabhinav.Fn LIST_INSERT_AFTER
63382164e46Schristosinserts the new element
63482164e46Schristos.Fa elm
63582164e46Schristosafter the element
63682164e46Schristos.Fa listelm .
63782164e46Schristos.Pp
63882164e46SchristosThe macro
6390604df8aSabhinav.Fn LIST_INSERT_BEFORE
64082164e46Schristosinserts the new element
64182164e46Schristos.Fa elm
64282164e46Schristosbefore the element
64382164e46Schristos.Fa listelm .
64482164e46Schristos.Pp
64582164e46SchristosThe macro
6460604df8aSabhinav.Fn LIST_INSERT_HEAD
64782164e46Schristosinserts the new element
64882164e46Schristos.Fa elm
64982164e46Schristosat the head of the list.
65082164e46Schristos.Pp
65182164e46SchristosThe macro
6520604df8aSabhinav.Fn LIST_REMOVE
65382164e46Schristosremoves the element
65482164e46Schristos.Fa elm
65582164e46Schristosfrom the list.
65682164e46Schristos.Pp
65782164e46SchristosThe macro
6580604df8aSabhinav.Fn LIST_REPLACE
65982164e46Schristosreplaces the element
66082164e46Schristos.Fa elm
66182164e46Schristoswith
66282164e46Schristos.Fa new
66382164e46Schristosin the list.
664169afaf5Srmind.Pp
665169afaf5SrmindThe macro
6660604df8aSabhinav.Fn LIST_MOVE
667169afaf5Srmindmoves the list headed by
668169afaf5Srmind.Fa head1
669169afaf5Srmindonto the list headed by
670169afaf5Srmind.Fa head2 ,
671169afaf5Srmindalways making the former empty.
67282164e46Schristos.Sh LIST EXAMPLE
67382164e46Schristos.Bd -literal
67482164e46SchristosLIST_HEAD(listhead, entry) head;
67582164e46Schristosstruct listhead *headp;			/* List head. */
67682164e46Schristosstruct entry {
67782164e46Schristos	...
67882164e46Schristos	LIST_ENTRY(entry) entries;	/* List. */
67982164e46Schristos	...
68082164e46Schristos} *n1, *n2, *np;
68182164e46Schristos
68201869ca4SwizLIST_INIT(&head);			/* Initialize the list. */
68382164e46Schristos
68482164e46Schristosn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
68501869ca4SwizLIST_INSERT_HEAD(&head, n1, entries);
68682164e46Schristos
68782164e46Schristosn2 = malloc(sizeof(struct entry));	/* Insert after. */
68882164e46SchristosLIST_INSERT_AFTER(n1, n2, entries);
68982164e46Schristos
69082164e46Schristosn2 = malloc(sizeof(struct entry));	/* Insert before. */
69182164e46SchristosLIST_INSERT_BEFORE(n1, n2, entries);
692318922f0Sryoon
69301869ca4SwizLIST_FOREACH(np, &head, entries)	/* Forward traversal. */
69401869ca4Swiz	np-> ...
695318922f0Sryoon
69601869ca4Swizwhile (LIST_FIRST(&head) != NULL)	/* Delete. */
69701869ca4Swiz	LIST_REMOVE(LIST_FIRST(&head), entries);
69801869ca4Swizif (LIST_EMPTY(&head))			/* Test for emptiness. */
69982164e46Schristos	printf("nothing to do\\n");
70082164e46Schristos.Ed
70106de4264Slukem.Sh SIMPLE QUEUES
70206de4264SlukemA simple queue is headed by a structure defined by the
7030604df8aSabhinav.Fn SIMPLEQ_HEAD
70406de4264Slukemmacro.
70506de4264SlukemThis structure contains a pair of pointers,
70606de4264Slukemone to the first element in the simple queue and the other to
70706de4264Slukemthe last element in the simple queue.
70806de4264SlukemThe elements are singly linked for minimum space and pointer manipulation
70906de4264Slukemoverhead at the expense of O(n) removal for arbitrary elements.
71006de4264SlukemNew elements can be added to the queue after an existing element,
71106de4264Slukemat the head of the queue, or at the end of the queue.
71206de4264SlukemA
71306de4264Slukem.Fa SIMPLEQ_HEAD
71406de4264Slukemstructure is declared as follows:
71506de4264Slukem.Bd -literal -offset indent
71606de4264SlukemSIMPLEQ_HEAD(HEADNAME, TYPE) head;
71706de4264Slukem.Ed
718ba856526Snjoly.Pp
71906de4264Slukemwhere
72006de4264Slukem.Li HEADNAME
72106de4264Slukemis the name of the structure to be defined, and
72206de4264Slukem.Li TYPE
72306de4264Slukemis the type of the elements to be linked into the simple queue.
72406de4264SlukemA pointer to the head of the simple queue can later be declared as:
72506de4264Slukem.Bd -literal -offset indent
72606de4264Slukemstruct HEADNAME *headp;
72706de4264Slukem.Ed
728ba856526Snjoly.Pp
72906de4264Slukem(The names
73006de4264Slukem.Li head
73106de4264Slukemand
73206de4264Slukem.Li headp
73306de4264Slukemare user selectable.)
73406de4264Slukem.Pp
73506de4264SlukemThe macro
7360604df8aSabhinav.Fn SIMPLEQ_ENTRY
73706de4264Slukemdeclares a structure that connects the elements in
73806de4264Slukemthe simple queue.
73906de4264Slukem.Pp
74006de4264SlukemThe macro
7410604df8aSabhinav.Fn SIMPLEQ_HEAD_INITIALIZER
74206de4264Slukemprovides a value which can be used to initialize a simple queue head at
74306de4264Slukemcompile time, and is used at the point that the simple queue head
74406de4264Slukemvariable is declared, like:
74506de4264Slukem.Bd -literal -offset indent
74606de4264Slukemstruct HEADNAME head = SIMPLEQ_HEAD_INITIALIZER(head);
74706de4264Slukem.Ed
74806de4264Slukem.Pp
74906de4264SlukemThe macro
7500604df8aSabhinav.Fn SIMPLEQ_FIRST
75182164e46Schristosreturns the first element of the simple queue
75282164e46Schristos.Fa head .
75382164e46Schristos.Pp
75482164e46SchristosThe macro
7550604df8aSabhinav.Fn SIMPLEQ_EMPTY
75662d7bff7Ssnjreturns true if the simple queue
75782164e46Schristos.Fa head
75882164e46Schristoshas no elements.
75982164e46Schristos.Pp
76082164e46SchristosThe macro
7610604df8aSabhinav.Fn SIMPLEQ_NEXT
76282164e46Schristosreturns the element after the element
76382164e46Schristos.Fa elm .
76482164e46Schristos.Pp
76582164e46SchristosThe macro
7660604df8aSabhinav.Fn SIMPLEQ_LAST
76708587dfcSisakireturns the last item on the simple queue.
76808587dfcSisakiIf the simple queue is empty the return value is
76982164e46Schristos.Dv NULL .
77082164e46Schristos.Pp
77182164e46SchristosThe macro
7720604df8aSabhinav.Fn SIMPLEQ_FOREACH
77308587dfcSisakitraverses the simple queue referenced by
77482164e46Schristos.Fa head
77582164e46Schristosin the forward direction, assigning each element
77682164e46Schristosin turn to
77782164e46Schristos.Fa var .
77882164e46Schristos.Pp
77982164e46SchristosThe SAFE version uses
78082164e46Schristos.Fa tmp
78182164e46Schristosto hold the next element, so
78282164e46Schristos.Fa var
78382164e46Schristosmay be freed or removed from the list.
78482164e46Schristos.Pp
78582164e46SchristosThe macro
7860604df8aSabhinav.Fn SIMPLEQ_INIT
78706de4264Slukeminitializes the simple queue referenced by
78806de4264Slukem.Fa head .
78906de4264Slukem.Pp
79006de4264SlukemThe macro
7910604df8aSabhinav.Fn SIMPLEQ_INSERT_HEAD
79206de4264Slukeminserts the new element
79306de4264Slukem.Fa elm
79406de4264Slukemat the head of the simple queue.
79506de4264Slukem.Pp
79606de4264SlukemThe macro
7970604df8aSabhinav.Fn SIMPLEQ_INSERT_TAIL
79806de4264Slukeminserts the new element
79906de4264Slukem.Fa elm
80006de4264Slukemat the end of the simple queue.
80106de4264Slukem.Pp
80206de4264SlukemThe macro
8030604df8aSabhinav.Fn SIMPLEQ_INSERT_AFTER
80406de4264Slukeminserts the new element
80506de4264Slukem.Fa elm
80606de4264Slukemafter the element
80706de4264Slukem.Fa listelm .
80806de4264Slukem.Pp
80906de4264SlukemThe macro
8100604df8aSabhinav.Fn SIMPLEQ_REMOVE_HEAD
81106de4264Slukemremoves the first element from the head of the simple queue.
81206de4264SlukemFor optimum efficiency,
81306de4264Slukemelements being removed from the head of the queue should explicitly use
81406de4264Slukemthis macro instead of the generic
8150604df8aSabhinav.Fn SIMPLEQ_REMOVE
81606de4264Slukemmacro.
81706de4264Slukem.Pp
81806de4264SlukemThe macro
8190604df8aSabhinav.Fn SIMPLEQ_REMOVE_AFTER
82082164e46Schristosremoves the element after the one specified from the simple queue.
82182164e46SchristosFor optimum efficiency,
82282164e46Schristoselements being removed after specified elements should explicitly use
82382164e46Schristosthis macro instead of the generic
8240604df8aSabhinav.Fn SIMPLEQ_REMOVE
82582164e46Schristosmacro.
82606de4264Slukem.Pp
82706de4264SlukemThe macro
8280604df8aSabhinav.Fn SIMPLEQ_REMOVE
82982164e46Schristosremoves
83082164e46Schristos.Fa elm
83182164e46Schristosfrom the simple queue.
8320d53a16dSmschuett.Pp
8330d53a16dSmschuettThe macro
8340604df8aSabhinav.Fn SIMPLEQ_CONCAT
83508587dfcSisakiconcatenates the simple queue headed by
8360d53a16dSmschuett.Fa head2
8370d53a16dSmschuettonto the end of the one headed by
83862d7bff7Ssnj.Fa head1 ,
8390d53a16dSmschuettremoving all entries from the former.
84006de4264Slukem.Sh SIMPLE QUEUE EXAMPLE
84106de4264Slukem.Bd -literal
84206de4264SlukemSIMPLEQ_HEAD(simplehead, entry) head;
84306de4264Slukemstruct simplehead *headp;		/* Simple queue head. */
84406de4264Slukemstruct entry {
84506de4264Slukem	...
84606de4264Slukem	SIMPLEQ_ENTRY(entry) entries;	/* Simple queue. */
84706de4264Slukem	...
84806de4264Slukem} *n1, *n2, *np;
84906de4264Slukem
85001869ca4SwizSIMPLEQ_INIT(&head);			/* Initialize the queue. */
85106de4264Slukem
85206de4264Slukemn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
85301869ca4SwizSIMPLEQ_INSERT_HEAD(&head, n1, entries);
85406de4264Slukem
85506de4264Slukemn1 = malloc(sizeof(struct entry));	/* Insert at the tail. */
85601869ca4SwizSIMPLEQ_INSERT_TAIL(&head, n1, entries);
85706de4264Slukem
85806de4264Slukemn2 = malloc(sizeof(struct entry));	/* Insert after. */
85901869ca4SwizSIMPLEQ_INSERT_AFTER(&head, n1, n2, entries);
860318922f0Sryoon
86101869ca4SwizSIMPLEQ_FOREACH(np, &head, entries)	/* Forward traversal. */
86201869ca4Swiz	np-> ...
863318922f0Sryoon
86401869ca4Swizwhile (SIMPLEQ_FIRST(&head) != NULL)	/* Delete. */
86501869ca4Swiz	SIMPLEQ_REMOVE_HEAD(&head, entries);
86601869ca4Swizif (SIMPLEQ_EMPTY(&head))		/* Test for emptiness. */
86706de4264Slukem	printf("nothing to do\\n");
86806de4264Slukem.Ed
869630651b7Scgd.Sh TAIL QUEUES
870630651b7ScgdA tail queue is headed by a structure defined by the
8710604df8aSabhinav.Fn TAILQ_HEAD
872630651b7Scgdmacro.
873630651b7ScgdThis structure contains a pair of pointers,
874630651b7Scgdone to the first element in the tail queue and the other to
875630651b7Scgdthe last element in the tail queue.
876630651b7ScgdThe elements are doubly linked so that an arbitrary element can be
877630651b7Scgdremoved without traversing the tail queue.
878b545b9dbSmycroftNew elements can be added to the queue after an existing element,
879b545b9dbSmycroftbefore an existing element, at the head of the queue, or at the end
880b545b9dbSmycroftthe queue.
881630651b7ScgdA
882630651b7Scgd.Fa TAILQ_HEAD
883630651b7Scgdstructure is declared as follows:
884630651b7Scgd.Bd -literal -offset indent
885630651b7ScgdTAILQ_HEAD(HEADNAME, TYPE) head;
886630651b7Scgd.Ed
887ba856526Snjoly.Pp
888630651b7Scgdwhere
889630651b7Scgd.Li HEADNAME
890630651b7Scgdis the name of the structure to be defined, and
891630651b7Scgd.Li TYPE
892630651b7Scgdis the type of the elements to be linked into the tail queue.
893630651b7ScgdA pointer to the head of the tail queue can later be declared as:
894630651b7Scgd.Bd -literal -offset indent
895630651b7Scgdstruct HEADNAME *headp;
896630651b7Scgd.Ed
897ba856526Snjoly.Pp
898630651b7Scgd(The names
899630651b7Scgd.Li head
900630651b7Scgdand
901630651b7Scgd.Li headp
902630651b7Scgdare user selectable.)
903630651b7Scgd.Pp
904630651b7ScgdThe macro
9050604df8aSabhinav.Fn TAILQ_ENTRY
906630651b7Scgddeclares a structure that connects the elements in
907630651b7Scgdthe tail queue.
908630651b7Scgd.Pp
909630651b7ScgdThe macro
9100604df8aSabhinav.Fn TAILQ_HEAD_INITIALIZER
911ed72b850Scgdprovides a value which can be used to initialize a tail queue head at
912ed72b850Scgdcompile time, and is used at the point that the tail queue head
913ed72b850Scgdvariable is declared, like:
914ed72b850Scgd.Bd -literal -offset indent
915ed72b850Scgdstruct HEADNAME head = TAILQ_HEAD_INITIALIZER(head);
916ed72b850Scgd.Ed
917ed72b850Scgd.Pp
918ed72b850ScgdThe macro
9190604df8aSabhinav.Fn TAILQ_FIRST
92082164e46Schristosreturns the first element of the tail queue
92182164e46Schristos.Fa head .
92282164e46Schristos.Pp
92382164e46SchristosThe macro
9240604df8aSabhinav.Fn TAILQ_NEXT
92582164e46Schristosreturns the element after the element
92682164e46Schristos.Fa elm .
92782164e46Schristos.Pp
92882164e46SchristosThe macro
9290604df8aSabhinav.Fn TAILQ_LAST
93082164e46Schristosreturns the last item on the tail queue.
93182164e46SchristosIf the tail queue is empty the return value is
93282164e46Schristos.Dv NULL .
93382164e46Schristos.Pp
93482164e46SchristosThe macro
9350604df8aSabhinav.Fn TAILQ_PREV
93682164e46Schristosreturns the previous item on the tail queue, from the one specified.
93782164e46SchristosIf the tail queue is empty the return value is
93882164e46Schristos.Dv NULL .
93982164e46Schristos.Pp
94082164e46SchristosThe macro
9410604df8aSabhinav.Fn TAILQ_EMPTY
94262d7bff7Ssnjreturns true if the tail queue
94382164e46Schristos.Fa head
94482164e46Schristoshas no elements.
94582164e46Schristos.Pp
94682164e46SchristosThe macros
9470604df8aSabhinav.Fn TAILQ_FOREACH ,
9480604df8aSabhinav.Fn TAILQ_FOREACH_REVERSE ,
9490604df8aSabhinav.Fn TAILQ_FOREACH_SAFE ,
95082164e46Schristosand
9510604df8aSabhinav.Fn TAILQ_FOREACH_REVERSE_SAFE
95282164e46Schristostraverse the tail queue referenced by
95382164e46Schristos.Fa head
9548b7a64b2Seadlerin the forward or reverse direction, assigning each element in turn to
95582164e46Schristos.Fa var .
95682164e46Schristos.Pp
95782164e46SchristosThe SAFE versions use
95882164e46Schristos.Fa tmp
95982164e46Schristosto hold the next element, so
96082164e46Schristos.Fa var
96182164e46Schristosmay be freed or removed from the list.
96282164e46Schristos.Pp
96382164e46SchristosThe macro
9640604df8aSabhinav.Fn TAILQ_INIT
965630651b7Scgdinitializes the tail queue referenced by
966630651b7Scgd.Fa head .
967630651b7Scgd.Pp
968630651b7ScgdThe macro
9690604df8aSabhinav.Fn TAILQ_INSERT_HEAD
970630651b7Scgdinserts the new element
971630651b7Scgd.Fa elm
972630651b7Scgdat the head of the tail queue.
973630651b7Scgd.Pp
974630651b7ScgdThe macro
9750604df8aSabhinav.Fn TAILQ_INSERT_TAIL
976630651b7Scgdinserts the new element
977630651b7Scgd.Fa elm
978630651b7Scgdat the end of the tail queue.
979630651b7Scgd.Pp
980630651b7ScgdThe macro
9810604df8aSabhinav.Fn TAILQ_INSERT_AFTER
982630651b7Scgdinserts the new element
983630651b7Scgd.Fa elm
984630651b7Scgdafter the element
985630651b7Scgd.Fa listelm .
986630651b7Scgd.Pp
987630651b7ScgdThe macro
9880604df8aSabhinav.Fn TAILQ_INSERT_BEFORE
98973a1524aSmycroftinserts the new element
99073a1524aSmycroft.Fa elm
99173a1524aSmycroftbefore the element
99273a1524aSmycroft.Fa listelm .
99373a1524aSmycroft.Pp
99473a1524aSmycroftThe macro
9950604df8aSabhinav.Fn TAILQ_REMOVE
996630651b7Scgdremoves the element
997630651b7Scgd.Fa elm
998630651b7Scgdfrom the tail queue.
999dcbd40b7Sthorpej.Pp
1000dcbd40b7SthorpejThe macro
10010604df8aSabhinav.Fn TAILQ_REPLACE
100262d7bff7Ssnjreplaces the element
100382164e46Schristos.Fa elm
100482164e46Schristoswith the
100582164e46Schristos.Fa new
100682164e46Schristosone specified in the tail queue.
100798c50c91Selad.Pp
100898c50c91SeladThe macro
10090604df8aSabhinav.Fn TAILQ_CONCAT
101098c50c91Seladconcatenates the tail queue headed by
101198c50c91Selad.Fa head2
101298c50c91Seladonto the end of the one headed by
101362d7bff7Ssnj.Fa head1 ,
101498c50c91Seladremoving all entries from the former.
1015630651b7Scgd.Sh TAIL QUEUE EXAMPLE
1016630651b7Scgd.Bd -literal
1017630651b7ScgdTAILQ_HEAD(tailhead, entry) head;
1018630651b7Scgdstruct tailhead *headp;			/* Tail queue head. */
1019630651b7Scgdstruct entry {
1020630651b7Scgd	...
1021630651b7Scgd	TAILQ_ENTRY(entry) entries;	/* Tail queue. */
1022630651b7Scgd	...
1023630651b7Scgd} *n1, *n2, *np;
1024630651b7Scgd
102501869ca4SwizTAILQ_INIT(&head);			/* Initialize the queue. */
1026630651b7Scgd
1027630651b7Scgdn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
102801869ca4SwizTAILQ_INSERT_HEAD(&head, n1, entries);
1029630651b7Scgd
1030630651b7Scgdn1 = malloc(sizeof(struct entry));	/* Insert at the tail. */
103101869ca4SwizTAILQ_INSERT_TAIL(&head, n1, entries);
1032630651b7Scgd
1033630651b7Scgdn2 = malloc(sizeof(struct entry));	/* Insert after. */
103401869ca4SwizTAILQ_INSERT_AFTER(&head, n1, n2, entries);
103573a1524aSmycroft
103673a1524aSmycroftn2 = malloc(sizeof(struct entry));	/* Insert before. */
103773a1524aSmycroftTAILQ_INSERT_BEFORE(n1, n2, entries);
1038318922f0Sryoon
103901869ca4SwizTAILQ_FOREACH(np, &head, entries)	/* Forward traversal. */
104001869ca4Swiz	np-> ...
10414c51b74bSdeberg					/* Reverse traversal. */
104201869ca4SwizTAILQ_FOREACH_REVERSE(np, &head, tailhead, entries)
104301869ca4Swiz	np-> ...
1044318922f0Sryoon
104501869ca4Swizwhile (TAILQ_FIRST(&head) != NULL)	/* Delete. */
104601869ca4Swiz	TAILQ_REMOVE(&head, TAILQ_FIRST(&head), entries);
104701869ca4Swizif (TAILQ_EMPTY(&head))			/* Test for emptiness. */
104889e229d9Smycroft	printf("nothing to do\\n");
1049630651b7Scgd.Ed
105082164e46Schristos.Sh SINGLY LINKED TAIL QUEUES
105182164e46SchristosThe macros prefixed with
10520604df8aSabhinav.Do Nm STAILQ_ Dc (
10530604df8aSabhinav.Fn STAILQ_HEAD ,
10540604df8aSabhinav.Fn STAILQ_HEAD_INITIALIZER ,
10550604df8aSabhinav.Fn STAILQ_ENTRY ,
10560604df8aSabhinav.Fn STAILQ_FOREACH ,
10570604df8aSabhinav.Fn STAILQ_FOREACH_SAFE ,
10580604df8aSabhinav.Fn STAILQ_FIRST ,
10590604df8aSabhinav.Fn STAILQ_EMPTY ,
10600604df8aSabhinav.Fn STAILQ_NEXT ,
10610604df8aSabhinav.Fn STAILQ_LAST ,
10620604df8aSabhinav.Fn STAILQ_INIT ,
10630604df8aSabhinav.Fn STAILQ_INSERT_HEAD ,
10640604df8aSabhinav.Fn STAILQ_INSERT_TAIL ,
10650604df8aSabhinav.Fn STAILQ_INSERT_AFTER ,
10660604df8aSabhinav.Fn STAILQ_REMOVE_HEAD ,
10670604df8aSabhinav.Fn STAILQ_REMOVE ,
106882164e46Schristosand
10690604df8aSabhinav.Fn STAILQ_CONCAT )
107082164e46Schristosare functionally identical to these simple queue functions,
107182164e46Schristosand are provided for compatibility with
107282164e46Schristos.Fx .
10733fa869bcSapb.Sh NOTES
10743fa869bcSapbSome of these macros or functions perform no error checking,
10753fa869bcSapband invalid usage leads to undefined behaviour.
10763fa869bcSapbIn the case of macros or functions that expect their arguments
10773fa869bcSapbto be elements that are present in the list or queue, passing an element
10783fa869bcSapbthat is not present is invalid.
1079630651b7Scgd.Sh HISTORY
1080630651b7ScgdThe
1081630651b7Scgd.Nm queue
108234a98169Sperryfunctions first appeared in
108334a98169Sperry.Bx 4.4 .
108468727e36SchristosThe
108568727e36Schristos.Nm SIMPLEQ
108668727e36Schristosfunctions first appeared in
108768727e36Schristos.Nx 1.2 .
1088d729cba0SpookaThe
1089d729cba0Spooka.Nm SLIST
10902f6ed1a8Slukemand
10912f6ed1a8Slukem.Nm STAILQ
1092d729cba0Spookafunctions first appeared in
1093d729cba0Spooka.Fx 2.1.5 .
1094*7ba76359Skamil.Pp
1095*7ba76359SkamilThe
1096*7ba76359Skamil.Nm CIRCLEQ
1097*7ba76359Skamilfunctions first appeared in
1098*7ba76359Skamil.Bx 4.4
1099*7ba76359Skamiland were deprecated in
1100*7ba76359Skamil.Nx 7
1101*7ba76359Skamiland removed in
1102*7ba76359Skamil.Nx 10
1103*7ba76359Skamildue to the pointer aliasing violations.
1104