xref: /freebsd/share/man/man3/queue.3 (revision 4a775e8f6862746bfaf65bb73361c8bb146dc771)
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
33afe61c15SRodney W. Grimes.\"
34afe61c15SRodney W. Grimes.Dd "January 24, 1994"
35afe61c15SRodney W. Grimes.Dt QUEUE 3
36afe61c15SRodney W. Grimes.Os BSD 4
37afe61c15SRodney W. Grimes.Sh NAME
384a775e8fSJustin T. Gibbs.Nm SLIST_ENTRY ,
394a775e8fSJustin T. Gibbs.Nm SLIST_HEAD ,
404a775e8fSJustin T. Gibbs.Nm SLIST_INIT ,
414a775e8fSJustin T. Gibbs.Nm SLIST_INSERT_AFTER ,
424a775e8fSJustin T. Gibbs.Nm SLIST_INSERT_HEAD ,
434a775e8fSJustin T. Gibbs.Nm SLIST_REMOVE_HEAD ,
444a775e8fSJustin T. Gibbs.Nm SLIST_REMOVE ,
454a775e8fSJustin T. Gibbs.Nm STAILQ_ENTRY ,
464a775e8fSJustin T. Gibbs.Nm STAILQ_HEAD ,
474a775e8fSJustin T. Gibbs.Nm STAILQ_INIT ,
484a775e8fSJustin T. Gibbs.Nm STAILQ_INSERT_AFTER ,
494a775e8fSJustin T. Gibbs.Nm STAILQ_INSERT_HEAD ,
504a775e8fSJustin T. Gibbs.Nm STAILQ_INSERT_TAIL ,
514a775e8fSJustin T. Gibbs.Nm STAILQ_REMOVE_HEAD ,
524a775e8fSJustin T. Gibbs.Nm STAILQ_REMOVE ,
53afe61c15SRodney W. Grimes.Nm LIST_ENTRY ,
54afe61c15SRodney W. Grimes.Nm LIST_HEAD ,
55afe61c15SRodney W. Grimes.Nm LIST_INIT ,
56afe61c15SRodney W. Grimes.Nm LIST_INSERT_AFTER ,
577658b0a2SJustin T. Gibbs.Nm LIST_INSERT_BEFORE ,
58afe61c15SRodney W. Grimes.Nm LIST_INSERT_HEAD ,
59afe61c15SRodney W. Grimes.Nm LIST_REMOVE ,
60afe61c15SRodney W. Grimes.Nm TAILQ_ENTRY ,
61afe61c15SRodney W. Grimes.Nm TAILQ_HEAD ,
62afe61c15SRodney W. Grimes.Nm TAILQ_INIT ,
63afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_AFTER ,
647658b0a2SJustin T. Gibbs.Nm TAILQ_INSERT_BEFORE ,
65afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_HEAD ,
66afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_TAIL ,
67afe61c15SRodney W. Grimes.Nm TAILQ_REMOVE ,
68afe61c15SRodney W. Grimes.Nm CIRCLEQ_ENTRY ,
69afe61c15SRodney W. Grimes.Nm CIRCLEQ_HEAD ,
70afe61c15SRodney W. Grimes.Nm CIRCLEQ_INIT ,
71afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_AFTER ,
72afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_BEFORE ,
73afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_HEAD ,
74afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_TAIL ,
75afe61c15SRodney W. Grimes.Nm CIRCLEQ_REMOVE
764a775e8fSJustin T. Gibbs.Nd implementations of singly-linked lists, singly-linked tail queues,
774a775e8fSJustin T. Gibbslists, tail queues, and circular queues
78afe61c15SRodney W. Grimes.Sh SYNOPSIS
79afe61c15SRodney W. Grimes.Fd #include <sys/queue.h>
80afe61c15SRodney W. Grimes.sp
814a775e8fSJustin T. Gibbs.Fn SLIST_ENTRY "TYPE"
824a775e8fSJustin T. Gibbs.Fn SLIST_HEAD "HEADNAME" "TYPE"
834a775e8fSJustin T. Gibbs.Fn SLIST_INIT "SLIST_HEAD *head"
844a775e8fSJustin T. Gibbs.Fn SLIST_INSERT_AFTER "TYPE *listelm" "TYPE *elm" "SLIST_ENTRY NAME"
854a775e8fSJustin T. Gibbs.Fn SLIST_INSERT_HEAD "SLIST_HEAD *head" "TYPE *elm" "SLIST_ENTRY NAME"
864a775e8fSJustin T. Gibbs.Fn SLIST_REMOVE_HEAD "SLIST_HEAD *head" "SLIST_ENTRY NAME"
874a775e8fSJustin T. Gibbs.Fn SLIST_REMOVE "SLIST_HEAD *head" "TYPE *elm" "TYPE" "SLIST_ENTRY NAME"
884a775e8fSJustin T. Gibbs.sp
894a775e8fSJustin T. Gibbs.Fn STAILQ_ENTRY "TYPE"
904a775e8fSJustin T. Gibbs.Fn STAILQ_HEAD "HEADNAME" "TYPE"
914a775e8fSJustin T. Gibbs.Fn STAILQ_INIT "STAILQ_HEAD *head"
924a775e8fSJustin T. Gibbs.Fn STAILQ_INSERT_AFTER "STAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "STAILQ_ENTRY NAME"
934a775e8fSJustin T. Gibbs.Fn STAILQ_INSERT_HEAD "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
944a775e8fSJustin T. Gibbs.Fn STAILQ_INSERT_TAIL "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
954a775e8fSJustin T. Gibbs.Fn STAILQ_REMOVE_HEAD "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
964a775e8fSJustin T. Gibbs.Fn STAILQ_REMOVE "STAILQ_HEAD *head" "TYPE *elm" "TYPE" "STAILQ_ENTRY NAME"
974a775e8fSJustin T. Gibbs.sp
98afe61c15SRodney W. Grimes.Fn LIST_ENTRY "TYPE"
99afe61c15SRodney W. Grimes.Fn LIST_HEAD "HEADNAME" "TYPE"
100afe61c15SRodney W. Grimes.Fn LIST_INIT "LIST_HEAD *head"
1014a775e8fSJustin T. Gibbs.Fn LIST_INSERT_AFTER "TYPE *listelm" "TYPE *elm" "LIST_ENTRY NAME"
1024a775e8fSJustin T. Gibbs.Fn LIST_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "LIST_ENTRY NAME"
103afe61c15SRodney W. Grimes.Fn LIST_INSERT_HEAD "LIST_HEAD *head" "TYPE *elm" "LIST_ENTRY NAME"
104afe61c15SRodney W. Grimes.Fn LIST_REMOVE "TYPE *elm" "LIST_ENTRY NAME"
105afe61c15SRodney W. Grimes.sp
106afe61c15SRodney W. Grimes.Fn TAILQ_ENTRY "TYPE"
107afe61c15SRodney W. Grimes.Fn TAILQ_HEAD "HEADNAME" "TYPE"
108afe61c15SRodney W. Grimes.Fn TAILQ_INIT "TAILQ_HEAD *head"
109afe61c15SRodney W. Grimes.Fn TAILQ_INSERT_AFTER "TAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME"
1103652ff55SJustin T. Gibbs.Fn TAILQ_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME"
111afe61c15SRodney W. Grimes.Fn TAILQ_INSERT_HEAD "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
112afe61c15SRodney W. Grimes.Fn TAILQ_INSERT_TAIL "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
113afe61c15SRodney W. Grimes.Fn TAILQ_REMOVE "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
114afe61c15SRodney W. Grimes.sp
115afe61c15SRodney W. Grimes.Fn CIRCLEQ_ENTRY "TYPE"
116afe61c15SRodney W. Grimes.Fn CIRCLEQ_HEAD "HEADNAME" "TYPE"
117afe61c15SRodney W. Grimes.Fn CIRCLEQ_INIT "CIRCLEQ_HEAD *head"
118afe61c15SRodney W. Grimes.Fn CIRCLEQ_INSERT_AFTER "CIRCLEQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
119afe61c15SRodney W. Grimes.Fn CIRCLEQ_INSERT_BEFORE "CIRCLEQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
120afe61c15SRodney W. Grimes.Fn CIRCLEQ_INSERT_HEAD "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
121afe61c15SRodney W. Grimes.Fn CIRCLEQ_INSERT_TAIL "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
122afe61c15SRodney W. Grimes.Fn CIRCLEQ_REMOVE "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
123afe61c15SRodney W. Grimes.Sh DESCRIPTION
1244a775e8fSJustin T. GibbsThese macros define and operate on five types of data structures:
1254a775e8fSJustin T. Gibbssingly-linked lists, singly-linked tail queues, lists, tail queues,
1264a775e8fSJustin T. Gibbsand circular queues.
1274a775e8fSJustin T. GibbsAll five structures support the following functionality:
128afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
129afe61c15SRodney W. Grimes.It
130afe61c15SRodney W. GrimesInsertion of a new entry at the head of the list.
131afe61c15SRodney W. Grimes.It
132afe61c15SRodney W. GrimesInsertion of a new entry after any element in the list.
133afe61c15SRodney W. Grimes.It
1344a775e8fSJustin T. GibbsO(1) removal of an entry from the head of the list.
1357658b0a2SJustin T. Gibbs.It
1364a775e8fSJustin T. GibbsO(n) removal of any entry in the list.
137afe61c15SRodney W. Grimes.It
138afe61c15SRodney W. GrimesForward traversal through the list.
139afe61c15SRodney W. Grimes.El
140afe61c15SRodney W. Grimes.Pp
1414a775e8fSJustin T. GibbsSingly-linked lists are the simplest of the five data structures
1424a775e8fSJustin T. Gibbsand support only the above functionality.
1434a775e8fSJustin T. GibbsSingly-linked lists are ideal for applications with large datasets
1444a775e8fSJustin T. Gibbsand few or no removals,
1454a775e8fSJustin T. Gibbsor for implementing a LIFO queue.
1464a775e8fSJustin T. Gibbs.Pp
1474a775e8fSJustin T. GibbsSingly-linked tail queues add the following functionality:
1484a775e8fSJustin T. Gibbs.Bl -enum -compact -offset indent
1494a775e8fSJustin T. Gibbs.It
1504a775e8fSJustin T. GibbsEntries can be added at the end of a list.
1514a775e8fSJustin T. Gibbs.El
1524a775e8fSJustin T. GibbsHowever:
1534a775e8fSJustin T. Gibbs.Bl -enum -compact -offset indent
1544a775e8fSJustin T. Gibbs.It
1554a775e8fSJustin T. GibbsAll list insertions must specify the head of the list.
1564a775e8fSJustin T. Gibbs.It
1574a775e8fSJustin T. GibbsEach head entry requires two pointers rather than one.
1584a775e8fSJustin T. Gibbs.It
1594a775e8fSJustin T. GibbsCode size is about 15% greater and operations run about 20% slower
1604a775e8fSJustin T. Gibbsthan singly-linked lists.
1614a775e8fSJustin T. Gibbs.El
1624a775e8fSJustin T. Gibbs.Pp
1634a775e8fSJustin T. GibbsSingly-linked tailqs are ideal for applications with large datasets and
1644a775e8fSJustin T. Gibbsfew or no removals,
1654a775e8fSJustin T. Gibbsor for implementing a FIFO queue.
1664a775e8fSJustin T. Gibbs.Pp
1674a775e8fSJustin T. GibbsAll doubly linked types of data structures (lists, tail queues, and circle
1684a775e8fSJustin T. Gibbsqueues) additionally allow:
1694a775e8fSJustin T. Gibbs.Bl -enum -compact -offset indent
1704a775e8fSJustin T. Gibbs.It
1714a775e8fSJustin T. GibbsInsertion of a new entry before any element in the list.
1724a775e8fSJustin T. Gibbs.It
1734a775e8fSJustin T. GibbsO(1) removal of any entry in the list.
1744a775e8fSJustin T. Gibbs.El
1754a775e8fSJustin T. GibbsHowever:
1764a775e8fSJustin T. Gibbs.Bl -enum -compact -offset indent
1774a775e8fSJustin T. Gibbs.It
1784a775e8fSJustin T. GibbsEach elements requires two pointers rather than one.
1794a775e8fSJustin T. Gibbs.It
1804a775e8fSJustin T. GibbsCode size and execution time of operations (except for removal) is about
1814a775e8fSJustin T. Gibbstwice that of the singly-linked data-structures.
1824a775e8fSJustin T. Gibbs.El
1834a775e8fSJustin T. Gibbs.Pp
1844a775e8fSJustin T. GibbsLinked lists are the simplest of the doubly linked data structures and support
1854a775e8fSJustin T. Gibbsonly the above functionality over singly-linked lists.
186afe61c15SRodney W. Grimes.Pp
187afe61c15SRodney W. GrimesTail queues add the following functionality:
188afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
189afe61c15SRodney W. Grimes.It
190afe61c15SRodney W. GrimesEntries can be added at the end of a list.
191afe61c15SRodney W. Grimes.El
192afe61c15SRodney W. GrimesHowever:
193afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
194afe61c15SRodney W. Grimes.It
195afe61c15SRodney W. GrimesAll list insertions and removals must specify the head of the list.
196afe61c15SRodney W. Grimes.It
197afe61c15SRodney W. GrimesEach head entry requires two pointers rather than one.
198afe61c15SRodney W. Grimes.It
199afe61c15SRodney W. GrimesCode size is about 15% greater and operations run about 20% slower
2004a775e8fSJustin T. Gibbsthan singly-linked lists.
201afe61c15SRodney W. Grimes.El
202afe61c15SRodney W. Grimes.Pp
203afe61c15SRodney W. GrimesCircular queues add the following functionality:
204afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
205afe61c15SRodney W. Grimes.It
206afe61c15SRodney W. GrimesEntries can be added at the end of a list.
207afe61c15SRodney W. Grimes.It
208afe61c15SRodney W. GrimesThey may be traversed backwards, from tail to head.
209afe61c15SRodney W. Grimes.El
210afe61c15SRodney W. GrimesHowever:
211afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
212afe61c15SRodney W. Grimes.It
213afe61c15SRodney W. GrimesAll list insertions and removals must specify the head of the list.
214afe61c15SRodney W. Grimes.It
215afe61c15SRodney W. GrimesEach head entry requires two pointers rather than one.
216afe61c15SRodney W. Grimes.It
217afe61c15SRodney W. GrimesThe termination condition for traversal is more complex.
218afe61c15SRodney W. Grimes.It
219afe61c15SRodney W. GrimesCode size is about 40% greater and operations run about 45% slower
220afe61c15SRodney W. Grimesthan lists.
221afe61c15SRodney W. Grimes.El
222afe61c15SRodney W. Grimes.Pp
223afe61c15SRodney W. GrimesIn the macro definitions,
224afe61c15SRodney W. Grimes.Fa TYPE
225afe61c15SRodney W. Grimesis the name of a user defined structure,
226afe61c15SRodney W. Grimesthat must contain a field of type
2274a775e8fSJustin T. Gibbs.Li SLIST_ENTRY ,
2284a775e8fSJustin T. Gibbs.Li STAILQ_ENTRY ,
229afe61c15SRodney W. Grimes.Li LIST_ENTRY ,
230afe61c15SRodney W. Grimes.Li TAILQ_ENTRY ,
231afe61c15SRodney W. Grimesor
232afe61c15SRodney W. Grimes.Li CIRCLEQ_ENTRY ,
233afe61c15SRodney W. Grimesnamed
234afe61c15SRodney W. Grimes.Fa NAME .
235afe61c15SRodney W. GrimesThe argument
236afe61c15SRodney W. Grimes.Fa HEADNAME
237afe61c15SRodney W. Grimesis the name of a user defined structure that must be declared
238afe61c15SRodney W. Grimesusing the macros
2394a775e8fSJustin T. Gibbs.Li SLIST_HEAD ,
2404a775e8fSJustin T. Gibbs.Li STAILQ_HEAD ,
241afe61c15SRodney W. Grimes.Li LIST_HEAD ,
242afe61c15SRodney W. Grimes.Li TAILQ_HEAD ,
243afe61c15SRodney W. Grimesor
244afe61c15SRodney W. Grimes.Li CIRCLEQ_HEAD .
245afe61c15SRodney W. GrimesSee the examples below for further explanation of how these
246afe61c15SRodney W. Grimesmacros are used.
2474a775e8fSJustin T. Gibbs.Sh SINGLY-LINKED LISTS
2484a775e8fSJustin T. GibbsA singly-linked list is headed by a structure defined by the
2494a775e8fSJustin T. Gibbs.Nm SLIST_HEAD
2504a775e8fSJustin T. Gibbsmacro.
2514a775e8fSJustin T. GibbsThis structure contains a single pointer to the first element
2524a775e8fSJustin T. Gibbson the list.
2534a775e8fSJustin T. GibbsThe elements are singly linked for minimum space and pointer manipulation
2544a775e8fSJustin T. Gibbsoverhead at the expense of O(n) removal for arbitrary elements.
2554a775e8fSJustin T. GibbsNew elements can be added to the list after an existing element or
2564a775e8fSJustin T. Gibbsat the head of the list.
2574a775e8fSJustin T. GibbsAn
2584a775e8fSJustin T. Gibbs.Fa SLIST_HEAD
2594a775e8fSJustin T. Gibbsstructure is declared as follows:
2604a775e8fSJustin T. Gibbs.Bd -literal -offset indent
2614a775e8fSJustin T. GibbsSLIST_HEAD(HEADNAME, TYPE) head;
2624a775e8fSJustin T. Gibbs.Ed
2634a775e8fSJustin T. Gibbs.sp
2644a775e8fSJustin T. Gibbswhere
2654a775e8fSJustin T. Gibbs.Fa HEADNAME
2664a775e8fSJustin T. Gibbsis the name of the structure to be defined, and
2674a775e8fSJustin T. Gibbs.Fa TYPE
2684a775e8fSJustin T. Gibbsis the type of the elements to be linked into the list.
2694a775e8fSJustin T. GibbsA pointer to the head of the list can later be declared as:
2704a775e8fSJustin T. Gibbs.Bd -literal -offset indent
2714a775e8fSJustin T. Gibbsstruct HEADNAME *headp;
2724a775e8fSJustin T. Gibbs.Ed
2734a775e8fSJustin T. Gibbs.sp
2744a775e8fSJustin T. Gibbs(The names
2754a775e8fSJustin T. Gibbs.Li head
2764a775e8fSJustin T. Gibbsand
2774a775e8fSJustin T. Gibbs.Li headp
2784a775e8fSJustin T. Gibbsare user selectable.)
2794a775e8fSJustin T. Gibbs.Pp
2804a775e8fSJustin T. GibbsThe macro
2814a775e8fSJustin T. Gibbs.Nm SLIST_ENTRY
2824a775e8fSJustin T. Gibbsdeclares a structure that connects the elements in
2834a775e8fSJustin T. Gibbsthe list.
2844a775e8fSJustin T. Gibbs.Pp
2854a775e8fSJustin T. GibbsThe macro
2864a775e8fSJustin T. Gibbs.Nm SLIST_INIT
2874a775e8fSJustin T. Gibbsinitializes the list referenced by
2884a775e8fSJustin T. Gibbs.Fa head .
2894a775e8fSJustin T. Gibbs.Pp
2904a775e8fSJustin T. GibbsThe macro
2914a775e8fSJustin T. Gibbs.Nm SLIST_INSERT_HEAD
2924a775e8fSJustin T. Gibbsinserts the new element
2934a775e8fSJustin T. Gibbs.Fa elm
2944a775e8fSJustin T. Gibbsat the head of the list.
2954a775e8fSJustin T. Gibbs.Pp
2964a775e8fSJustin T. GibbsThe macro
2974a775e8fSJustin T. Gibbs.Nm SLIST_INSERT_AFTER
2984a775e8fSJustin T. Gibbsinserts the new element
2994a775e8fSJustin T. Gibbs.Fa elm
3004a775e8fSJustin T. Gibbsafter the element
3014a775e8fSJustin T. Gibbs.Fa listelm .
3024a775e8fSJustin T. Gibbs.Pp
3034a775e8fSJustin T. GibbsThe macro
3044a775e8fSJustin T. Gibbs.Nm SLIST_REMOVE_HEAD
3054a775e8fSJustin T. Gibbsremoves the element
3064a775e8fSJustin T. Gibbs.Fa elm
3074a775e8fSJustin T. Gibbsfrom the head of the list.
3084a775e8fSJustin T. GibbsFor optimum efficiency,
3094a775e8fSJustin T. Gibbselements being removed from the head of the list should explicitly use
3104a775e8fSJustin T. Gibbsthis macro instead of the generic
3114a775e8fSJustin T. Gibbs.Fa SLIST_REMOVE
3124a775e8fSJustin T. Gibbsmacro.
3134a775e8fSJustin T. Gibbs.Pp
3144a775e8fSJustin T. GibbsThe macro
3154a775e8fSJustin T. Gibbs.Nm SLIST_REMOVE
3164a775e8fSJustin T. Gibbsremoves the element
3174a775e8fSJustin T. Gibbs.Fa elm
3184a775e8fSJustin T. Gibbsfrom the list.
3194a775e8fSJustin T. Gibbs.Sh SINGLY-LINKED LIST EXAMPLE
3204a775e8fSJustin T. Gibbs.Bd -literal
3214a775e8fSJustin T. GibbsSLIST_HEAD(slisthead, entry) head;
3224a775e8fSJustin T. Gibbsstruct slisthead *headp;		/* Singly-linked List head. */
3234a775e8fSJustin T. Gibbsstruct entry {
3244a775e8fSJustin T. Gibbs	...
3254a775e8fSJustin T. Gibbs	SLIST_ENTRY(entry) entries;	/* Singly-linked List. */
3264a775e8fSJustin T. Gibbs	...
3274a775e8fSJustin T. Gibbs} *n1, *n2, *n3, *np;
3284a775e8fSJustin T. Gibbs
3294a775e8fSJustin T. GibbsSLIST_INIT(&head);			/* Initialize the list. */
3304a775e8fSJustin T. Gibbs
3314a775e8fSJustin T. Gibbsn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
3324a775e8fSJustin T. GibbsSLIST_INSERT_HEAD(&head, n1, entries);
3334a775e8fSJustin T. Gibbs
3344a775e8fSJustin T. Gibbsn2 = malloc(sizeof(struct entry));	/* Insert after. */
3354a775e8fSJustin T. GibbsSLIST_INSERT_AFTER(n1, n2, entries);
3364a775e8fSJustin T. Gibbs
3374a775e8fSJustin T. GibbsSLIST_REMOVE(&head, n2, entry, entries);/* Deletion. */
3384a775e8fSJustin T. Gibbsfree(n2);
3394a775e8fSJustin T. Gibbs
3404a775e8fSJustin T. Gibbsn3 = head.slh_first;
3414a775e8fSJustin T. GibbsSLIST_REMOVE_HEAD(&head, entries);	/* Deletion. */
3424a775e8fSJustin T. Gibbsfree(n3);
3434a775e8fSJustin T. Gibbs
3444a775e8fSJustin T. Gibbs					/* Forward traversal. */
3454a775e8fSJustin T. Gibbsfor (np = head.slh_first; np != NULL; np = np->entries.sle_next)
3464a775e8fSJustin T. Gibbs	np-> ...
3474a775e8fSJustin T. Gibbs
3484a775e8fSJustin T. Gibbswhile (head.slh_first != NULL) {	/* List Deletion. */
3494a775e8fSJustin T. Gibbs	n1 = head.slh_first;
3504a775e8fSJustin T. Gibbs	SLIST_REMOVE_HEAD(&head, entries);
3514a775e8fSJustin T. Gibbs	free(n1);
3524a775e8fSJustin T. Gibbs}
3534a775e8fSJustin T. Gibbs.Ed
3544a775e8fSJustin T. Gibbs.Sh SINGLY-LINKED TAIL QUEUES
3554a775e8fSJustin T. GibbsA singly-linked tail queue is headed by a structure defined by the
3564a775e8fSJustin T. Gibbs.Nm STAILQ_HEAD
3574a775e8fSJustin T. Gibbsmacro.
3584a775e8fSJustin T. GibbsThis structure contains a pair of pointers,
3594a775e8fSJustin T. Gibbsone to the first element in the tail queue and the other to
3604a775e8fSJustin T. Gibbsthe last element in the tail queue.
3614a775e8fSJustin T. GibbsThe elements are singly linked for minimum space and pointer
3624a775e8fSJustin T. Gibbsmanipulation overhead at the expense of O(n) removal for arbitrary
3634a775e8fSJustin T. Gibbselements.
3644a775e8fSJustin T. GibbsNew elements can be added to the tail queue after an existing element,
3654a775e8fSJustin T. Gibbsat the head of the tail queue, or at the end of the tail queue.
3664a775e8fSJustin T. GibbsA
3674a775e8fSJustin T. Gibbs.Fa STAILQ_HEAD
3684a775e8fSJustin T. Gibbsstructure is declared as follows:
3694a775e8fSJustin T. Gibbs.Bd -literal -offset indent
3704a775e8fSJustin T. GibbsSTAILQ_HEAD(HEADNAME, TYPE) head;
3714a775e8fSJustin T. Gibbs.Ed
3724a775e8fSJustin T. Gibbs.sp
3734a775e8fSJustin T. Gibbswhere
3744a775e8fSJustin T. Gibbs.Li HEADNAME
3754a775e8fSJustin T. Gibbsis the name of the structure to be defined, and
3764a775e8fSJustin T. Gibbs.Li TYPE
3774a775e8fSJustin T. Gibbsis the type of the elements to be linked into the tail queue.
3784a775e8fSJustin T. GibbsA pointer to the head of the tail queue can later be declared as:
3794a775e8fSJustin T. Gibbs.Bd -literal -offset indent
3804a775e8fSJustin T. Gibbsstruct HEADNAME *headp;
3814a775e8fSJustin T. Gibbs.Ed
3824a775e8fSJustin T. Gibbs.sp
3834a775e8fSJustin T. Gibbs(The names
3844a775e8fSJustin T. Gibbs.Li head
3854a775e8fSJustin T. Gibbsand
3864a775e8fSJustin T. Gibbs.Li headp
3874a775e8fSJustin T. Gibbsare user selectable.)
3884a775e8fSJustin T. Gibbs.Pp
3894a775e8fSJustin T. GibbsThe macro
3904a775e8fSJustin T. Gibbs.Nm STAILQ_ENTRY
3914a775e8fSJustin T. Gibbsdeclares a structure that connects the elements in
3924a775e8fSJustin T. Gibbsthe tail queue.
3934a775e8fSJustin T. Gibbs.Pp
3944a775e8fSJustin T. GibbsThe macro
3954a775e8fSJustin T. Gibbs.Nm STAILQ_INIT
3964a775e8fSJustin T. Gibbsinitializes the tail queue referenced by
3974a775e8fSJustin T. Gibbs.Fa head .
3984a775e8fSJustin T. Gibbs.Pp
3994a775e8fSJustin T. GibbsThe macro
4004a775e8fSJustin T. Gibbs.Nm STAILQ_INSERT_HEAD
4014a775e8fSJustin T. Gibbsinserts the new element
4024a775e8fSJustin T. Gibbs.Fa elm
4034a775e8fSJustin T. Gibbsat the head of the tail queue.
4044a775e8fSJustin T. Gibbs.Pp
4054a775e8fSJustin T. GibbsThe macro
4064a775e8fSJustin T. Gibbs.Nm STAILQ_INSERT_TAIL
4074a775e8fSJustin T. Gibbsinserts the new element
4084a775e8fSJustin T. Gibbs.Fa elm
4094a775e8fSJustin T. Gibbsat the end of the tail queue.
4104a775e8fSJustin T. Gibbs.Pp
4114a775e8fSJustin T. GibbsThe macro
4124a775e8fSJustin T. Gibbs.Nm STAILQ_INSERT_AFTER
4134a775e8fSJustin T. Gibbsinserts the new element
4144a775e8fSJustin T. Gibbs.Fa elm
4154a775e8fSJustin T. Gibbsafter the element
4164a775e8fSJustin T. Gibbs.Fa listelm .
4174a775e8fSJustin T. Gibbs.Pp
4184a775e8fSJustin T. GibbsThe macro
4194a775e8fSJustin T. Gibbs.Nm STAILQ_REMOVE_HEAD
4204a775e8fSJustin T. Gibbsremoves the element
4214a775e8fSJustin T. Gibbs.Fa elm
4224a775e8fSJustin T. Gibbsfrom the head of the tail queue.
4234a775e8fSJustin T. GibbsFor optimum efficiency,
4244a775e8fSJustin T. Gibbselements being removed from the head of the tail queue should
4254a775e8fSJustin T. Gibbsuse this macro explicitly rather than the generic
4264a775e8fSJustin T. Gibbs.Fa STAILQ_REMOVE
4274a775e8fSJustin T. Gibbsmacro.
4284a775e8fSJustin T. Gibbs.Pp
4294a775e8fSJustin T. GibbsThe macro
4304a775e8fSJustin T. Gibbs.Nm STAILQ_REMOVE
4314a775e8fSJustin T. Gibbsremoves the element
4324a775e8fSJustin T. Gibbs.Fa elm
4334a775e8fSJustin T. Gibbsfrom the tail queue.
4344a775e8fSJustin T. Gibbs.Sh SINGLY-LINKED TAIL QUEUE EXAMPLE
4354a775e8fSJustin T. Gibbs.Bd -literal
4364a775e8fSJustin T. GibbsSTAILQ_HEAD(stailhead, entry) head;
4374a775e8fSJustin T. Gibbsstruct stailhead *headp;		/* Singly-linked tail queue head. */
4384a775e8fSJustin T. Gibbsstruct entry {
4394a775e8fSJustin T. Gibbs	...
4404a775e8fSJustin T. Gibbs	STAILQ_ENTRY(entry) entries;	/* Tail queue. */
4414a775e8fSJustin T. Gibbs	...
4424a775e8fSJustin T. Gibbs} *n1, *n2, *n3, *np;
4434a775e8fSJustin T. Gibbs
4444a775e8fSJustin T. GibbsSTAILQ_INIT(&head);			/* Initialize the queue. */
4454a775e8fSJustin T. Gibbs
4464a775e8fSJustin T. Gibbsn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
4474a775e8fSJustin T. GibbsSTAILQ_INSERT_HEAD(&head, n1, entries);
4484a775e8fSJustin T. Gibbs
4494a775e8fSJustin T. Gibbsn1 = malloc(sizeof(struct entry));	/* Insert at the tail. */
4504a775e8fSJustin T. GibbsSTAILQ_INSERT_TAIL(&head, n1, entries);
4514a775e8fSJustin T. Gibbs
4524a775e8fSJustin T. Gibbsn2 = malloc(sizeof(struct entry));	/* Insert after. */
4534a775e8fSJustin T. GibbsSTAILQ_INSERT_AFTER(&head, n1, n2, entries);
4544a775e8fSJustin T. Gibbs
4554a775e8fSJustin T. Gibbs					/* Deletion. */
4564a775e8fSJustin T. GibbsSTAILQ_REMOVE(&head, n2, entry, entries);
4574a775e8fSJustin T. Gibbsfree(n2);
4584a775e8fSJustin T. Gibbs
4594a775e8fSJustin T. Gibbs					/* Deletion from the head */
4604a775e8fSJustin T. Gibbsn3 = head.stqh_first;
4614a775e8fSJustin T. GibbsSTAILQ_REMOVE_HEAD(&head, entries);
4624a775e8fSJustin T. Gibbsfree(n3);
4634a775e8fSJustin T. Gibbs
4644a775e8fSJustin T. Gibbs					/* Forward traversal. */
4654a775e8fSJustin T. Gibbsfor (np = head.stqh_first; np != NULL; np = np->entries.stqe_next)
4664a775e8fSJustin T. Gibbs	np-> ...
4674a775e8fSJustin T. Gibbs					/* TailQ Deletion. */
4684a775e8fSJustin T. Gibbswhile (head.stqh_first != NULL) {
4694a775e8fSJustin T. Gibbs	n1 = head.stqh_first;
4704a775e8fSJustin T. Gibbs	TAILQ_REMOVE_HEAD(&head, entries);
4714a775e8fSJustin T. Gibbs	free(n1);
4724a775e8fSJustin T. Gibbs}
4734a775e8fSJustin T. Gibbs					/* Faster TailQ Deletion. */
4744a775e8fSJustin T. Gibbsn1 = head.stqh_first;
4754a775e8fSJustin T. Gibbswhile (n1 != NULL) {
4764a775e8fSJustin T. Gibbs	n2 = n1->entries.stqe_next;
4774a775e8fSJustin T. Gibbs	free(n1);
4784a775e8fSJustin T. Gibbs	n1 = n2;
4794a775e8fSJustin T. Gibbs}
4804a775e8fSJustin T. GibbsSTAILQ_INIT(&head);
4814a775e8fSJustin T. Gibbs.Ed
482afe61c15SRodney W. Grimes.Sh LISTS
483afe61c15SRodney W. GrimesA list is headed by a structure defined by the
484afe61c15SRodney W. Grimes.Nm LIST_HEAD
485afe61c15SRodney W. Grimesmacro.
486afe61c15SRodney W. GrimesThis structure contains a single pointer to the first element
487afe61c15SRodney W. Grimeson the list.
488afe61c15SRodney W. GrimesThe elements are doubly linked so that an arbitrary element can be
489afe61c15SRodney W. Grimesremoved without traversing the list.
4904a775e8fSJustin T. GibbsNew elements can be added to the list after an existing element,
4914a775e8fSJustin T. Gibbsbefore an existing element, or at the head of the list.
492afe61c15SRodney W. GrimesA
493afe61c15SRodney W. Grimes.Fa LIST_HEAD
494afe61c15SRodney W. Grimesstructure is declared as follows:
495afe61c15SRodney W. Grimes.Bd -literal -offset indent
496afe61c15SRodney W. GrimesLIST_HEAD(HEADNAME, TYPE) head;
497afe61c15SRodney W. Grimes.Ed
498afe61c15SRodney W. Grimes.sp
499afe61c15SRodney W. Grimeswhere
500afe61c15SRodney W. Grimes.Fa HEADNAME
501afe61c15SRodney W. Grimesis the name of the structure to be defined, and
502afe61c15SRodney W. Grimes.Fa TYPE
503afe61c15SRodney W. Grimesis the type of the elements to be linked into the list.
504afe61c15SRodney W. GrimesA pointer to the head of the list can later be declared as:
505afe61c15SRodney W. Grimes.Bd -literal -offset indent
506afe61c15SRodney W. Grimesstruct HEADNAME *headp;
507afe61c15SRodney W. Grimes.Ed
508afe61c15SRodney W. Grimes.sp
509afe61c15SRodney W. Grimes(The names
510afe61c15SRodney W. Grimes.Li head
511afe61c15SRodney W. Grimesand
512afe61c15SRodney W. Grimes.Li headp
513afe61c15SRodney W. Grimesare user selectable.)
514afe61c15SRodney W. Grimes.Pp
515afe61c15SRodney W. GrimesThe macro
516afe61c15SRodney W. Grimes.Nm LIST_ENTRY
517afe61c15SRodney W. Grimesdeclares a structure that connects the elements in
518afe61c15SRodney W. Grimesthe list.
519afe61c15SRodney W. Grimes.Pp
520afe61c15SRodney W. GrimesThe macro
521afe61c15SRodney W. Grimes.Nm LIST_INIT
522afe61c15SRodney W. Grimesinitializes the list referenced by
523afe61c15SRodney W. Grimes.Fa head .
524afe61c15SRodney W. Grimes.Pp
525afe61c15SRodney W. GrimesThe macro
526afe61c15SRodney W. Grimes.Nm LIST_INSERT_HEAD
527afe61c15SRodney W. Grimesinserts the new element
528afe61c15SRodney W. Grimes.Fa elm
529afe61c15SRodney W. Grimesat the head of the list.
530afe61c15SRodney W. Grimes.Pp
531afe61c15SRodney W. GrimesThe macro
532afe61c15SRodney W. Grimes.Nm LIST_INSERT_AFTER
533afe61c15SRodney W. Grimesinserts the new element
534afe61c15SRodney W. Grimes.Fa elm
535afe61c15SRodney W. Grimesafter the element
536afe61c15SRodney W. Grimes.Fa listelm .
537afe61c15SRodney W. Grimes.Pp
538afe61c15SRodney W. GrimesThe macro
5397658b0a2SJustin T. Gibbs.Nm LIST_INSERT_BEFORE
5407658b0a2SJustin T. Gibbsinserts the new element
5417658b0a2SJustin T. Gibbs.Fa elm
5427658b0a2SJustin T. Gibbsbefore the element
5437658b0a2SJustin T. Gibbs.Fa listelm .
5447658b0a2SJustin T. Gibbs.Pp
5457658b0a2SJustin T. GibbsThe macro
546afe61c15SRodney W. Grimes.Nm LIST_REMOVE
547afe61c15SRodney W. Grimesremoves the element
548afe61c15SRodney W. Grimes.Fa elm
549afe61c15SRodney W. Grimesfrom the list.
550afe61c15SRodney W. Grimes.Sh LIST EXAMPLE
551afe61c15SRodney W. Grimes.Bd -literal
552afe61c15SRodney W. GrimesLIST_HEAD(listhead, entry) head;
553afe61c15SRodney W. Grimesstruct listhead *headp;		/* List head. */
554afe61c15SRodney W. Grimesstruct entry {
555afe61c15SRodney W. Grimes	...
556afe61c15SRodney W. Grimes	LIST_ENTRY(entry) entries;	/* List. */
557afe61c15SRodney W. Grimes	...
5587658b0a2SJustin T. Gibbs} *n1, *n2, *n3, *np;
559afe61c15SRodney W. Grimes
560afe61c15SRodney W. GrimesLIST_INIT(&head);			/* Initialize the list. */
561afe61c15SRodney W. Grimes
562afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
563afe61c15SRodney W. GrimesLIST_INSERT_HEAD(&head, n1, entries);
564afe61c15SRodney W. Grimes
565afe61c15SRodney W. Grimesn2 = malloc(sizeof(struct entry));	/* Insert after. */
566afe61c15SRodney W. GrimesLIST_INSERT_AFTER(n1, n2, entries);
5677658b0a2SJustin T. Gibbs
5687658b0a2SJustin T. Gibbsn3 = malloc(sizeof(struct entry));	/* Insert before. */
5697658b0a2SJustin T. GibbsLIST_INSERT_BEFORE(n2, n3, entries);
5707658b0a2SJustin T. Gibbs
5717658b0a2SJustin T. GibbsLIST_REMOVE(n2, entries);		/* Deletion. */
5727658b0a2SJustin T. Gibbsfree(n2);
5737658b0a2SJustin T. Gibbs
574afe61c15SRodney W. Grimes					/* Forward traversal. */
575afe61c15SRodney W. Grimesfor (np = head.lh_first; np != NULL; np = np->entries.le_next)
576afe61c15SRodney W. Grimes	np-> ...
577afe61c15SRodney W. Grimes
5787658b0a2SJustin T. Gibbswhile (head.lh_first != NULL) {		/* List Deletion. */
5797658b0a2SJustin T. Gibbs	n1 = head.lh_first;
5807658b0a2SJustin T. Gibbs	LIST_REMOVE(n1, entries);
5817658b0a2SJustin T. Gibbs	free(n1);
5827658b0a2SJustin T. Gibbs}
5837658b0a2SJustin T. Gibbs
5847658b0a2SJustin T. Gibbsn1 = head.lh_first;			/* Faster List Delete. */
5857658b0a2SJustin T. Gibbswhile (n1 != NULL) {
5867658b0a2SJustin T. Gibbs	n2 = n1->entires.le_next;
5877658b0a2SJustin T. Gibbs	free(n1);
5887658b0a2SJustin T. Gibbs	n1 = n2;
5897658b0a2SJustin T. Gibbs}
5907658b0a2SJustin T. GibbsLIST_INIT(&head);
5917658b0a2SJustin T. Gibbs
592afe61c15SRodney W. Grimes.Ed
593afe61c15SRodney W. Grimes.Sh TAIL QUEUES
594afe61c15SRodney W. GrimesA tail queue is headed by a structure defined by the
595afe61c15SRodney W. Grimes.Nm TAILQ_HEAD
596afe61c15SRodney W. Grimesmacro.
597afe61c15SRodney W. GrimesThis structure contains a pair of pointers,
598afe61c15SRodney W. Grimesone to the first element in the tail queue and the other to
599afe61c15SRodney W. Grimesthe last element in the tail queue.
600afe61c15SRodney W. GrimesThe elements are doubly linked so that an arbitrary element can be
601afe61c15SRodney W. Grimesremoved without traversing the tail queue.
602afe61c15SRodney W. GrimesNew elements can be added to the tail queue after an existing element,
6034a775e8fSJustin T. Gibbsbefore an existing element, at the head of the tail queue,
6044a775e8fSJustin T. Gibbsor at the end of the tail queue.
605afe61c15SRodney W. GrimesA
606afe61c15SRodney W. Grimes.Fa TAILQ_HEAD
607afe61c15SRodney W. Grimesstructure is declared as follows:
608afe61c15SRodney W. Grimes.Bd -literal -offset indent
609afe61c15SRodney W. GrimesTAILQ_HEAD(HEADNAME, TYPE) head;
610afe61c15SRodney W. Grimes.Ed
611afe61c15SRodney W. Grimes.sp
612afe61c15SRodney W. Grimeswhere
613afe61c15SRodney W. Grimes.Li HEADNAME
614afe61c15SRodney W. Grimesis the name of the structure to be defined, and
615afe61c15SRodney W. Grimes.Li TYPE
616afe61c15SRodney W. Grimesis the type of the elements to be linked into the tail queue.
617afe61c15SRodney W. GrimesA pointer to the head of the tail queue can later be declared as:
618afe61c15SRodney W. Grimes.Bd -literal -offset indent
619afe61c15SRodney W. Grimesstruct HEADNAME *headp;
620afe61c15SRodney W. Grimes.Ed
621afe61c15SRodney W. Grimes.sp
622afe61c15SRodney W. Grimes(The names
623afe61c15SRodney W. Grimes.Li head
624afe61c15SRodney W. Grimesand
625afe61c15SRodney W. Grimes.Li headp
626afe61c15SRodney W. Grimesare user selectable.)
627afe61c15SRodney W. Grimes.Pp
628afe61c15SRodney W. GrimesThe macro
629afe61c15SRodney W. Grimes.Nm TAILQ_ENTRY
630afe61c15SRodney W. Grimesdeclares a structure that connects the elements in
631afe61c15SRodney W. Grimesthe tail queue.
632afe61c15SRodney W. Grimes.Pp
633afe61c15SRodney W. GrimesThe macro
634afe61c15SRodney W. Grimes.Nm TAILQ_INIT
635afe61c15SRodney W. Grimesinitializes the tail queue referenced by
636afe61c15SRodney W. Grimes.Fa head .
637afe61c15SRodney W. Grimes.Pp
638afe61c15SRodney W. GrimesThe macro
639afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_HEAD
640afe61c15SRodney W. Grimesinserts the new element
641afe61c15SRodney W. Grimes.Fa elm
642afe61c15SRodney W. Grimesat the head of the tail queue.
643afe61c15SRodney W. Grimes.Pp
644afe61c15SRodney W. GrimesThe macro
645afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_TAIL
646afe61c15SRodney W. Grimesinserts the new element
647afe61c15SRodney W. Grimes.Fa elm
648afe61c15SRodney W. Grimesat the end of the tail queue.
649afe61c15SRodney W. Grimes.Pp
650afe61c15SRodney W. GrimesThe macro
651afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_AFTER
652afe61c15SRodney W. Grimesinserts the new element
653afe61c15SRodney W. Grimes.Fa elm
654afe61c15SRodney W. Grimesafter the element
655afe61c15SRodney W. Grimes.Fa listelm .
656afe61c15SRodney W. Grimes.Pp
657afe61c15SRodney W. GrimesThe macro
6587658b0a2SJustin T. Gibbs.Nm TAILQ_INSERT_BEFORE
6597658b0a2SJustin T. Gibbsinserts the new element
6607658b0a2SJustin T. Gibbs.Fa elm
6617658b0a2SJustin T. Gibbsbefore the element
6627658b0a2SJustin T. Gibbs.Fa listelm .
6637658b0a2SJustin T. Gibbs.Pp
6647658b0a2SJustin T. GibbsThe macro
665afe61c15SRodney W. Grimes.Nm TAILQ_REMOVE
666afe61c15SRodney W. Grimesremoves the element
667afe61c15SRodney W. Grimes.Fa elm
668afe61c15SRodney W. Grimesfrom the tail queue.
669afe61c15SRodney W. Grimes.Sh TAIL QUEUE EXAMPLE
670afe61c15SRodney W. Grimes.Bd -literal
671afe61c15SRodney W. GrimesTAILQ_HEAD(tailhead, entry) head;
672afe61c15SRodney W. Grimesstruct tailhead *headp;		/* Tail queue head. */
673afe61c15SRodney W. Grimesstruct entry {
674afe61c15SRodney W. Grimes	...
675afe61c15SRodney W. Grimes	TAILQ_ENTRY(entry) entries;	/* Tail queue. */
676afe61c15SRodney W. Grimes	...
6777658b0a2SJustin T. Gibbs} *n1, *n2, *n3, *np;
678afe61c15SRodney W. Grimes
679afe61c15SRodney W. GrimesTAILQ_INIT(&head);			/* Initialize the queue. */
680afe61c15SRodney W. Grimes
681afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
682afe61c15SRodney W. GrimesTAILQ_INSERT_HEAD(&head, n1, entries);
683afe61c15SRodney W. Grimes
684afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the tail. */
685afe61c15SRodney W. GrimesTAILQ_INSERT_TAIL(&head, n1, entries);
686afe61c15SRodney W. Grimes
687afe61c15SRodney W. Grimesn2 = malloc(sizeof(struct entry));	/* Insert after. */
688afe61c15SRodney W. GrimesTAILQ_INSERT_AFTER(&head, n1, n2, entries);
6897658b0a2SJustin T. Gibbs
6907658b0a2SJustin T. Gibbsn3 = malloc(sizeof(struct entry));	/* Insert before. */
6913652ff55SJustin T. GibbsTAILQ_INSERT_BEFORE(n2, n3, entries);
6927658b0a2SJustin T. Gibbs
6937658b0a2SJustin T. GibbsTAILQ_REMOVE(&head, n2, entries);	/* Deletion. */
6947658b0a2SJustin T. Gibbsfree(n2);
695afe61c15SRodney W. Grimes					/* Forward traversal. */
696afe61c15SRodney W. Grimesfor (np = head.tqh_first; np != NULL; np = np->entries.tqe_next)
697afe61c15SRodney W. Grimes	np-> ...
6987658b0a2SJustin T. Gibbs					/* TailQ Deletion. */
6997658b0a2SJustin T. Gibbswhile (head.tqh_first != NULL) {
7007658b0a2SJustin T. Gibbs	n1 = head.tqh_first;
701afe61c15SRodney W. Grimes	TAILQ_REMOVE(&head, head.tqh_first, entries);
7027658b0a2SJustin T. Gibbs	free(n1);
7037658b0a2SJustin T. Gibbs}
7047658b0a2SJustin T. Gibbs					/* Faster TailQ Deletion. */
7057658b0a2SJustin T. Gibbsn1 = head.tqh_first;
7067658b0a2SJustin T. Gibbswhile (n1 != NULL) {
7077658b0a2SJustin T. Gibbs	n2 = n1->entries.tqe_next;
7087658b0a2SJustin T. Gibbs	free(n1);
7097658b0a2SJustin T. Gibbs	n1 = n2;
7107658b0a2SJustin T. Gibbs}
7117658b0a2SJustin T. GibbsTAILQ_INIT(&head);
712afe61c15SRodney W. Grimes.Ed
713afe61c15SRodney W. Grimes.Sh CIRCULAR QUEUES
714afe61c15SRodney W. GrimesA circular queue is headed by a structure defined by the
715afe61c15SRodney W. Grimes.Nm CIRCLEQ_HEAD
716afe61c15SRodney W. Grimesmacro.
717afe61c15SRodney W. GrimesThis structure contains a pair of pointers,
718afe61c15SRodney W. Grimesone to the first element in the circular queue and the other to the
719afe61c15SRodney W. Grimeslast element in the circular queue.
720afe61c15SRodney W. GrimesThe elements are doubly linked so that an arbitrary element can be
721afe61c15SRodney W. Grimesremoved without traversing the queue.
722afe61c15SRodney W. GrimesNew elements can be added to the queue after an existing element,
723afe61c15SRodney W. Grimesbefore an existing element, at the head of the queue, or at the end
724afe61c15SRodney W. Grimesof the queue.
725afe61c15SRodney W. GrimesA
726afe61c15SRodney W. Grimes.Fa CIRCLEQ_HEAD
727afe61c15SRodney W. Grimesstructure is declared as follows:
728afe61c15SRodney W. Grimes.Bd -literal -offset indent
729afe61c15SRodney W. GrimesCIRCLEQ_HEAD(HEADNAME, TYPE) head;
730afe61c15SRodney W. Grimes.Ed
731afe61c15SRodney W. Grimes.sp
732afe61c15SRodney W. Grimeswhere
733afe61c15SRodney W. Grimes.Li HEADNAME
734afe61c15SRodney W. Grimesis the name of the structure to be defined, and
735afe61c15SRodney W. Grimes.Li TYPE
736afe61c15SRodney W. Grimesis the type of the elements to be linked into the circular queue.
737afe61c15SRodney W. GrimesA pointer to the head of the circular queue can later be declared as:
738afe61c15SRodney W. Grimes.Bd -literal -offset indent
739afe61c15SRodney W. Grimesstruct HEADNAME *headp;
740afe61c15SRodney W. Grimes.Ed
741afe61c15SRodney W. Grimes.sp
742afe61c15SRodney W. Grimes(The names
743afe61c15SRodney W. Grimes.Li head
744afe61c15SRodney W. Grimesand
745afe61c15SRodney W. Grimes.Li headp
746afe61c15SRodney W. Grimesare user selectable.)
747afe61c15SRodney W. Grimes.Pp
748afe61c15SRodney W. GrimesThe macro
749afe61c15SRodney W. Grimes.Nm CIRCLEQ_ENTRY
750afe61c15SRodney W. Grimesdeclares a structure that connects the elements in
751afe61c15SRodney W. Grimesthe circular queue.
752afe61c15SRodney W. Grimes.Pp
753afe61c15SRodney W. GrimesThe macro
754afe61c15SRodney W. Grimes.Nm CIRCLEQ_INIT
755afe61c15SRodney W. Grimesinitializes the circular queue referenced by
756afe61c15SRodney W. Grimes.Fa head .
757afe61c15SRodney W. Grimes.Pp
758afe61c15SRodney W. GrimesThe macro
759afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_HEAD
760afe61c15SRodney W. Grimesinserts the new element
761afe61c15SRodney W. Grimes.Fa elm
762afe61c15SRodney W. Grimesat the head of the circular queue.
763afe61c15SRodney W. Grimes.Pp
764afe61c15SRodney W. GrimesThe macro
765afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_TAIL
766afe61c15SRodney W. Grimesinserts the new element
767afe61c15SRodney W. Grimes.Fa elm
768afe61c15SRodney W. Grimesat the end of the circular queue.
769afe61c15SRodney W. Grimes.Pp
770afe61c15SRodney W. GrimesThe macro
771afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_AFTER
772afe61c15SRodney W. Grimesinserts the new element
773afe61c15SRodney W. Grimes.Fa elm
774afe61c15SRodney W. Grimesafter the element
775afe61c15SRodney W. Grimes.Fa listelm .
776afe61c15SRodney W. Grimes.Pp
777afe61c15SRodney W. GrimesThe macro
778afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_BEFORE
779afe61c15SRodney W. Grimesinserts the new element
780afe61c15SRodney W. Grimes.Fa elm
781afe61c15SRodney W. Grimesbefore the element
782afe61c15SRodney W. Grimes.Fa listelm .
783afe61c15SRodney W. Grimes.Pp
784afe61c15SRodney W. GrimesThe macro
785afe61c15SRodney W. Grimes.Nm CIRCLEQ_REMOVE
786afe61c15SRodney W. Grimesremoves the element
787afe61c15SRodney W. Grimes.Fa elm
788afe61c15SRodney W. Grimesfrom the circular queue.
789afe61c15SRodney W. Grimes.Sh CIRCULAR QUEUE EXAMPLE
790afe61c15SRodney W. Grimes.Bd -literal
791afe61c15SRodney W. GrimesCIRCLEQ_HEAD(circleq, entry) head;
792afe61c15SRodney W. Grimesstruct circleq *headp;			/* Circular queue head. */
793afe61c15SRodney W. Grimesstruct entry {
794afe61c15SRodney W. Grimes	...
795afe61c15SRodney W. Grimes	CIRCLEQ_ENTRY entries;		/* Circular queue. */
796afe61c15SRodney W. Grimes	...
797afe61c15SRodney W. Grimes} *n1, *n2, *np;
798afe61c15SRodney W. Grimes
799afe61c15SRodney W. GrimesCIRCLEQ_INIT(&head);			/* Initialize the circular queue. */
800afe61c15SRodney W. Grimes
801afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
802afe61c15SRodney W. GrimesCIRCLEQ_INSERT_HEAD(&head, n1, entries);
803afe61c15SRodney W. Grimes
804afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the tail. */
805afe61c15SRodney W. GrimesCIRCLEQ_INSERT_TAIL(&head, n1, entries);
806afe61c15SRodney W. Grimes
807afe61c15SRodney W. Grimesn2 = malloc(sizeof(struct entry));	/* Insert after. */
808afe61c15SRodney W. GrimesCIRCLEQ_INSERT_AFTER(&head, n1, n2, entries);
809afe61c15SRodney W. Grimes
810afe61c15SRodney W. Grimesn2 = malloc(sizeof(struct entry));	/* Insert before. */
811afe61c15SRodney W. GrimesCIRCLEQ_INSERT_BEFORE(&head, n1, n2, entries);
8127658b0a2SJustin T. Gibbs
8137658b0a2SJustin T. GibbsCIRCLEQ_REMOVE(&head, n1, entries);	/* Deletion. */
8147658b0a2SJustin T. Gibbsfree(n1);
815afe61c15SRodney W. Grimes					/* Forward traversal. */
816afe61c15SRodney W. Grimesfor (np = head.cqh_first; np != (void *)&head; np = np->entries.cqe_next)
817afe61c15SRodney W. Grimes	np-> ...
818afe61c15SRodney W. Grimes					/* Reverse traversal. */
819afe61c15SRodney W. Grimesfor (np = head.cqh_last; np != (void *)&head; np = np->entries.cqe_prev)
820afe61c15SRodney W. Grimes	np-> ...
8217658b0a2SJustin T. Gibbs					/* CircleQ Deletion. */
8227658b0a2SJustin T. Gibbswhile (head.cqh_first != (void *)&head) {
8237658b0a2SJustin T. Gibbs	n1 = head.cqh_first;
824afe61c15SRodney W. Grimes	CIRCLEQ_REMOVE(&head, head.cqh_first, entries);
8257658b0a2SJustin T. Gibbs	free(n1);
8267658b0a2SJustin T. Gibbs}
8277658b0a2SJustin T. Gibbs					/* Faster CircleQ Deletion. */
8287658b0a2SJustin T. Gibbsn1 = head.cqh_first;
8297658b0a2SJustin T. Gibbswhile (n1 != (void *)&head) {
8307658b0a2SJustin T. Gibbs	n2 = n1->entries.cqh_next;
8317658b0a2SJustin T. Gibbs	free(n1);
8327658b0a2SJustin T. Gibbs	n1 = n2;
8337658b0a2SJustin T. Gibbs}
8347658b0a2SJustin T. GibbsCIRCLEQ_INIT(&head);
835afe61c15SRodney W. Grimes.Ed
836afe61c15SRodney W. Grimes.Sh HISTORY
837afe61c15SRodney W. GrimesThe
838afe61c15SRodney W. Grimes.Nm queue
839afe61c15SRodney W. Grimesfunctions first appeared in 4.4BSD.
840