xref: /freebsd/share/man/man3/queue.3 (revision d6c6381834a4a6a87809b9ed2e03e553acf16de1)
1afe61c15SRodney W. Grimes.\" Copyright (c) 1993
2afe61c15SRodney W. Grimes.\"	The Regents of the University of California.  All rights reserved.
3afe61c15SRodney W. Grimes.\"
4afe61c15SRodney W. Grimes.\" Redistribution and use in source and binary forms, with or without
5afe61c15SRodney W. Grimes.\" modification, are permitted provided that the following conditions
6afe61c15SRodney W. Grimes.\" are met:
7afe61c15SRodney W. Grimes.\" 1. Redistributions of source code must retain the above copyright
8afe61c15SRodney W. Grimes.\"    notice, this list of conditions and the following disclaimer.
9afe61c15SRodney W. Grimes.\" 2. Redistributions in binary form must reproduce the above copyright
10afe61c15SRodney W. Grimes.\"    notice, this list of conditions and the following disclaimer in the
11afe61c15SRodney W. Grimes.\"    documentation and/or other materials provided with the distribution.
12afe61c15SRodney W. Grimes.\" 3. All advertising materials mentioning features or use of this software
13afe61c15SRodney W. Grimes.\"    must display the following acknowledgement:
14afe61c15SRodney W. Grimes.\"	This product includes software developed by the University of
15afe61c15SRodney W. Grimes.\"	California, Berkeley and its contributors.
16afe61c15SRodney W. Grimes.\" 4. Neither the name of the University nor the names of its contributors
17afe61c15SRodney W. Grimes.\"    may be used to endorse or promote products derived from this software
18afe61c15SRodney W. Grimes.\"    without specific prior written permission.
19afe61c15SRodney W. Grimes.\"
20afe61c15SRodney W. Grimes.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21afe61c15SRodney W. Grimes.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22afe61c15SRodney W. Grimes.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23afe61c15SRodney W. Grimes.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24afe61c15SRodney W. Grimes.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25afe61c15SRodney W. Grimes.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26afe61c15SRodney W. Grimes.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27afe61c15SRodney W. Grimes.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28afe61c15SRodney W. Grimes.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29afe61c15SRodney W. Grimes.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30afe61c15SRodney W. Grimes.\" SUCH DAMAGE.
31afe61c15SRodney W. Grimes.\"
32afe61c15SRodney W. Grimes.\"	@(#)queue.3	8.2 (Berkeley) 1/24/94
337f3dea24SPeter Wemm.\" $FreeBSD$
34afe61c15SRodney W. Grimes.\"
35d3df5ce1SMike Pritchard.Dd January 24, 1994
36afe61c15SRodney W. Grimes.Dt QUEUE 3
37afe61c15SRodney W. Grimes.Os BSD 4
38afe61c15SRodney W. Grimes.Sh NAME
39aea88892SPoul-Henning Kamp.Nm SLIST_EMPTY ,
404a775e8fSJustin T. Gibbs.Nm SLIST_ENTRY ,
41aea88892SPoul-Henning Kamp.Nm SLIST_FIRST ,
4279ea9bc4SAlexey Zelkin.Nm SLIST_FOREACH ,
434a775e8fSJustin T. Gibbs.Nm SLIST_HEAD ,
4403763fe0SJake Burkholder.Nm SLIST_HEAD_INITIALIZER ,
454a775e8fSJustin T. Gibbs.Nm SLIST_INIT ,
464a775e8fSJustin T. Gibbs.Nm SLIST_INSERT_AFTER ,
474a775e8fSJustin T. Gibbs.Nm SLIST_INSERT_HEAD ,
48aea88892SPoul-Henning Kamp.Nm SLIST_NEXT ,
494a775e8fSJustin T. Gibbs.Nm SLIST_REMOVE_HEAD ,
504a775e8fSJustin T. Gibbs.Nm SLIST_REMOVE ,
5179ea9bc4SAlexey Zelkin.Nm STAILQ_EMPTY ,
524a775e8fSJustin T. Gibbs.Nm STAILQ_ENTRY ,
5379ea9bc4SAlexey Zelkin.Nm STAILQ_FIRST ,
5479ea9bc4SAlexey Zelkin.Nm STAILQ_FOREACH ,
554a775e8fSJustin T. Gibbs.Nm STAILQ_HEAD ,
5603763fe0SJake Burkholder.Nm STAILQ_HEAD_INITIALIZER ,
574a775e8fSJustin T. Gibbs.Nm STAILQ_INIT ,
584a775e8fSJustin T. Gibbs.Nm STAILQ_INSERT_AFTER ,
594a775e8fSJustin T. Gibbs.Nm STAILQ_INSERT_HEAD ,
604a775e8fSJustin T. Gibbs.Nm STAILQ_INSERT_TAIL ,
6179ea9bc4SAlexey Zelkin.Nm STAILQ_LAST ,
6279ea9bc4SAlexey Zelkin.Nm STAILQ_NEXT ,
634a775e8fSJustin T. Gibbs.Nm STAILQ_REMOVE_HEAD ,
644a775e8fSJustin T. Gibbs.Nm STAILQ_REMOVE ,
6579ea9bc4SAlexey Zelkin.Nm LIST_EMPTY ,
66afe61c15SRodney W. Grimes.Nm LIST_ENTRY ,
6779ea9bc4SAlexey Zelkin.Nm LIST_FIRST ,
6879ea9bc4SAlexey Zelkin.Nm LIST_FOREACH ,
69afe61c15SRodney W. Grimes.Nm LIST_HEAD ,
7003763fe0SJake Burkholder.Nm LIST_HEAD_INITIALIZER ,
71afe61c15SRodney W. Grimes.Nm LIST_INIT ,
72afe61c15SRodney W. Grimes.Nm LIST_INSERT_AFTER ,
737658b0a2SJustin T. Gibbs.Nm LIST_INSERT_BEFORE ,
74afe61c15SRodney W. Grimes.Nm LIST_INSERT_HEAD ,
7579ea9bc4SAlexey Zelkin.Nm LIST_NEXT ,
76afe61c15SRodney W. Grimes.Nm LIST_REMOVE ,
77c5c15c16SPoul-Henning Kamp.Nm TAILQ_EMPTY ,
78afe61c15SRodney W. Grimes.Nm TAILQ_ENTRY ,
79c5c15c16SPoul-Henning Kamp.Nm TAILQ_FIRST ,
8079ea9bc4SAlexey Zelkin.Nm TAILQ_FOREACH ,
816c1d0fbfSArchie Cobbs.Nm TAILQ_FOREACH_REVERSE ,
82afe61c15SRodney W. Grimes.Nm TAILQ_HEAD ,
8303763fe0SJake Burkholder.Nm TAILQ_HEAD_INITIALIZER ,
84afe61c15SRodney W. Grimes.Nm TAILQ_INIT ,
85afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_AFTER ,
867658b0a2SJustin T. Gibbs.Nm TAILQ_INSERT_BEFORE ,
87afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_HEAD ,
88afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_TAIL ,
89c5c15c16SPoul-Henning Kamp.Nm TAILQ_LAST ,
90c5c15c16SPoul-Henning Kamp.Nm TAILQ_NEXT ,
9179ea9bc4SAlexey Zelkin.Nm TAILQ_PREV ,
92afe61c15SRodney W. Grimes.Nm TAILQ_REMOVE ,
9379ea9bc4SAlexey Zelkin.Nm CIRCLEQ_EMPTY ,
94afe61c15SRodney W. Grimes.Nm CIRCLEQ_ENTRY ,
9579ea9bc4SAlexey Zelkin.Nm CIRCLEQ_FIRST ,
9679ea9bc4SAlexey Zelkin.Nm CIRCLEQ_FOREACH ,
976c1d0fbfSArchie Cobbs.Nm CIRCLEQ_FOREACH_REVERSE ,
98afe61c15SRodney W. Grimes.Nm CIRCLEQ_HEAD ,
9903763fe0SJake Burkholder.Nm CIRCLEQ_HEAD_INITIALIZER ,
100afe61c15SRodney W. Grimes.Nm CIRCLEQ_INIT ,
101afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_AFTER ,
102afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_BEFORE ,
103afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_HEAD ,
104afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_TAIL ,
10579ea9bc4SAlexey Zelkin.Nm CIRCLE_LAST ,
10679ea9bc4SAlexey Zelkin.Nm CIRCLE_NEXT ,
10779ea9bc4SAlexey Zelkin.Nm CIRCLE_PREV ,
108afe61c15SRodney W. Grimes.Nm CIRCLEQ_REMOVE
1094a775e8fSJustin T. Gibbs.Nd implementations of singly-linked lists, singly-linked tail queues,
1104a775e8fSJustin T. Gibbslists, tail queues, and circular queues
111afe61c15SRodney W. Grimes.Sh SYNOPSIS
112afe61c15SRodney W. Grimes.Fd #include <sys/queue.h>
1138f20a914SMike Pritchard.\"
114aea88892SPoul-Henning Kamp.Fn SLIST_EMPTY "SLIST_HEAD *head"
1154a775e8fSJustin T. Gibbs.Fn SLIST_ENTRY "TYPE"
116aea88892SPoul-Henning Kamp.Fn SLIST_FIRST "SLIST_HEAD *head"
11779ea9bc4SAlexey Zelkin.Fn SLIST_FOREACH "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME"
1184a775e8fSJustin T. Gibbs.Fn SLIST_HEAD "HEADNAME" "TYPE"
11903763fe0SJake Burkholder.Fn SLIST_HEAD_INITIALIZER "SLIST_HEAD head"
1204a775e8fSJustin T. Gibbs.Fn SLIST_INIT "SLIST_HEAD *head"
1214a775e8fSJustin T. Gibbs.Fn SLIST_INSERT_AFTER "TYPE *listelm" "TYPE *elm" "SLIST_ENTRY NAME"
1224a775e8fSJustin T. Gibbs.Fn SLIST_INSERT_HEAD "SLIST_HEAD *head" "TYPE *elm" "SLIST_ENTRY NAME"
123aea88892SPoul-Henning Kamp.Fn SLIST_NEXT "TYPE *elm" "SLIST_ENTRY NAME"
1244a775e8fSJustin T. Gibbs.Fn SLIST_REMOVE_HEAD "SLIST_HEAD *head" "SLIST_ENTRY NAME"
1254a775e8fSJustin T. Gibbs.Fn SLIST_REMOVE "SLIST_HEAD *head" "TYPE *elm" "TYPE" "SLIST_ENTRY NAME"
1268f20a914SMike Pritchard.\"
12779ea9bc4SAlexey Zelkin.Fn STAILQ_EMPTY "STAILQ_HEAD *head"
1284a775e8fSJustin T. Gibbs.Fn STAILQ_ENTRY "TYPE"
12979ea9bc4SAlexey Zelkin.Fn STAILQ_FIRST "STAILQ_HEAD *head"
13079ea9bc4SAlexey Zelkin.Fn STAILQ_FOREACH "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME"
1314a775e8fSJustin T. Gibbs.Fn STAILQ_HEAD "HEADNAME" "TYPE"
13203763fe0SJake Burkholder.Fn STAILQ_HEAD_INITIALIZER "STAILQ_HEAD head"
1334a775e8fSJustin T. Gibbs.Fn STAILQ_INIT "STAILQ_HEAD *head"
1344a775e8fSJustin T. Gibbs.Fn STAILQ_INSERT_AFTER "STAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "STAILQ_ENTRY NAME"
1354a775e8fSJustin T. Gibbs.Fn STAILQ_INSERT_HEAD "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
1364a775e8fSJustin T. Gibbs.Fn STAILQ_INSERT_TAIL "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
13779ea9bc4SAlexey Zelkin.Fn STAILQ_LAST "STAILQ_HEAD *head"
13879ea9bc4SAlexey Zelkin.Fn STAILQ_NEXT "TYPE *elm" "STAILQ_ENTRY NAME"
13902a98699SBruce Evans.Fn STAILQ_REMOVE_HEAD "STAILQ_HEAD *head" "STAILQ_ENTRY NAME"
1404a775e8fSJustin T. Gibbs.Fn STAILQ_REMOVE "STAILQ_HEAD *head" "TYPE *elm" "TYPE" "STAILQ_ENTRY NAME"
1418f20a914SMike Pritchard.\"
14279ea9bc4SAlexey Zelkin.Fn LIST_EMPTY "LIST_HEAD *head"
143afe61c15SRodney W. Grimes.Fn LIST_ENTRY "TYPE"
14479ea9bc4SAlexey Zelkin.Fn LIST_FIRST "LIST_HEAD *head"
14579ea9bc4SAlexey Zelkin.Fn LIST_FOREACH "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME"
146afe61c15SRodney W. Grimes.Fn LIST_HEAD "HEADNAME" "TYPE"
14703763fe0SJake Burkholder.Fn LIST_HEAD_INITIALIZER "LIST_HEAD head"
148afe61c15SRodney W. Grimes.Fn LIST_INIT "LIST_HEAD *head"
1494a775e8fSJustin T. Gibbs.Fn LIST_INSERT_AFTER "TYPE *listelm" "TYPE *elm" "LIST_ENTRY NAME"
1504a775e8fSJustin T. Gibbs.Fn LIST_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "LIST_ENTRY NAME"
151afe61c15SRodney W. Grimes.Fn LIST_INSERT_HEAD "LIST_HEAD *head" "TYPE *elm" "LIST_ENTRY NAME"
15279ea9bc4SAlexey Zelkin.Fn LIST_NEXT "TYPE *elm" "LIST_ENTRY NAME"
153afe61c15SRodney W. Grimes.Fn LIST_REMOVE "TYPE *elm" "LIST_ENTRY NAME"
1548f20a914SMike Pritchard.\"
155c5c15c16SPoul-Henning Kamp.Fn TAILQ_EMPTY "TAILQ_HEAD *head"
156afe61c15SRodney W. Grimes.Fn TAILQ_ENTRY "TYPE"
157c5c15c16SPoul-Henning Kamp.Fn TAILQ_FIRST "TAILQ_HEAD *head"
15879ea9bc4SAlexey Zelkin.Fn TAILQ_FOREACH "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME"
1596c1d0fbfSArchie Cobbs.Fn TAILQ_FOREACH_REVERSE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME"
160afe61c15SRodney W. Grimes.Fn TAILQ_HEAD "HEADNAME" "TYPE"
16103763fe0SJake Burkholder.Fn TAILQ_HEAD_INITIALIZER "TAILQ_HEAD head"
162afe61c15SRodney W. Grimes.Fn TAILQ_INIT "TAILQ_HEAD *head"
163afe61c15SRodney W. Grimes.Fn TAILQ_INSERT_AFTER "TAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME"
1643652ff55SJustin T. Gibbs.Fn TAILQ_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME"
165afe61c15SRodney W. Grimes.Fn TAILQ_INSERT_HEAD "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
166afe61c15SRodney W. Grimes.Fn TAILQ_INSERT_TAIL "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
16779ea9bc4SAlexey Zelkin.Fn TAILQ_LAST "TAILQ_HEAD *head" "HEADNAME"
168c5c15c16SPoul-Henning Kamp.Fn TAILQ_NEXT "TYPE *elm" "TAILQ_ENTRY NAME"
16979ea9bc4SAlexey Zelkin.Fn TAILQ_PREV "TYPE *elm" "HEADNAME" "TAILQ_ENTRY NAME"
170afe61c15SRodney W. Grimes.Fn TAILQ_REMOVE "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
1718f20a914SMike Pritchard.\"
17279ea9bc4SAlexey Zelkin.Fn CIRCLEQ_EMPTY "CIRCLEQ_HEAD *head"
173afe61c15SRodney W. Grimes.Fn CIRCLEQ_ENTRY "TYPE"
17479ea9bc4SAlexey Zelkin.Fn CIRCLEQ_FIRST "CIRCLEQ_HEAD *head"
17579ea9bc4SAlexey Zelkin.Fn CIRCLEQ_FOREACH "TYPE *var" "CIRCLEQ_HEAD *head" "CIRCLEQ_ENTRY NAME"
1766c1d0fbfSArchie Cobbs.Fn CIRCLEQ_FOREACH_REVERSE "TYPE *var" "CIRCLEQ_HEAD *head" "CIRCLEQ_ENTRY NAME"
177afe61c15SRodney W. Grimes.Fn CIRCLEQ_HEAD "HEADNAME" "TYPE"
17803763fe0SJake Burkholder.Fn CIRCLEQ_HEAD_INITIALIZER "CIRCLEQ_HEAD head"
179afe61c15SRodney W. Grimes.Fn CIRCLEQ_INIT "CIRCLEQ_HEAD *head"
180afe61c15SRodney W. Grimes.Fn CIRCLEQ_INSERT_AFTER "CIRCLEQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
181afe61c15SRodney W. Grimes.Fn CIRCLEQ_INSERT_BEFORE "CIRCLEQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
182afe61c15SRodney W. Grimes.Fn CIRCLEQ_INSERT_HEAD "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
183afe61c15SRodney W. Grimes.Fn CIRCLEQ_INSERT_TAIL "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
18479ea9bc4SAlexey Zelkin.Fn CIRCLEQ_LAST "CIRCLEQ_HEAD *head"
18579ea9bc4SAlexey Zelkin.Fn CIRCLEQ_NEXT "TYPE *elm" "CIRCLEQ_ENTRY NAME"
18679ea9bc4SAlexey Zelkin.Fn CIRCLE_PREV "TYPE *elm" "CIRCLEQ_ENTRY NAME"
187afe61c15SRodney W. Grimes.Fn CIRCLEQ_REMOVE "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
188afe61c15SRodney W. Grimes.Sh DESCRIPTION
1894a775e8fSJustin T. GibbsThese macros define and operate on five types of data structures:
1904a775e8fSJustin T. Gibbssingly-linked lists, singly-linked tail queues, lists, tail queues,
1914a775e8fSJustin T. Gibbsand circular queues.
1924a775e8fSJustin T. GibbsAll five structures support the following functionality:
193afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
194afe61c15SRodney W. Grimes.It
195afe61c15SRodney W. GrimesInsertion of a new entry at the head of the list.
196afe61c15SRodney W. Grimes.It
197afe61c15SRodney W. GrimesInsertion of a new entry after any element in the list.
198afe61c15SRodney W. Grimes.It
1994a775e8fSJustin T. GibbsO(1) removal of an entry from the head of the list.
2007658b0a2SJustin T. Gibbs.It
2014a775e8fSJustin T. GibbsO(n) removal of any entry in the list.
202afe61c15SRodney W. Grimes.It
203afe61c15SRodney W. GrimesForward traversal through the list.
204afe61c15SRodney W. Grimes.El
205afe61c15SRodney W. Grimes.Pp
2064a775e8fSJustin T. GibbsSingly-linked lists are the simplest of the five data structures
2074a775e8fSJustin T. Gibbsand support only the above functionality.
2084a775e8fSJustin T. GibbsSingly-linked lists are ideal for applications with large datasets
2094a775e8fSJustin T. Gibbsand few or no removals,
2104a775e8fSJustin T. Gibbsor for implementing a LIFO queue.
2114a775e8fSJustin T. Gibbs.Pp
2124a775e8fSJustin T. GibbsSingly-linked tail queues add the following functionality:
2134a775e8fSJustin T. Gibbs.Bl -enum -compact -offset indent
2144a775e8fSJustin T. Gibbs.It
2154a775e8fSJustin T. GibbsEntries can be added at the end of a list.
2164a775e8fSJustin T. Gibbs.El
2174a775e8fSJustin T. GibbsHowever:
2184a775e8fSJustin T. Gibbs.Bl -enum -compact -offset indent
2194a775e8fSJustin T. Gibbs.It
2204a775e8fSJustin T. GibbsAll list insertions must specify the head of the list.
2214a775e8fSJustin T. Gibbs.It
2224a775e8fSJustin T. GibbsEach head entry requires two pointers rather than one.
2234a775e8fSJustin T. Gibbs.It
2244a775e8fSJustin T. GibbsCode size is about 15% greater and operations run about 20% slower
2254a775e8fSJustin T. Gibbsthan singly-linked lists.
2264a775e8fSJustin T. Gibbs.El
2274a775e8fSJustin T. Gibbs.Pp
2284a775e8fSJustin T. GibbsSingly-linked tailqs are ideal for applications with large datasets and
2294a775e8fSJustin T. Gibbsfew or no removals,
2304a775e8fSJustin T. Gibbsor for implementing a FIFO queue.
2314a775e8fSJustin T. Gibbs.Pp
2324a775e8fSJustin T. GibbsAll doubly linked types of data structures (lists, tail queues, and circle
2334a775e8fSJustin T. Gibbsqueues) additionally allow:
2344a775e8fSJustin T. Gibbs.Bl -enum -compact -offset indent
2354a775e8fSJustin T. Gibbs.It
2364a775e8fSJustin T. GibbsInsertion of a new entry before any element in the list.
2374a775e8fSJustin T. Gibbs.It
2384a775e8fSJustin T. GibbsO(1) removal of any entry in the list.
2394a775e8fSJustin T. Gibbs.El
2404a775e8fSJustin T. GibbsHowever:
2414a775e8fSJustin T. Gibbs.Bl -enum -compact -offset indent
2424a775e8fSJustin T. Gibbs.It
2434a775e8fSJustin T. GibbsEach elements requires two pointers rather than one.
2444a775e8fSJustin T. Gibbs.It
2454a775e8fSJustin T. GibbsCode size and execution time of operations (except for removal) is about
2464a775e8fSJustin T. Gibbstwice that of the singly-linked data-structures.
2474a775e8fSJustin T. Gibbs.El
2484a775e8fSJustin T. Gibbs.Pp
2494a775e8fSJustin T. GibbsLinked lists are the simplest of the doubly linked data structures and support
2504a775e8fSJustin T. Gibbsonly the above functionality over singly-linked lists.
251afe61c15SRodney W. Grimes.Pp
252afe61c15SRodney W. GrimesTail queues add the following functionality:
253afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
254afe61c15SRodney W. Grimes.It
255afe61c15SRodney W. GrimesEntries can be added at the end of a list.
2566c1d0fbfSArchie Cobbs.It
2576c1d0fbfSArchie CobbsThey may be traversed backwards, from tail to head.
258afe61c15SRodney W. Grimes.El
259afe61c15SRodney W. GrimesHowever:
260afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
261afe61c15SRodney W. Grimes.It
262afe61c15SRodney W. GrimesAll list insertions and removals must specify the head of the list.
263afe61c15SRodney W. Grimes.It
264afe61c15SRodney W. GrimesEach head entry requires two pointers rather than one.
265afe61c15SRodney W. Grimes.It
266afe61c15SRodney W. GrimesCode size is about 15% greater and operations run about 20% slower
2674a775e8fSJustin T. Gibbsthan singly-linked lists.
268afe61c15SRodney W. Grimes.El
269afe61c15SRodney W. Grimes.Pp
270afe61c15SRodney W. GrimesCircular queues add the following functionality:
271afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
272afe61c15SRodney W. Grimes.It
273afe61c15SRodney W. GrimesEntries can be added at the end of a list.
274afe61c15SRodney W. Grimes.It
275afe61c15SRodney W. GrimesThey may be traversed backwards, from tail to head.
276afe61c15SRodney W. Grimes.El
277afe61c15SRodney W. GrimesHowever:
278afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
279afe61c15SRodney W. Grimes.It
280afe61c15SRodney W. GrimesAll list insertions and removals must specify the head of the list.
281afe61c15SRodney W. Grimes.It
282afe61c15SRodney W. GrimesEach head entry requires two pointers rather than one.
283afe61c15SRodney W. Grimes.It
284afe61c15SRodney W. GrimesThe termination condition for traversal is more complex.
285afe61c15SRodney W. Grimes.It
286afe61c15SRodney W. GrimesCode size is about 40% greater and operations run about 45% slower
287afe61c15SRodney W. Grimesthan lists.
288afe61c15SRodney W. Grimes.El
289afe61c15SRodney W. Grimes.Pp
290afe61c15SRodney W. GrimesIn the macro definitions,
291afe61c15SRodney W. Grimes.Fa TYPE
292afe61c15SRodney W. Grimesis the name of a user defined structure,
293afe61c15SRodney W. Grimesthat must contain a field of type
2944a775e8fSJustin T. Gibbs.Li SLIST_ENTRY ,
2954a775e8fSJustin T. Gibbs.Li STAILQ_ENTRY ,
296afe61c15SRodney W. Grimes.Li LIST_ENTRY ,
297afe61c15SRodney W. Grimes.Li TAILQ_ENTRY ,
298afe61c15SRodney W. Grimesor
299afe61c15SRodney W. Grimes.Li CIRCLEQ_ENTRY ,
300afe61c15SRodney W. Grimesnamed
301afe61c15SRodney W. Grimes.Fa NAME .
302afe61c15SRodney W. GrimesThe argument
303afe61c15SRodney W. Grimes.Fa HEADNAME
304afe61c15SRodney W. Grimesis the name of a user defined structure that must be declared
305afe61c15SRodney W. Grimesusing the macros
3064a775e8fSJustin T. Gibbs.Li SLIST_HEAD ,
3074a775e8fSJustin T. Gibbs.Li STAILQ_HEAD ,
308afe61c15SRodney W. Grimes.Li LIST_HEAD ,
309afe61c15SRodney W. Grimes.Li TAILQ_HEAD ,
310afe61c15SRodney W. Grimesor
311afe61c15SRodney W. Grimes.Li CIRCLEQ_HEAD .
312afe61c15SRodney W. GrimesSee the examples below for further explanation of how these
313afe61c15SRodney W. Grimesmacros are used.
3144a775e8fSJustin T. Gibbs.Sh SINGLY-LINKED LISTS
3154a775e8fSJustin T. GibbsA singly-linked list is headed by a structure defined by the
3164a775e8fSJustin T. Gibbs.Nm SLIST_HEAD
3174a775e8fSJustin T. Gibbsmacro.
3184a775e8fSJustin T. GibbsThis structure contains a single pointer to the first element
3194a775e8fSJustin T. Gibbson the list.
3204a775e8fSJustin T. GibbsThe elements are singly linked for minimum space and pointer manipulation
3214a775e8fSJustin T. Gibbsoverhead at the expense of O(n) removal for arbitrary elements.
3224a775e8fSJustin T. GibbsNew elements can be added to the list after an existing element or
3234a775e8fSJustin T. Gibbsat the head of the list.
3244a775e8fSJustin T. GibbsAn
3254a775e8fSJustin T. Gibbs.Fa SLIST_HEAD
3264a775e8fSJustin T. Gibbsstructure is declared as follows:
3274a775e8fSJustin T. Gibbs.Bd -literal -offset indent
3284a775e8fSJustin T. GibbsSLIST_HEAD(HEADNAME, TYPE) head;
3294a775e8fSJustin T. Gibbs.Ed
3308f20a914SMike Pritchard.Pp
3314a775e8fSJustin T. Gibbswhere
3324a775e8fSJustin T. Gibbs.Fa HEADNAME
3334a775e8fSJustin T. Gibbsis the name of the structure to be defined, and
3344a775e8fSJustin T. Gibbs.Fa TYPE
3354a775e8fSJustin T. Gibbsis the type of the elements to be linked into the list.
3364a775e8fSJustin T. GibbsA pointer to the head of the list can later be declared as:
3374a775e8fSJustin T. Gibbs.Bd -literal -offset indent
3384a775e8fSJustin T. Gibbsstruct HEADNAME *headp;
3394a775e8fSJustin T. Gibbs.Ed
3408f20a914SMike Pritchard.Pp
3414a775e8fSJustin T. Gibbs(The names
3424a775e8fSJustin T. Gibbs.Li head
3434a775e8fSJustin T. Gibbsand
3444a775e8fSJustin T. Gibbs.Li headp
3454a775e8fSJustin T. Gibbsare user selectable.)
3464a775e8fSJustin T. Gibbs.Pp
3474a775e8fSJustin T. GibbsThe macro
34803763fe0SJake Burkholder.Nm SLIST_HEAD_INITIALIZER
34903763fe0SJake Burkholderevaluates to an initializer for the list
35003763fe0SJake Burkholder.Fa head .
35103763fe0SJake Burkholder.Pp
35203763fe0SJake BurkholderThe macro
35379ea9bc4SAlexey Zelkin.Nm SLIST_EMPTY
35479ea9bc4SAlexey Zelkinevaluates to true if there are no elements in the list.
35579ea9bc4SAlexey Zelkin.Pp
35679ea9bc4SAlexey ZelkinThe macro
3574a775e8fSJustin T. Gibbs.Nm SLIST_ENTRY
3584a775e8fSJustin T. Gibbsdeclares a structure that connects the elements in
3594a775e8fSJustin T. Gibbsthe list.
3604a775e8fSJustin T. Gibbs.Pp
3614a775e8fSJustin T. GibbsThe macro
36279ea9bc4SAlexey Zelkin.Nm SLIST_FIRST
36379ea9bc4SAlexey Zelkinreturns the first element in the list or NULL if the list is empty.
36479ea9bc4SAlexey Zelkin.Pp
36579ea9bc4SAlexey ZelkinThe macro
36679ea9bc4SAlexey Zelkin.Nm SLIST_FOREACH
36779ea9bc4SAlexey Zelkintraverses the list referenced by
36879ea9bc4SAlexey Zelkin.Fa head
36979ea9bc4SAlexey Zelkinin the forward direction, assigning each element in
37079ea9bc4SAlexey Zelkinturn to
37179ea9bc4SAlexey Zelkin.Fa var .
37279ea9bc4SAlexey Zelkin.Pp
37379ea9bc4SAlexey ZelkinThe macro
3744a775e8fSJustin T. Gibbs.Nm SLIST_INIT
3754a775e8fSJustin T. Gibbsinitializes the list referenced by
3764a775e8fSJustin T. Gibbs.Fa head .
3774a775e8fSJustin T. Gibbs.Pp
3784a775e8fSJustin T. GibbsThe macro
3794a775e8fSJustin T. Gibbs.Nm SLIST_INSERT_HEAD
3804a775e8fSJustin T. Gibbsinserts the new element
3814a775e8fSJustin T. Gibbs.Fa elm
3824a775e8fSJustin T. Gibbsat the head of the list.
3834a775e8fSJustin T. Gibbs.Pp
3844a775e8fSJustin T. GibbsThe macro
3854a775e8fSJustin T. Gibbs.Nm SLIST_INSERT_AFTER
3864a775e8fSJustin T. Gibbsinserts the new element
3874a775e8fSJustin T. Gibbs.Fa elm
3884a775e8fSJustin T. Gibbsafter the element
3894a775e8fSJustin T. Gibbs.Fa listelm .
3904a775e8fSJustin T. Gibbs.Pp
3914a775e8fSJustin T. GibbsThe macro
39279ea9bc4SAlexey Zelkin.Nm SLIST_NEXT
39379ea9bc4SAlexey Zelkinreturns the next element in the list.
39479ea9bc4SAlexey Zelkin.Pp
39579ea9bc4SAlexey ZelkinThe macro
3964a775e8fSJustin T. Gibbs.Nm SLIST_REMOVE_HEAD
3974a775e8fSJustin T. Gibbsremoves the element
3984a775e8fSJustin T. Gibbs.Fa elm
3994a775e8fSJustin T. Gibbsfrom the head of the list.
4004a775e8fSJustin T. GibbsFor optimum efficiency,
4014a775e8fSJustin T. Gibbselements being removed from the head of the list should explicitly use
4024a775e8fSJustin T. Gibbsthis macro instead of the generic
4034a775e8fSJustin T. Gibbs.Fa SLIST_REMOVE
4044a775e8fSJustin T. Gibbsmacro.
4054a775e8fSJustin T. Gibbs.Pp
4064a775e8fSJustin T. GibbsThe macro
4074a775e8fSJustin T. Gibbs.Nm SLIST_REMOVE
4084a775e8fSJustin T. Gibbsremoves the element
4094a775e8fSJustin T. Gibbs.Fa elm
4104a775e8fSJustin T. Gibbsfrom the list.
4114a775e8fSJustin T. Gibbs.Sh SINGLY-LINKED LIST EXAMPLE
4124a775e8fSJustin T. Gibbs.Bd -literal
41303763fe0SJake BurkholderSLIST_HEAD(slisthead, entry) head =
41403763fe0SJake Burkholder    SLIST_HEAD_INITIALIZER(head);
4154a775e8fSJustin T. Gibbsstruct slisthead *headp;		/* Singly-linked List head. */
4164a775e8fSJustin T. Gibbsstruct entry {
4174a775e8fSJustin T. Gibbs	...
4184a775e8fSJustin T. Gibbs	SLIST_ENTRY(entry) entries;	/* Singly-linked List. */
4194a775e8fSJustin T. Gibbs	...
4204a775e8fSJustin T. Gibbs} *n1, *n2, *n3, *np;
4214a775e8fSJustin T. Gibbs
4224a775e8fSJustin T. GibbsSLIST_INIT(&head);			/* Initialize the list. */
4234a775e8fSJustin T. Gibbs
4244a775e8fSJustin T. Gibbsn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
4254a775e8fSJustin T. GibbsSLIST_INSERT_HEAD(&head, n1, entries);
4264a775e8fSJustin T. Gibbs
4274a775e8fSJustin T. Gibbsn2 = malloc(sizeof(struct entry));	/* Insert after. */
4284a775e8fSJustin T. GibbsSLIST_INSERT_AFTER(n1, n2, entries);
4294a775e8fSJustin T. Gibbs
4304a775e8fSJustin T. GibbsSLIST_REMOVE(&head, n2, entry, entries);/* Deletion. */
4314a775e8fSJustin T. Gibbsfree(n2);
4324a775e8fSJustin T. Gibbs
43379ea9bc4SAlexey Zelkinn3 = SLIST_FIRST(&head);
43403763fe0SJake BurkholderSLIST_REMOVE_HEAD(&head, entries);	/* Deletion from the head. */
4354a775e8fSJustin T. Gibbsfree(n3);
4364a775e8fSJustin T. Gibbs					/* Forward traversal. */
43779ea9bc4SAlexey ZelkinSLIST_FOREACH(np, &head, entries)
4384a775e8fSJustin T. Gibbs	np-> ...
4394a775e8fSJustin T. Gibbs
44079ea9bc4SAlexey Zelkinwhile (!SLIST_EMPTY(&head)) {		/* List Deletion. */
44179ea9bc4SAlexey Zelkin	n1 = SLIST_FIRST(&head);
4424a775e8fSJustin T. Gibbs	SLIST_REMOVE_HEAD(&head, entries);
4434a775e8fSJustin T. Gibbs	free(n1);
4444a775e8fSJustin T. Gibbs}
4454a775e8fSJustin T. Gibbs.Ed
4464a775e8fSJustin T. Gibbs.Sh SINGLY-LINKED TAIL QUEUES
4474a775e8fSJustin T. GibbsA singly-linked tail queue is headed by a structure defined by the
4484a775e8fSJustin T. Gibbs.Nm STAILQ_HEAD
4494a775e8fSJustin T. Gibbsmacro.
4504a775e8fSJustin T. GibbsThis structure contains a pair of pointers,
4514a775e8fSJustin T. Gibbsone to the first element in the tail queue and the other to
4524a775e8fSJustin T. Gibbsthe last element in the tail queue.
4534a775e8fSJustin T. GibbsThe elements are singly linked for minimum space and pointer
4544a775e8fSJustin T. Gibbsmanipulation overhead at the expense of O(n) removal for arbitrary
4554a775e8fSJustin T. Gibbselements.
4564a775e8fSJustin T. GibbsNew elements can be added to the tail queue after an existing element,
4574a775e8fSJustin T. Gibbsat the head of the tail queue, or at the end of the tail queue.
4584a775e8fSJustin T. GibbsA
4594a775e8fSJustin T. Gibbs.Fa STAILQ_HEAD
4604a775e8fSJustin T. Gibbsstructure is declared as follows:
4614a775e8fSJustin T. Gibbs.Bd -literal -offset indent
4624a775e8fSJustin T. GibbsSTAILQ_HEAD(HEADNAME, TYPE) head;
4634a775e8fSJustin T. Gibbs.Ed
4648f20a914SMike Pritchard.Pp
4654a775e8fSJustin T. Gibbswhere
4664a775e8fSJustin T. Gibbs.Li HEADNAME
4674a775e8fSJustin T. Gibbsis the name of the structure to be defined, and
4684a775e8fSJustin T. Gibbs.Li TYPE
4694a775e8fSJustin T. Gibbsis the type of the elements to be linked into the tail queue.
4704a775e8fSJustin T. GibbsA pointer to the head of the tail queue can later be declared as:
4714a775e8fSJustin T. Gibbs.Bd -literal -offset indent
4724a775e8fSJustin T. Gibbsstruct HEADNAME *headp;
4734a775e8fSJustin T. Gibbs.Ed
4748f20a914SMike Pritchard.Pp
4754a775e8fSJustin T. Gibbs(The names
4764a775e8fSJustin T. Gibbs.Li head
4774a775e8fSJustin T. Gibbsand
4784a775e8fSJustin T. Gibbs.Li headp
4794a775e8fSJustin T. Gibbsare user selectable.)
4804a775e8fSJustin T. Gibbs.Pp
4814a775e8fSJustin T. GibbsThe macro
48203763fe0SJake Burkholder.Nm STAILQ_HEAD_INITIALIZER
48303763fe0SJake Burkholderevaluates to an initializer for the tail queue
48403763fe0SJake Burkholder.Fa head .
48503763fe0SJake Burkholder.Pp
48603763fe0SJake BurkholderThe macro
48779ea9bc4SAlexey Zelkin.Nm STAILQ_EMPTY
48879ea9bc4SAlexey Zelkinevaluates to true if there are no items on the tail queue.
48979ea9bc4SAlexey Zelkin.Pp
49079ea9bc4SAlexey ZelkinThe macro
4914a775e8fSJustin T. Gibbs.Nm STAILQ_ENTRY
4924a775e8fSJustin T. Gibbsdeclares a structure that connects the elements in
4934a775e8fSJustin T. Gibbsthe tail queue.
4944a775e8fSJustin T. Gibbs.Pp
4954a775e8fSJustin T. GibbsThe macro
49679ea9bc4SAlexey Zelkin.Nm STAILQ_FIRST
49779ea9bc4SAlexey Zelkinreturns the first item on the tail queue or NULL if the tail queue
49879ea9bc4SAlexey Zelkinis empty.
49979ea9bc4SAlexey Zelkin.Pp
50079ea9bc4SAlexey ZelkinThe macro
50179ea9bc4SAlexey Zelkin.Nm STAILQ_FOREACH
50279ea9bc4SAlexey Zelkintraverses the tail queue referenced by
50379ea9bc4SAlexey Zelkin.Fa head
50479ea9bc4SAlexey Zelkinin the forward direction, assigning each element
50579ea9bc4SAlexey Zelkinin turn to
50679ea9bc4SAlexey Zelkin.Fa var .
50779ea9bc4SAlexey Zelkin.Pp
50879ea9bc4SAlexey ZelkinThe macro
5094a775e8fSJustin T. Gibbs.Nm STAILQ_INIT
5104a775e8fSJustin T. Gibbsinitializes the tail queue referenced by
5114a775e8fSJustin T. Gibbs.Fa head .
5124a775e8fSJustin T. Gibbs.Pp
5134a775e8fSJustin T. GibbsThe macro
5144a775e8fSJustin T. Gibbs.Nm STAILQ_INSERT_HEAD
5154a775e8fSJustin T. Gibbsinserts the new element
5164a775e8fSJustin T. Gibbs.Fa elm
5174a775e8fSJustin T. Gibbsat the head of the tail queue.
5184a775e8fSJustin T. Gibbs.Pp
5194a775e8fSJustin T. GibbsThe macro
5204a775e8fSJustin T. Gibbs.Nm STAILQ_INSERT_TAIL
5214a775e8fSJustin T. Gibbsinserts the new element
5224a775e8fSJustin T. Gibbs.Fa elm
5234a775e8fSJustin T. Gibbsat the end of the tail queue.
5244a775e8fSJustin T. Gibbs.Pp
5254a775e8fSJustin T. GibbsThe macro
5264a775e8fSJustin T. Gibbs.Nm STAILQ_INSERT_AFTER
5274a775e8fSJustin T. Gibbsinserts the new element
5284a775e8fSJustin T. Gibbs.Fa elm
5294a775e8fSJustin T. Gibbsafter the element
5304a775e8fSJustin T. Gibbs.Fa listelm .
5314a775e8fSJustin T. Gibbs.Pp
5324a775e8fSJustin T. GibbsThe macro
53379ea9bc4SAlexey Zelkin.Nm STAILQ_LAST
53479ea9bc4SAlexey Zelkinreturns the last item on the tail queue.
53579ea9bc4SAlexey ZelkinIf the tail queue is empty the return value is undefined.
53679ea9bc4SAlexey Zelkin.Pp
53779ea9bc4SAlexey ZelkinThe macro
53879ea9bc4SAlexey Zelkin.Nm STAILQ_NEXT
53979ea9bc4SAlexey Zelkinreturns the next item on the tail queue, or NULL this item is the last.
54079ea9bc4SAlexey Zelkin.Pp
54179ea9bc4SAlexey ZelkinThe macro
5424a775e8fSJustin T. Gibbs.Nm STAILQ_REMOVE_HEAD
5434a775e8fSJustin T. Gibbsremoves the element
5444a775e8fSJustin T. Gibbs.Fa elm
5454a775e8fSJustin T. Gibbsfrom the head of the tail queue.
5464a775e8fSJustin T. GibbsFor optimum efficiency,
5474a775e8fSJustin T. Gibbselements being removed from the head of the tail queue should
5484a775e8fSJustin T. Gibbsuse this macro explicitly rather than the generic
5494a775e8fSJustin T. Gibbs.Fa STAILQ_REMOVE
5504a775e8fSJustin T. Gibbsmacro.
5514a775e8fSJustin T. Gibbs.Pp
5524a775e8fSJustin T. GibbsThe macro
5534a775e8fSJustin T. Gibbs.Nm STAILQ_REMOVE
5544a775e8fSJustin T. Gibbsremoves the element
5554a775e8fSJustin T. Gibbs.Fa elm
5564a775e8fSJustin T. Gibbsfrom the tail queue.
5574a775e8fSJustin T. Gibbs.Sh SINGLY-LINKED TAIL QUEUE EXAMPLE
5584a775e8fSJustin T. Gibbs.Bd -literal
55903763fe0SJake BurkholderSTAILQ_HEAD(stailhead, entry) head =
56003763fe0SJake Burkholder    STAILQ_HEAD_INITIALIZER(head);
5614a775e8fSJustin T. Gibbsstruct stailhead *headp;		/* Singly-linked tail queue head. */
5624a775e8fSJustin T. Gibbsstruct entry {
5634a775e8fSJustin T. Gibbs	...
5644a775e8fSJustin T. Gibbs	STAILQ_ENTRY(entry) entries;	/* Tail queue. */
5654a775e8fSJustin T. Gibbs	...
5664a775e8fSJustin T. Gibbs} *n1, *n2, *n3, *np;
5674a775e8fSJustin T. Gibbs
5684a775e8fSJustin T. GibbsSTAILQ_INIT(&head);			/* Initialize the queue. */
5694a775e8fSJustin T. Gibbs
5704a775e8fSJustin T. Gibbsn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
5714a775e8fSJustin T. GibbsSTAILQ_INSERT_HEAD(&head, n1, entries);
5724a775e8fSJustin T. Gibbs
5734a775e8fSJustin T. Gibbsn1 = malloc(sizeof(struct entry));	/* Insert at the tail. */
5744a775e8fSJustin T. GibbsSTAILQ_INSERT_TAIL(&head, n1, entries);
5754a775e8fSJustin T. Gibbs
5764a775e8fSJustin T. Gibbsn2 = malloc(sizeof(struct entry));	/* Insert after. */
5774a775e8fSJustin T. GibbsSTAILQ_INSERT_AFTER(&head, n1, n2, entries);
5784a775e8fSJustin T. Gibbs					/* Deletion. */
5794a775e8fSJustin T. GibbsSTAILQ_REMOVE(&head, n2, entry, entries);
5804a775e8fSJustin T. Gibbsfree(n2);
58103763fe0SJake Burkholder					/* Deletion from the head. */
58279ea9bc4SAlexey Zelkinn3 = STAILQ_FIRST(&head);
5834a775e8fSJustin T. GibbsSTAILQ_REMOVE_HEAD(&head, entries);
5844a775e8fSJustin T. Gibbsfree(n3);
5854a775e8fSJustin T. Gibbs					/* Forward traversal. */
58679ea9bc4SAlexey ZelkinSTAILQ_FOREACH(np, &head, entries)
5874a775e8fSJustin T. Gibbs	np-> ...
5884a775e8fSJustin T. Gibbs					/* TailQ Deletion. */
58979ea9bc4SAlexey Zelkinwhile (!STAILQ_EMPTY(&head)) {
59003763fe0SJake Burkholder	n1 = STAILQ_FIRST(&head);
591266e33fdSJohn Baldwin	STAILQ_REMOVE_HEAD(&head, entries);
5924a775e8fSJustin T. Gibbs	free(n1);
5934a775e8fSJustin T. Gibbs}
5944a775e8fSJustin T. Gibbs					/* Faster TailQ Deletion. */
59579ea9bc4SAlexey Zelkinn1 = STAILQ_FIRST(&head);
5964a775e8fSJustin T. Gibbswhile (n1 != NULL) {
59779ea9bc4SAlexey Zelkin	n2 = STAILQ_NEXT(n1, entries);
5984a775e8fSJustin T. Gibbs	free(n1);
5994a775e8fSJustin T. Gibbs	n1 = n2;
6004a775e8fSJustin T. Gibbs}
6014a775e8fSJustin T. GibbsSTAILQ_INIT(&head);
6024a775e8fSJustin T. Gibbs.Ed
603afe61c15SRodney W. Grimes.Sh LISTS
604afe61c15SRodney W. GrimesA list is headed by a structure defined by the
605afe61c15SRodney W. Grimes.Nm LIST_HEAD
606afe61c15SRodney W. Grimesmacro.
607afe61c15SRodney W. GrimesThis structure contains a single pointer to the first element
608afe61c15SRodney W. Grimeson the list.
609afe61c15SRodney W. GrimesThe elements are doubly linked so that an arbitrary element can be
610afe61c15SRodney W. Grimesremoved without traversing the list.
6114a775e8fSJustin T. GibbsNew elements can be added to the list after an existing element,
6124a775e8fSJustin T. Gibbsbefore an existing element, or at the head of the list.
613afe61c15SRodney W. GrimesA
614afe61c15SRodney W. Grimes.Fa LIST_HEAD
615afe61c15SRodney W. Grimesstructure is declared as follows:
616afe61c15SRodney W. Grimes.Bd -literal -offset indent
617afe61c15SRodney W. GrimesLIST_HEAD(HEADNAME, TYPE) head;
618afe61c15SRodney W. Grimes.Ed
6198f20a914SMike Pritchard.Pp
620afe61c15SRodney W. Grimeswhere
621afe61c15SRodney W. Grimes.Fa HEADNAME
622afe61c15SRodney W. Grimesis the name of the structure to be defined, and
623afe61c15SRodney W. Grimes.Fa TYPE
624afe61c15SRodney W. Grimesis the type of the elements to be linked into the list.
625afe61c15SRodney W. GrimesA pointer to the head of the list can later be declared as:
626afe61c15SRodney W. Grimes.Bd -literal -offset indent
627afe61c15SRodney W. Grimesstruct HEADNAME *headp;
628afe61c15SRodney W. Grimes.Ed
6298f20a914SMike Pritchard.Pp
630afe61c15SRodney W. Grimes(The names
631afe61c15SRodney W. Grimes.Li head
632afe61c15SRodney W. Grimesand
633afe61c15SRodney W. Grimes.Li headp
634afe61c15SRodney W. Grimesare user selectable.)
635afe61c15SRodney W. Grimes.Pp
636afe61c15SRodney W. GrimesThe macro
63703763fe0SJake Burkholder.Nm LIST_HEAD_INITIALIZER
63803763fe0SJake Burkholderevaluates to an initializer for the list
63903763fe0SJake Burkholder.Fa head .
64003763fe0SJake Burkholder.Pp
64103763fe0SJake BurkholderThe macro
64279ea9bc4SAlexey Zelkin.Nm LIST_EMPTY
64379ea9bc4SAlexey Zelkinevaluates to true if their are no elements in the list.
64479ea9bc4SAlexey Zelkin.Pp
64579ea9bc4SAlexey ZelkinThe macro
646afe61c15SRodney W. Grimes.Nm LIST_ENTRY
647afe61c15SRodney W. Grimesdeclares a structure that connects the elements in
648afe61c15SRodney W. Grimesthe list.
649afe61c15SRodney W. Grimes.Pp
650afe61c15SRodney W. GrimesThe macro
65179ea9bc4SAlexey Zelkin.Nm LIST_FIRST
65279ea9bc4SAlexey Zelkinreturns the first element in the list or NULL if the list
65379ea9bc4SAlexey Zelkinis empty.
65479ea9bc4SAlexey Zelkin.Pp
65579ea9bc4SAlexey ZelkinThe macro
65679ea9bc4SAlexey Zelkin.Nm LIST_FOREACH
65779ea9bc4SAlexey Zelkintraverses the list referenced by
65879ea9bc4SAlexey Zelkin.Fa head
65979ea9bc4SAlexey Zelkinin the forward direction, assigning each element in turn to
66079ea9bc4SAlexey Zelkin.Fa var .
66179ea9bc4SAlexey Zelkin.Pp
66279ea9bc4SAlexey ZelkinThe macro
663afe61c15SRodney W. Grimes.Nm LIST_INIT
664afe61c15SRodney W. Grimesinitializes the list referenced by
665afe61c15SRodney W. Grimes.Fa head .
666afe61c15SRodney W. Grimes.Pp
667afe61c15SRodney W. GrimesThe macro
668afe61c15SRodney W. Grimes.Nm LIST_INSERT_HEAD
669afe61c15SRodney W. Grimesinserts the new element
670afe61c15SRodney W. Grimes.Fa elm
671afe61c15SRodney W. Grimesat the head of the list.
672afe61c15SRodney W. Grimes.Pp
673afe61c15SRodney W. GrimesThe macro
674afe61c15SRodney W. Grimes.Nm LIST_INSERT_AFTER
675afe61c15SRodney W. Grimesinserts the new element
676afe61c15SRodney W. Grimes.Fa elm
677afe61c15SRodney W. Grimesafter the element
678afe61c15SRodney W. Grimes.Fa listelm .
679afe61c15SRodney W. Grimes.Pp
680afe61c15SRodney W. GrimesThe macro
6817658b0a2SJustin T. Gibbs.Nm LIST_INSERT_BEFORE
6827658b0a2SJustin T. Gibbsinserts the new element
6837658b0a2SJustin T. Gibbs.Fa elm
6847658b0a2SJustin T. Gibbsbefore the element
6857658b0a2SJustin T. Gibbs.Fa listelm .
6867658b0a2SJustin T. Gibbs.Pp
6877658b0a2SJustin T. GibbsThe macro
68879ea9bc4SAlexey Zelkin.Nm LIST_NEXT
68979ea9bc4SAlexey Zelkinreturns the next element in the list, or NULL if this is the last.
69079ea9bc4SAlexey Zelkin.Pp
69179ea9bc4SAlexey ZelkinThe macro
692afe61c15SRodney W. Grimes.Nm LIST_REMOVE
693afe61c15SRodney W. Grimesremoves the element
694afe61c15SRodney W. Grimes.Fa elm
695afe61c15SRodney W. Grimesfrom the list.
696afe61c15SRodney W. Grimes.Sh LIST EXAMPLE
697afe61c15SRodney W. Grimes.Bd -literal
69803763fe0SJake BurkholderLIST_HEAD(listhead, entry) head =
69903763fe0SJake Burkholder    LIST_HEAD_INITIALIZER(head);
700afe61c15SRodney W. Grimesstruct listhead *headp;			/* List head. */
701afe61c15SRodney W. Grimesstruct entry {
702afe61c15SRodney W. Grimes	...
703afe61c15SRodney W. Grimes	LIST_ENTRY(entry) entries;	/* List. */
704afe61c15SRodney W. Grimes	...
7057658b0a2SJustin T. Gibbs} *n1, *n2, *n3, *np;
706afe61c15SRodney W. Grimes
707afe61c15SRodney W. GrimesLIST_INIT(&head);			/* Initialize the list. */
708afe61c15SRodney W. Grimes
709afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
710afe61c15SRodney W. GrimesLIST_INSERT_HEAD(&head, n1, entries);
711afe61c15SRodney W. Grimes
712afe61c15SRodney W. Grimesn2 = malloc(sizeof(struct entry));	/* Insert after. */
713afe61c15SRodney W. GrimesLIST_INSERT_AFTER(n1, n2, entries);
7147658b0a2SJustin T. Gibbs
7157658b0a2SJustin T. Gibbsn3 = malloc(sizeof(struct entry));	/* Insert before. */
7167658b0a2SJustin T. GibbsLIST_INSERT_BEFORE(n2, n3, entries);
7177658b0a2SJustin T. Gibbs
7187658b0a2SJustin T. GibbsLIST_REMOVE(n2, entries);		/* Deletion. */
7197658b0a2SJustin T. Gibbsfree(n2);
720afe61c15SRodney W. Grimes					/* Forward traversal. */
72179ea9bc4SAlexey ZelkinLIST_FOREACH(np, &head, entries)
722afe61c15SRodney W. Grimes	np-> ...
723afe61c15SRodney W. Grimes
72479ea9bc4SAlexey Zelkinwhile (!LIST_EMPTY(&head)) {		/* List Deletion. */
72579ea9bc4SAlexey Zelkin	n1 = LIST_FIRST(&head);
7267658b0a2SJustin T. Gibbs	LIST_REMOVE(n1, entries);
7277658b0a2SJustin T. Gibbs	free(n1);
7287658b0a2SJustin T. Gibbs}
7297658b0a2SJustin T. Gibbs
73003763fe0SJake Burkholdern1 = LIST_FIRST(&head);			/* Faster List Deletion. */
7317658b0a2SJustin T. Gibbswhile (n1 != NULL) {
73279ea9bc4SAlexey Zelkin	n2 = LIST_NEXT(n1, entries);
7337658b0a2SJustin T. Gibbs	free(n1);
7347658b0a2SJustin T. Gibbs	n1 = n2;
7357658b0a2SJustin T. Gibbs}
7367658b0a2SJustin T. GibbsLIST_INIT(&head);
737afe61c15SRodney W. Grimes.Ed
738afe61c15SRodney W. Grimes.Sh TAIL QUEUES
739afe61c15SRodney W. GrimesA tail queue is headed by a structure defined by the
740afe61c15SRodney W. Grimes.Nm TAILQ_HEAD
741afe61c15SRodney W. Grimesmacro.
742afe61c15SRodney W. GrimesThis structure contains a pair of pointers,
743afe61c15SRodney W. Grimesone to the first element in the tail queue and the other to
744afe61c15SRodney W. Grimesthe last element in the tail queue.
745afe61c15SRodney W. GrimesThe elements are doubly linked so that an arbitrary element can be
746afe61c15SRodney W. Grimesremoved without traversing the tail queue.
747afe61c15SRodney W. GrimesNew elements can be added to the tail queue after an existing element,
7484a775e8fSJustin T. Gibbsbefore an existing element, at the head of the tail queue,
7494a775e8fSJustin T. Gibbsor at the end of the tail queue.
750afe61c15SRodney W. GrimesA
751afe61c15SRodney W. Grimes.Fa TAILQ_HEAD
752afe61c15SRodney W. Grimesstructure is declared as follows:
753afe61c15SRodney W. Grimes.Bd -literal -offset indent
754afe61c15SRodney W. GrimesTAILQ_HEAD(HEADNAME, TYPE) head;
755afe61c15SRodney W. Grimes.Ed
7568f20a914SMike Pritchard.Pp
757afe61c15SRodney W. Grimeswhere
758afe61c15SRodney W. Grimes.Li HEADNAME
759afe61c15SRodney W. Grimesis the name of the structure to be defined, and
760afe61c15SRodney W. Grimes.Li TYPE
761afe61c15SRodney W. Grimesis the type of the elements to be linked into the tail queue.
762afe61c15SRodney W. GrimesA pointer to the head of the tail queue can later be declared as:
763afe61c15SRodney W. Grimes.Bd -literal -offset indent
764afe61c15SRodney W. Grimesstruct HEADNAME *headp;
765afe61c15SRodney W. Grimes.Ed
7668f20a914SMike Pritchard.Pp
767afe61c15SRodney W. Grimes(The names
768afe61c15SRodney W. Grimes.Li head
769afe61c15SRodney W. Grimesand
770afe61c15SRodney W. Grimes.Li headp
771afe61c15SRodney W. Grimesare user selectable.)
772afe61c15SRodney W. Grimes.Pp
773afe61c15SRodney W. GrimesThe macro
77403763fe0SJake Burkholder.Nm TAILQ_HEAD_INITIALIZER
77503763fe0SJake Burkholderevaluates to an initializer for the tail queue
77603763fe0SJake Burkholder.Fa head .
77703763fe0SJake Burkholder.Pp
77803763fe0SJake BurkholderThe macro
779c5c15c16SPoul-Henning Kamp.Nm TAILQ_EMPTY
780c5c15c16SPoul-Henning Kampevaluates to true if there are no items on the tail queue.
781c5c15c16SPoul-Henning Kamp.Pp
782c5c15c16SPoul-Henning KampThe macro
783afe61c15SRodney W. Grimes.Nm TAILQ_ENTRY
784afe61c15SRodney W. Grimesdeclares a structure that connects the elements in
785afe61c15SRodney W. Grimesthe tail queue.
786afe61c15SRodney W. Grimes.Pp
787afe61c15SRodney W. GrimesThe macro
788c5c15c16SPoul-Henning Kamp.Nm TAILQ_FIRST
789c5c15c16SPoul-Henning Kampreturns the first item on the tail queue or NULL if the tail queue
790c5c15c16SPoul-Henning Kampis empty.
791c5c15c16SPoul-Henning Kamp.Pp
792c5c15c16SPoul-Henning KampThe macro
79379ea9bc4SAlexey Zelkin.Nm TAILQ_FOREACH
79479ea9bc4SAlexey Zelkintraverses the tail queue referenced by
79579ea9bc4SAlexey Zelkin.Fa head
79679ea9bc4SAlexey Zelkinin the forward direction, assigning each element in turn to
79779ea9bc4SAlexey Zelkin.Fa var .
79879ea9bc4SAlexey Zelkin.Pp
79979ea9bc4SAlexey ZelkinThe macro
8006c1d0fbfSArchie Cobbs.Nm TAILQ_FOREACH_REVERSE
8016c1d0fbfSArchie Cobbstraverses the tail queue referenced by
8026c1d0fbfSArchie Cobbs.Fa head
8036c1d0fbfSArchie Cobbsin the reverse direction, assigning each element in turn to
8046c1d0fbfSArchie Cobbs.Fa var .
8056c1d0fbfSArchie Cobbs.Pp
8066c1d0fbfSArchie CobbsThe macro
807afe61c15SRodney W. Grimes.Nm TAILQ_INIT
808afe61c15SRodney W. Grimesinitializes the tail queue referenced by
809afe61c15SRodney W. Grimes.Fa head .
810afe61c15SRodney W. Grimes.Pp
811afe61c15SRodney W. GrimesThe macro
812afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_HEAD
813afe61c15SRodney W. Grimesinserts the new element
814afe61c15SRodney W. Grimes.Fa elm
815afe61c15SRodney W. Grimesat the head of the tail queue.
816afe61c15SRodney W. Grimes.Pp
817afe61c15SRodney W. GrimesThe macro
818afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_TAIL
819afe61c15SRodney W. Grimesinserts the new element
820afe61c15SRodney W. Grimes.Fa elm
821afe61c15SRodney W. Grimesat the end of the tail queue.
822afe61c15SRodney W. Grimes.Pp
823afe61c15SRodney W. GrimesThe macro
824afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_AFTER
825afe61c15SRodney W. Grimesinserts the new element
826afe61c15SRodney W. Grimes.Fa elm
827afe61c15SRodney W. Grimesafter the element
828afe61c15SRodney W. Grimes.Fa listelm .
829afe61c15SRodney W. Grimes.Pp
830afe61c15SRodney W. GrimesThe macro
8317658b0a2SJustin T. Gibbs.Nm TAILQ_INSERT_BEFORE
8327658b0a2SJustin T. Gibbsinserts the new element
8337658b0a2SJustin T. Gibbs.Fa elm
8347658b0a2SJustin T. Gibbsbefore the element
8357658b0a2SJustin T. Gibbs.Fa listelm .
8367658b0a2SJustin T. Gibbs.Pp
8377658b0a2SJustin T. GibbsThe macro
838c5c15c16SPoul-Henning Kamp.Nm TAILQ_LAST
839c5c15c16SPoul-Henning Kampreturns the last item on the tail queue.
840c5c15c16SPoul-Henning KampIf the tail queue is empty the return value is undefined.
841c5c15c16SPoul-Henning Kamp.Pp
842c5c15c16SPoul-Henning KampThe macro
843c5c15c16SPoul-Henning Kamp.Nm TAILQ_NEXT
84479ea9bc4SAlexey Zelkinreturns the next item on the tail queue, or NULL if this item is the last.
84579ea9bc4SAlexey Zelkin.Pp
84679ea9bc4SAlexey ZelkinThe macro
84779ea9bc4SAlexey Zelkin.Nm TAILQ_PREV
84879ea9bc4SAlexey Zelkinreturns the previous item on the tail queue, or NULL if this item
84979ea9bc4SAlexey Zelkinis the first.
850c5c15c16SPoul-Henning Kamp.Pp
851c5c15c16SPoul-Henning KampThe macro
852afe61c15SRodney W. Grimes.Nm TAILQ_REMOVE
853afe61c15SRodney W. Grimesremoves the element
854afe61c15SRodney W. Grimes.Fa elm
855afe61c15SRodney W. Grimesfrom the tail queue.
856afe61c15SRodney W. Grimes.Sh TAIL QUEUE EXAMPLE
857afe61c15SRodney W. Grimes.Bd -literal
85803763fe0SJake BurkholderTAILQ_HEAD(tailhead, entry) head =
85903763fe0SJake Burkholder    TAILQ_HEAD_INITIALIZER(head);
860afe61c15SRodney W. Grimesstruct tailhead *headp;			/* Tail queue head. */
861afe61c15SRodney W. Grimesstruct entry {
862afe61c15SRodney W. Grimes	...
863afe61c15SRodney W. Grimes	TAILQ_ENTRY(entry) entries;	/* Tail queue. */
864afe61c15SRodney W. Grimes	...
8657658b0a2SJustin T. Gibbs} *n1, *n2, *n3, *np;
866afe61c15SRodney W. Grimes
867afe61c15SRodney W. GrimesTAILQ_INIT(&head);			/* Initialize the queue. */
868afe61c15SRodney W. Grimes
869afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
870afe61c15SRodney W. GrimesTAILQ_INSERT_HEAD(&head, n1, entries);
871afe61c15SRodney W. Grimes
872afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the tail. */
873afe61c15SRodney W. GrimesTAILQ_INSERT_TAIL(&head, n1, entries);
874afe61c15SRodney W. Grimes
875afe61c15SRodney W. Grimesn2 = malloc(sizeof(struct entry));	/* Insert after. */
876afe61c15SRodney W. GrimesTAILQ_INSERT_AFTER(&head, n1, n2, entries);
8777658b0a2SJustin T. Gibbs
8787658b0a2SJustin T. Gibbsn3 = malloc(sizeof(struct entry));	/* Insert before. */
8793652ff55SJustin T. GibbsTAILQ_INSERT_BEFORE(n2, n3, entries);
8807658b0a2SJustin T. Gibbs
8817658b0a2SJustin T. GibbsTAILQ_REMOVE(&head, n2, entries);	/* Deletion. */
8827658b0a2SJustin T. Gibbsfree(n2);
883afe61c15SRodney W. Grimes					/* Forward traversal. */
88479ea9bc4SAlexey ZelkinTAILQ_FOREACH(np, &head, entries)
885afe61c15SRodney W. Grimes	np-> ...
8866c1d0fbfSArchie Cobbs					/* Reverse traversal. */
8876c1d0fbfSArchie CobbsTAILQ_FOREACH_REVERSE(np, &head, tailhead, entries)
8886c1d0fbfSArchie Cobbs	np-> ...
8897658b0a2SJustin T. Gibbs					/* TailQ Deletion. */
890d6c63818SMark Murraywhile (!TAILQ_EMPTY(&head)) {
891c5c15c16SPoul-Henning Kamp	n1 = TAILQ_FIRST(&head);
89279ea9bc4SAlexey Zelkin	TAILQ_REMOVE(&head, n1, entries);
8937658b0a2SJustin T. Gibbs	free(n1);
8947658b0a2SJustin T. Gibbs}
8957658b0a2SJustin T. Gibbs					/* Faster TailQ Deletion. */
896c5c15c16SPoul-Henning Kampn1 = TAILQ_FIRST(&head);
8977658b0a2SJustin T. Gibbswhile (n1 != NULL) {
898c5c15c16SPoul-Henning Kamp	n2 = TAILQ_NEXT(n1, entries);
8997658b0a2SJustin T. Gibbs	free(n1);
9007658b0a2SJustin T. Gibbs	n1 = n2;
9017658b0a2SJustin T. Gibbs}
9027658b0a2SJustin T. GibbsTAILQ_INIT(&head);
903afe61c15SRodney W. Grimes.Ed
904afe61c15SRodney W. Grimes.Sh CIRCULAR QUEUES
905afe61c15SRodney W. GrimesA circular queue is headed by a structure defined by the
906afe61c15SRodney W. Grimes.Nm CIRCLEQ_HEAD
907afe61c15SRodney W. Grimesmacro.
908afe61c15SRodney W. GrimesThis structure contains a pair of pointers,
909afe61c15SRodney W. Grimesone to the first element in the circular queue and the other to the
910afe61c15SRodney W. Grimeslast element in the circular queue.
911afe61c15SRodney W. GrimesThe elements are doubly linked so that an arbitrary element can be
912afe61c15SRodney W. Grimesremoved without traversing the queue.
913afe61c15SRodney W. GrimesNew elements can be added to the queue after an existing element,
914afe61c15SRodney W. Grimesbefore an existing element, at the head of the queue, or at the end
915afe61c15SRodney W. Grimesof the queue.
916afe61c15SRodney W. GrimesA
917afe61c15SRodney W. Grimes.Fa CIRCLEQ_HEAD
918afe61c15SRodney W. Grimesstructure is declared as follows:
919afe61c15SRodney W. Grimes.Bd -literal -offset indent
920afe61c15SRodney W. GrimesCIRCLEQ_HEAD(HEADNAME, TYPE) head;
921afe61c15SRodney W. Grimes.Ed
9228f20a914SMike Pritchard.Pp
923afe61c15SRodney W. Grimeswhere
924afe61c15SRodney W. Grimes.Li HEADNAME
925afe61c15SRodney W. Grimesis the name of the structure to be defined, and
926afe61c15SRodney W. Grimes.Li TYPE
927afe61c15SRodney W. Grimesis the type of the elements to be linked into the circular queue.
928afe61c15SRodney W. GrimesA pointer to the head of the circular queue can later be declared as:
929afe61c15SRodney W. Grimes.Bd -literal -offset indent
930afe61c15SRodney W. Grimesstruct HEADNAME *headp;
931afe61c15SRodney W. Grimes.Ed
9328f20a914SMike Pritchard.Pp
933afe61c15SRodney W. Grimes(The names
934afe61c15SRodney W. Grimes.Li head
935afe61c15SRodney W. Grimesand
936afe61c15SRodney W. Grimes.Li headp
937afe61c15SRodney W. Grimesare user selectable.)
938afe61c15SRodney W. Grimes.Pp
939afe61c15SRodney W. GrimesThe macro
94003763fe0SJake Burkholder.Nm CIRCLEQ_HEAD_INITIALIZER
94103763fe0SJake Burkholderevaluates to an initializer for the circle queue
94203763fe0SJake Burkholder.Fa head .
94303763fe0SJake Burkholder.Pp
94403763fe0SJake BurkholderThe macro
94579ea9bc4SAlexey Zelkin.Nm CIRCLEQ_EMPTY
94679ea9bc4SAlexey Zelkinevaluates to true if there are no items on the circle queue.
94779ea9bc4SAlexey Zelkin.Pp
94879ea9bc4SAlexey ZelkinThe macro
949afe61c15SRodney W. Grimes.Nm CIRCLEQ_ENTRY
950afe61c15SRodney W. Grimesdeclares a structure that connects the elements in
951afe61c15SRodney W. Grimesthe circular queue.
952afe61c15SRodney W. Grimes.Pp
953afe61c15SRodney W. GrimesThe macro
95479ea9bc4SAlexey Zelkin.Nm CIRCLEQ_FIRST
95579ea9bc4SAlexey Zelkinreturns the first item on the circle queue.
95679ea9bc4SAlexey Zelkin.Pp
95779ea9bc4SAlexey ZelkinThe macro
95879ea9bc4SAlexey Zelkin.Nm CICRLEQ_FOREACH
95979ea9bc4SAlexey Zelkintraverses the circle queue referenced by
96079ea9bc4SAlexey Zelkin.Fa head
96179ea9bc4SAlexey Zelkinin the forward direction, assigning each element in turn to
96279ea9bc4SAlexey Zelkin.Fa var .
96379ea9bc4SAlexey Zelkin.Pp
96479ea9bc4SAlexey ZelkinThe macro
9656c1d0fbfSArchie Cobbs.Nm CICRLEQ_FOREACH_REVERSE
9666c1d0fbfSArchie Cobbstraverses the circle queue referenced by
9676c1d0fbfSArchie Cobbs.Fa head
9686c1d0fbfSArchie Cobbsin the reverse direction, assigning each element in turn to
9696c1d0fbfSArchie Cobbs.Fa var .
9706c1d0fbfSArchie Cobbs.Pp
9716c1d0fbfSArchie CobbsThe macro
972afe61c15SRodney W. Grimes.Nm CIRCLEQ_INIT
973afe61c15SRodney W. Grimesinitializes the circular queue referenced by
974afe61c15SRodney W. Grimes.Fa head .
975afe61c15SRodney W. Grimes.Pp
976afe61c15SRodney W. GrimesThe macro
977afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_HEAD
978afe61c15SRodney W. Grimesinserts the new element
979afe61c15SRodney W. Grimes.Fa elm
980afe61c15SRodney W. Grimesat the head of the circular queue.
981afe61c15SRodney W. Grimes.Pp
982afe61c15SRodney W. GrimesThe macro
983afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_TAIL
984afe61c15SRodney W. Grimesinserts the new element
985afe61c15SRodney W. Grimes.Fa elm
986afe61c15SRodney W. Grimesat the end of the circular queue.
987afe61c15SRodney W. Grimes.Pp
988afe61c15SRodney W. GrimesThe macro
989afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_AFTER
990afe61c15SRodney W. Grimesinserts the new element
991afe61c15SRodney W. Grimes.Fa elm
992afe61c15SRodney W. Grimesafter the element
993afe61c15SRodney W. Grimes.Fa listelm .
994afe61c15SRodney W. Grimes.Pp
995afe61c15SRodney W. GrimesThe macro
996afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_BEFORE
997afe61c15SRodney W. Grimesinserts the new element
998afe61c15SRodney W. Grimes.Fa elm
999afe61c15SRodney W. Grimesbefore the element
1000afe61c15SRodney W. Grimes.Fa listelm .
1001afe61c15SRodney W. Grimes.Pp
1002afe61c15SRodney W. GrimesThe macro
100379ea9bc4SAlexey Zelkin.Nm CIRCLEQ_LAST
100479ea9bc4SAlexey Zelkinreturns the last item on the circle queue.
100579ea9bc4SAlexey Zelkin.Pp
100679ea9bc4SAlexey ZelkinThe macro
100779ea9bc4SAlexey Zelkin.Nm CIRCLEQ_NEXT
100879ea9bc4SAlexey Zelkinreturns the next item on the circle queue.
100979ea9bc4SAlexey Zelkin.Pp
101079ea9bc4SAlexey ZelkinThe macro
101179ea9bc4SAlexey Zelkin.Nm CIRCLEQ_PREV
101279ea9bc4SAlexey Zelkinreturns the previous item on the circle queue.
101379ea9bc4SAlexey Zelkin.Pp
101479ea9bc4SAlexey ZelkinThe macro
1015afe61c15SRodney W. Grimes.Nm CIRCLEQ_REMOVE
1016afe61c15SRodney W. Grimesremoves the element
1017afe61c15SRodney W. Grimes.Fa elm
1018afe61c15SRodney W. Grimesfrom the circular queue.
1019afe61c15SRodney W. Grimes.Sh CIRCULAR QUEUE EXAMPLE
1020afe61c15SRodney W. Grimes.Bd -literal
102103763fe0SJake BurkholderCIRCLEQ_HEAD(circlehead, entry) head =
102203763fe0SJake Burkholder    CIRCLEQ_HEAD_INITIALIZER(head);
102303763fe0SJake Burkholderstruct circlehead *headp;		/* Circular queue head. */
1024afe61c15SRodney W. Grimesstruct entry {
1025afe61c15SRodney W. Grimes	...
10266aea1c7cSMike Pritchard	CIRCLEQ_ENTRY(entry) entries;	/* Circular queue. */
1027afe61c15SRodney W. Grimes	...
1028afe61c15SRodney W. Grimes} *n1, *n2, *np;
1029afe61c15SRodney W. Grimes
1030afe61c15SRodney W. GrimesCIRCLEQ_INIT(&head);			/* Initialize the circular queue. */
1031afe61c15SRodney W. Grimes
1032afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
1033afe61c15SRodney W. GrimesCIRCLEQ_INSERT_HEAD(&head, n1, entries);
1034afe61c15SRodney W. Grimes
1035afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the tail. */
1036afe61c15SRodney W. GrimesCIRCLEQ_INSERT_TAIL(&head, n1, entries);
1037afe61c15SRodney W. Grimes
1038afe61c15SRodney W. Grimesn2 = malloc(sizeof(struct entry));	/* Insert after. */
1039afe61c15SRodney W. GrimesCIRCLEQ_INSERT_AFTER(&head, n1, n2, entries);
1040afe61c15SRodney W. Grimes
1041afe61c15SRodney W. Grimesn2 = malloc(sizeof(struct entry));	/* Insert before. */
1042afe61c15SRodney W. GrimesCIRCLEQ_INSERT_BEFORE(&head, n1, n2, entries);
10437658b0a2SJustin T. Gibbs
10447658b0a2SJustin T. GibbsCIRCLEQ_REMOVE(&head, n1, entries);	/* Deletion. */
10457658b0a2SJustin T. Gibbsfree(n1);
1046afe61c15SRodney W. Grimes					/* Forward traversal. */
104779ea9bc4SAlexey ZelkinCIRCLEQ_FOREACH(np, &head, entries)
1048afe61c15SRodney W. Grimes	np-> ...
1049afe61c15SRodney W. Grimes					/* Reverse traversal. */
10506c1d0fbfSArchie CobbsCIRCLEQ_FOREACH_REVERSE(np, &head, entries)
1051afe61c15SRodney W. Grimes	np-> ...
10527658b0a2SJustin T. Gibbs					/* CircleQ Deletion. */
105379ea9bc4SAlexey Zelkinwhile (CIRCLEQ_FIRST(&head) != (void *)&head) {
105479ea9bc4SAlexey Zelkin	n1 = CIRCLEQ_HEAD(&head);
105579ea9bc4SAlexey Zelkin	CIRCLEQ_REMOVE(&head, n1, entries);
10567658b0a2SJustin T. Gibbs	free(n1);
10577658b0a2SJustin T. Gibbs}
10587658b0a2SJustin T. Gibbs					/* Faster CircleQ Deletion. */
105979ea9bc4SAlexey Zelkinn1 = CIRCLEQ_FIRST(&head);
10607658b0a2SJustin T. Gibbswhile (n1 != (void *)&head) {
106179ea9bc4SAlexey Zelkin	n2 = CIRCLEQ_NEXT(n1, entries);
10627658b0a2SJustin T. Gibbs	free(n1);
10637658b0a2SJustin T. Gibbs	n1 = n2;
10647658b0a2SJustin T. Gibbs}
10657658b0a2SJustin T. GibbsCIRCLEQ_INIT(&head);
1066afe61c15SRodney W. Grimes.Ed
1067afe61c15SRodney W. Grimes.Sh HISTORY
1068afe61c15SRodney W. GrimesThe
1069afe61c15SRodney W. Grimes.Nm queue
107021421932SMike Pritchardfunctions first appeared in
107121421932SMike Pritchard.Bx 4.4 .
1072