xref: /freebsd/share/man/man3/queue.3 (revision 8f20a914b601e2eda8f5f23fcded8b64bff35812)
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.\"
34d3df5ce1SMike Pritchard.Dd January 24, 1994
35afe61c15SRodney W. Grimes.Dt QUEUE 3
36afe61c15SRodney W. Grimes.Os BSD 4
37afe61c15SRodney W. Grimes.Sh NAME
38aea88892SPoul-Henning Kamp.Nm SLIST_EMPTY ,
394a775e8fSJustin T. Gibbs.Nm SLIST_ENTRY ,
40aea88892SPoul-Henning Kamp.Nm SLIST_FIRST ,
414a775e8fSJustin T. Gibbs.Nm SLIST_HEAD ,
424a775e8fSJustin T. Gibbs.Nm SLIST_INIT ,
434a775e8fSJustin T. Gibbs.Nm SLIST_INSERT_AFTER ,
444a775e8fSJustin T. Gibbs.Nm SLIST_INSERT_HEAD ,
45aea88892SPoul-Henning Kamp.Nm SLIST_NEXT ,
464a775e8fSJustin T. Gibbs.Nm SLIST_REMOVE_HEAD ,
474a775e8fSJustin T. Gibbs.Nm SLIST_REMOVE ,
484a775e8fSJustin T. Gibbs.Nm STAILQ_ENTRY ,
494a775e8fSJustin T. Gibbs.Nm STAILQ_HEAD ,
504a775e8fSJustin T. Gibbs.Nm STAILQ_INIT ,
514a775e8fSJustin T. Gibbs.Nm STAILQ_INSERT_AFTER ,
524a775e8fSJustin T. Gibbs.Nm STAILQ_INSERT_HEAD ,
534a775e8fSJustin T. Gibbs.Nm STAILQ_INSERT_TAIL ,
544a775e8fSJustin T. Gibbs.Nm STAILQ_REMOVE_HEAD ,
554a775e8fSJustin T. Gibbs.Nm STAILQ_REMOVE ,
56afe61c15SRodney W. Grimes.Nm LIST_ENTRY ,
57afe61c15SRodney W. Grimes.Nm LIST_HEAD ,
58afe61c15SRodney W. Grimes.Nm LIST_INIT ,
59afe61c15SRodney W. Grimes.Nm LIST_INSERT_AFTER ,
607658b0a2SJustin T. Gibbs.Nm LIST_INSERT_BEFORE ,
61afe61c15SRodney W. Grimes.Nm LIST_INSERT_HEAD ,
62afe61c15SRodney W. Grimes.Nm LIST_REMOVE ,
63c5c15c16SPoul-Henning Kamp.Nm TAILQ_EMPTY ,
64afe61c15SRodney W. Grimes.Nm TAILQ_ENTRY ,
65c5c15c16SPoul-Henning Kamp.Nm TAILQ_FIRST ,
66afe61c15SRodney W. Grimes.Nm TAILQ_HEAD ,
67afe61c15SRodney W. Grimes.Nm TAILQ_INIT ,
68afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_AFTER ,
697658b0a2SJustin T. Gibbs.Nm TAILQ_INSERT_BEFORE ,
70afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_HEAD ,
71afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_TAIL ,
72c5c15c16SPoul-Henning Kamp.Nm TAILQ_LAST ,
73c5c15c16SPoul-Henning Kamp.Nm TAILQ_NEXT ,
74afe61c15SRodney W. Grimes.Nm TAILQ_REMOVE ,
75afe61c15SRodney W. Grimes.Nm CIRCLEQ_ENTRY ,
76afe61c15SRodney W. Grimes.Nm CIRCLEQ_HEAD ,
77afe61c15SRodney W. Grimes.Nm CIRCLEQ_INIT ,
78afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_AFTER ,
79afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_BEFORE ,
80afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_HEAD ,
81afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_TAIL ,
82afe61c15SRodney W. Grimes.Nm CIRCLEQ_REMOVE
834a775e8fSJustin T. Gibbs.Nd implementations of singly-linked lists, singly-linked tail queues,
844a775e8fSJustin T. Gibbslists, tail queues, and circular queues
85afe61c15SRodney W. Grimes.Sh SYNOPSIS
86afe61c15SRodney W. Grimes.Fd #include <sys/queue.h>
878f20a914SMike Pritchard.\"
88aea88892SPoul-Henning Kamp.Fn SLIST_EMPTY "SLIST_HEAD *head"
894a775e8fSJustin T. Gibbs.Fn SLIST_ENTRY "TYPE"
90aea88892SPoul-Henning Kamp.Fn SLIST_FIRST "SLIST_HEAD *head"
914a775e8fSJustin T. Gibbs.Fn SLIST_HEAD "HEADNAME" "TYPE"
924a775e8fSJustin T. Gibbs.Fn SLIST_INIT "SLIST_HEAD *head"
934a775e8fSJustin T. Gibbs.Fn SLIST_INSERT_AFTER "TYPE *listelm" "TYPE *elm" "SLIST_ENTRY NAME"
944a775e8fSJustin T. Gibbs.Fn SLIST_INSERT_HEAD "SLIST_HEAD *head" "TYPE *elm" "SLIST_ENTRY NAME"
95aea88892SPoul-Henning Kamp.Fn SLIST_NEXT "TYPE *elm" "SLIST_ENTRY NAME"
964a775e8fSJustin T. Gibbs.Fn SLIST_REMOVE_HEAD "SLIST_HEAD *head" "SLIST_ENTRY NAME"
974a775e8fSJustin T. Gibbs.Fn SLIST_REMOVE "SLIST_HEAD *head" "TYPE *elm" "TYPE" "SLIST_ENTRY NAME"
988f20a914SMike Pritchard.\"
994a775e8fSJustin T. Gibbs.Fn STAILQ_ENTRY "TYPE"
1004a775e8fSJustin T. Gibbs.Fn STAILQ_HEAD "HEADNAME" "TYPE"
1014a775e8fSJustin T. Gibbs.Fn STAILQ_INIT "STAILQ_HEAD *head"
1024a775e8fSJustin T. Gibbs.Fn STAILQ_INSERT_AFTER "STAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "STAILQ_ENTRY NAME"
1034a775e8fSJustin T. Gibbs.Fn STAILQ_INSERT_HEAD "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
1044a775e8fSJustin T. Gibbs.Fn STAILQ_INSERT_TAIL "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
1054a775e8fSJustin T. Gibbs.Fn STAILQ_REMOVE_HEAD "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
1064a775e8fSJustin T. Gibbs.Fn STAILQ_REMOVE "STAILQ_HEAD *head" "TYPE *elm" "TYPE" "STAILQ_ENTRY NAME"
1078f20a914SMike Pritchard.\"
108afe61c15SRodney W. Grimes.Fn LIST_ENTRY "TYPE"
109afe61c15SRodney W. Grimes.Fn LIST_HEAD "HEADNAME" "TYPE"
110afe61c15SRodney W. Grimes.Fn LIST_INIT "LIST_HEAD *head"
1114a775e8fSJustin T. Gibbs.Fn LIST_INSERT_AFTER "TYPE *listelm" "TYPE *elm" "LIST_ENTRY NAME"
1124a775e8fSJustin T. Gibbs.Fn LIST_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "LIST_ENTRY NAME"
113afe61c15SRodney W. Grimes.Fn LIST_INSERT_HEAD "LIST_HEAD *head" "TYPE *elm" "LIST_ENTRY NAME"
114afe61c15SRodney W. Grimes.Fn LIST_REMOVE "TYPE *elm" "LIST_ENTRY NAME"
1158f20a914SMike Pritchard.\"
116c5c15c16SPoul-Henning Kamp.Fn TAILQ_EMPTY "TAILQ_HEAD *head"
117afe61c15SRodney W. Grimes.Fn TAILQ_ENTRY "TYPE"
118c5c15c16SPoul-Henning Kamp.Fn TAILQ_FIRST "TAILQ_HEAD *head"
119afe61c15SRodney W. Grimes.Fn TAILQ_HEAD "HEADNAME" "TYPE"
120afe61c15SRodney W. Grimes.Fn TAILQ_INIT "TAILQ_HEAD *head"
121afe61c15SRodney W. Grimes.Fn TAILQ_INSERT_AFTER "TAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME"
1223652ff55SJustin T. Gibbs.Fn TAILQ_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME"
123afe61c15SRodney W. Grimes.Fn TAILQ_INSERT_HEAD "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
124afe61c15SRodney W. Grimes.Fn TAILQ_INSERT_TAIL "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
125c5c15c16SPoul-Henning Kamp.Fn TAILQ_LAST "TAILQ_HEAD *head"
126c5c15c16SPoul-Henning Kamp.Fn TAILQ_NEXT "TYPE *elm" "TAILQ_ENTRY NAME"
127afe61c15SRodney W. Grimes.Fn TAILQ_REMOVE "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
1288f20a914SMike Pritchard.\"
129afe61c15SRodney W. Grimes.Fn CIRCLEQ_ENTRY "TYPE"
130afe61c15SRodney W. Grimes.Fn CIRCLEQ_HEAD "HEADNAME" "TYPE"
131afe61c15SRodney W. Grimes.Fn CIRCLEQ_INIT "CIRCLEQ_HEAD *head"
132afe61c15SRodney W. Grimes.Fn CIRCLEQ_INSERT_AFTER "CIRCLEQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
133afe61c15SRodney W. Grimes.Fn CIRCLEQ_INSERT_BEFORE "CIRCLEQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
134afe61c15SRodney W. Grimes.Fn CIRCLEQ_INSERT_HEAD "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
135afe61c15SRodney W. Grimes.Fn CIRCLEQ_INSERT_TAIL "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
136afe61c15SRodney W. Grimes.Fn CIRCLEQ_REMOVE "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
137afe61c15SRodney W. Grimes.Sh DESCRIPTION
1384a775e8fSJustin T. GibbsThese macros define and operate on five types of data structures:
1394a775e8fSJustin T. Gibbssingly-linked lists, singly-linked tail queues, lists, tail queues,
1404a775e8fSJustin T. Gibbsand circular queues.
1414a775e8fSJustin T. GibbsAll five structures support the following functionality:
142afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
143afe61c15SRodney W. Grimes.It
144afe61c15SRodney W. GrimesInsertion of a new entry at the head of the list.
145afe61c15SRodney W. Grimes.It
146afe61c15SRodney W. GrimesInsertion of a new entry after any element in the list.
147afe61c15SRodney W. Grimes.It
1484a775e8fSJustin T. GibbsO(1) removal of an entry from the head of the list.
1497658b0a2SJustin T. Gibbs.It
1504a775e8fSJustin T. GibbsO(n) removal of any entry in the list.
151afe61c15SRodney W. Grimes.It
152afe61c15SRodney W. GrimesForward traversal through the list.
153afe61c15SRodney W. Grimes.El
154afe61c15SRodney W. Grimes.Pp
1554a775e8fSJustin T. GibbsSingly-linked lists are the simplest of the five data structures
1564a775e8fSJustin T. Gibbsand support only the above functionality.
1574a775e8fSJustin T. GibbsSingly-linked lists are ideal for applications with large datasets
1584a775e8fSJustin T. Gibbsand few or no removals,
1594a775e8fSJustin T. Gibbsor for implementing a LIFO queue.
1604a775e8fSJustin T. Gibbs.Pp
1614a775e8fSJustin T. GibbsSingly-linked tail queues add the following functionality:
1624a775e8fSJustin T. Gibbs.Bl -enum -compact -offset indent
1634a775e8fSJustin T. Gibbs.It
1644a775e8fSJustin T. GibbsEntries can be added at the end of a list.
1654a775e8fSJustin T. Gibbs.El
1664a775e8fSJustin T. GibbsHowever:
1674a775e8fSJustin T. Gibbs.Bl -enum -compact -offset indent
1684a775e8fSJustin T. Gibbs.It
1694a775e8fSJustin T. GibbsAll list insertions must specify the head of the list.
1704a775e8fSJustin T. Gibbs.It
1714a775e8fSJustin T. GibbsEach head entry requires two pointers rather than one.
1724a775e8fSJustin T. Gibbs.It
1734a775e8fSJustin T. GibbsCode size is about 15% greater and operations run about 20% slower
1744a775e8fSJustin T. Gibbsthan singly-linked lists.
1754a775e8fSJustin T. Gibbs.El
1764a775e8fSJustin T. Gibbs.Pp
1774a775e8fSJustin T. GibbsSingly-linked tailqs are ideal for applications with large datasets and
1784a775e8fSJustin T. Gibbsfew or no removals,
1794a775e8fSJustin T. Gibbsor for implementing a FIFO queue.
1804a775e8fSJustin T. Gibbs.Pp
1814a775e8fSJustin T. GibbsAll doubly linked types of data structures (lists, tail queues, and circle
1824a775e8fSJustin T. Gibbsqueues) additionally allow:
1834a775e8fSJustin T. Gibbs.Bl -enum -compact -offset indent
1844a775e8fSJustin T. Gibbs.It
1854a775e8fSJustin T. GibbsInsertion of a new entry before any element in the list.
1864a775e8fSJustin T. Gibbs.It
1874a775e8fSJustin T. GibbsO(1) removal of any entry in the list.
1884a775e8fSJustin T. Gibbs.El
1894a775e8fSJustin T. GibbsHowever:
1904a775e8fSJustin T. Gibbs.Bl -enum -compact -offset indent
1914a775e8fSJustin T. Gibbs.It
1924a775e8fSJustin T. GibbsEach elements requires two pointers rather than one.
1934a775e8fSJustin T. Gibbs.It
1944a775e8fSJustin T. GibbsCode size and execution time of operations (except for removal) is about
1954a775e8fSJustin T. Gibbstwice that of the singly-linked data-structures.
1964a775e8fSJustin T. Gibbs.El
1974a775e8fSJustin T. Gibbs.Pp
1984a775e8fSJustin T. GibbsLinked lists are the simplest of the doubly linked data structures and support
1994a775e8fSJustin T. Gibbsonly the above functionality over singly-linked lists.
200afe61c15SRodney W. Grimes.Pp
201afe61c15SRodney W. GrimesTail queues add the following functionality:
202afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
203afe61c15SRodney W. Grimes.It
204afe61c15SRodney W. GrimesEntries can be added at the end of a list.
205afe61c15SRodney W. Grimes.El
206afe61c15SRodney W. GrimesHowever:
207afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
208afe61c15SRodney W. Grimes.It
209afe61c15SRodney W. GrimesAll list insertions and removals must specify the head of the list.
210afe61c15SRodney W. Grimes.It
211afe61c15SRodney W. GrimesEach head entry requires two pointers rather than one.
212afe61c15SRodney W. Grimes.It
213afe61c15SRodney W. GrimesCode size is about 15% greater and operations run about 20% slower
2144a775e8fSJustin T. Gibbsthan singly-linked lists.
215afe61c15SRodney W. Grimes.El
216afe61c15SRodney W. Grimes.Pp
217afe61c15SRodney W. GrimesCircular queues add the following functionality:
218afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
219afe61c15SRodney W. Grimes.It
220afe61c15SRodney W. GrimesEntries can be added at the end of a list.
221afe61c15SRodney W. Grimes.It
222afe61c15SRodney W. GrimesThey may be traversed backwards, from tail to head.
223afe61c15SRodney W. Grimes.El
224afe61c15SRodney W. GrimesHowever:
225afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
226afe61c15SRodney W. Grimes.It
227afe61c15SRodney W. GrimesAll list insertions and removals must specify the head of the list.
228afe61c15SRodney W. Grimes.It
229afe61c15SRodney W. GrimesEach head entry requires two pointers rather than one.
230afe61c15SRodney W. Grimes.It
231afe61c15SRodney W. GrimesThe termination condition for traversal is more complex.
232afe61c15SRodney W. Grimes.It
233afe61c15SRodney W. GrimesCode size is about 40% greater and operations run about 45% slower
234afe61c15SRodney W. Grimesthan lists.
235afe61c15SRodney W. Grimes.El
236afe61c15SRodney W. Grimes.Pp
237afe61c15SRodney W. GrimesIn the macro definitions,
238afe61c15SRodney W. Grimes.Fa TYPE
239afe61c15SRodney W. Grimesis the name of a user defined structure,
240afe61c15SRodney W. Grimesthat must contain a field of type
2414a775e8fSJustin T. Gibbs.Li SLIST_ENTRY ,
2424a775e8fSJustin T. Gibbs.Li STAILQ_ENTRY ,
243afe61c15SRodney W. Grimes.Li LIST_ENTRY ,
244afe61c15SRodney W. Grimes.Li TAILQ_ENTRY ,
245afe61c15SRodney W. Grimesor
246afe61c15SRodney W. Grimes.Li CIRCLEQ_ENTRY ,
247afe61c15SRodney W. Grimesnamed
248afe61c15SRodney W. Grimes.Fa NAME .
249afe61c15SRodney W. GrimesThe argument
250afe61c15SRodney W. Grimes.Fa HEADNAME
251afe61c15SRodney W. Grimesis the name of a user defined structure that must be declared
252afe61c15SRodney W. Grimesusing the macros
2534a775e8fSJustin T. Gibbs.Li SLIST_HEAD ,
2544a775e8fSJustin T. Gibbs.Li STAILQ_HEAD ,
255afe61c15SRodney W. Grimes.Li LIST_HEAD ,
256afe61c15SRodney W. Grimes.Li TAILQ_HEAD ,
257afe61c15SRodney W. Grimesor
258afe61c15SRodney W. Grimes.Li CIRCLEQ_HEAD .
259afe61c15SRodney W. GrimesSee the examples below for further explanation of how these
260afe61c15SRodney W. Grimesmacros are used.
2614a775e8fSJustin T. Gibbs.Sh SINGLY-LINKED LISTS
2624a775e8fSJustin T. GibbsA singly-linked list is headed by a structure defined by the
2634a775e8fSJustin T. Gibbs.Nm SLIST_HEAD
2644a775e8fSJustin T. Gibbsmacro.
2654a775e8fSJustin T. GibbsThis structure contains a single pointer to the first element
2664a775e8fSJustin T. Gibbson the list.
2674a775e8fSJustin T. GibbsThe elements are singly linked for minimum space and pointer manipulation
2684a775e8fSJustin T. Gibbsoverhead at the expense of O(n) removal for arbitrary elements.
2694a775e8fSJustin T. GibbsNew elements can be added to the list after an existing element or
2704a775e8fSJustin T. Gibbsat the head of the list.
2714a775e8fSJustin T. GibbsAn
2724a775e8fSJustin T. Gibbs.Fa SLIST_HEAD
2734a775e8fSJustin T. Gibbsstructure is declared as follows:
2744a775e8fSJustin T. Gibbs.Bd -literal -offset indent
2754a775e8fSJustin T. GibbsSLIST_HEAD(HEADNAME, TYPE) head;
2764a775e8fSJustin T. Gibbs.Ed
2778f20a914SMike Pritchard.Pp
2784a775e8fSJustin T. Gibbswhere
2794a775e8fSJustin T. Gibbs.Fa HEADNAME
2804a775e8fSJustin T. Gibbsis the name of the structure to be defined, and
2814a775e8fSJustin T. Gibbs.Fa TYPE
2824a775e8fSJustin T. Gibbsis the type of the elements to be linked into the list.
2834a775e8fSJustin T. GibbsA pointer to the head of the list can later be declared as:
2844a775e8fSJustin T. Gibbs.Bd -literal -offset indent
2854a775e8fSJustin T. Gibbsstruct HEADNAME *headp;
2864a775e8fSJustin T. Gibbs.Ed
2878f20a914SMike Pritchard.Pp
2884a775e8fSJustin T. Gibbs(The names
2894a775e8fSJustin T. Gibbs.Li head
2904a775e8fSJustin T. Gibbsand
2914a775e8fSJustin T. Gibbs.Li headp
2924a775e8fSJustin T. Gibbsare user selectable.)
2934a775e8fSJustin T. Gibbs.Pp
2944a775e8fSJustin T. GibbsThe macro
2954a775e8fSJustin T. Gibbs.Nm SLIST_ENTRY
2964a775e8fSJustin T. Gibbsdeclares a structure that connects the elements in
2974a775e8fSJustin T. Gibbsthe list.
2984a775e8fSJustin T. Gibbs.Pp
2994a775e8fSJustin T. GibbsThe macro
3004a775e8fSJustin T. Gibbs.Nm SLIST_INIT
3014a775e8fSJustin T. Gibbsinitializes the list referenced by
3024a775e8fSJustin T. Gibbs.Fa head .
3034a775e8fSJustin T. Gibbs.Pp
3044a775e8fSJustin T. GibbsThe macro
3054a775e8fSJustin T. Gibbs.Nm SLIST_INSERT_HEAD
3064a775e8fSJustin T. Gibbsinserts the new element
3074a775e8fSJustin T. Gibbs.Fa elm
3084a775e8fSJustin T. Gibbsat the head of the list.
3094a775e8fSJustin T. Gibbs.Pp
3104a775e8fSJustin T. GibbsThe macro
3114a775e8fSJustin T. Gibbs.Nm SLIST_INSERT_AFTER
3124a775e8fSJustin T. Gibbsinserts the new element
3134a775e8fSJustin T. Gibbs.Fa elm
3144a775e8fSJustin T. Gibbsafter the element
3154a775e8fSJustin T. Gibbs.Fa listelm .
3164a775e8fSJustin T. Gibbs.Pp
3174a775e8fSJustin T. GibbsThe macro
3184a775e8fSJustin T. Gibbs.Nm SLIST_REMOVE_HEAD
3194a775e8fSJustin T. Gibbsremoves the element
3204a775e8fSJustin T. Gibbs.Fa elm
3214a775e8fSJustin T. Gibbsfrom the head of the list.
3224a775e8fSJustin T. GibbsFor optimum efficiency,
3234a775e8fSJustin T. Gibbselements being removed from the head of the list should explicitly use
3244a775e8fSJustin T. Gibbsthis macro instead of the generic
3254a775e8fSJustin T. Gibbs.Fa SLIST_REMOVE
3264a775e8fSJustin T. Gibbsmacro.
3274a775e8fSJustin T. Gibbs.Pp
3284a775e8fSJustin T. GibbsThe macro
3294a775e8fSJustin T. Gibbs.Nm SLIST_REMOVE
3304a775e8fSJustin T. Gibbsremoves the element
3314a775e8fSJustin T. Gibbs.Fa elm
3324a775e8fSJustin T. Gibbsfrom the list.
3334a775e8fSJustin T. Gibbs.Sh SINGLY-LINKED LIST EXAMPLE
3344a775e8fSJustin T. Gibbs.Bd -literal
3354a775e8fSJustin T. GibbsSLIST_HEAD(slisthead, entry) head;
3364a775e8fSJustin T. Gibbsstruct slisthead *headp;		/* Singly-linked List head. */
3374a775e8fSJustin T. Gibbsstruct entry {
3384a775e8fSJustin T. Gibbs	...
3394a775e8fSJustin T. Gibbs	SLIST_ENTRY(entry) entries;	/* Singly-linked List. */
3404a775e8fSJustin T. Gibbs	...
3414a775e8fSJustin T. Gibbs} *n1, *n2, *n3, *np;
3424a775e8fSJustin T. Gibbs
3434a775e8fSJustin T. GibbsSLIST_INIT(&head);			/* Initialize the list. */
3444a775e8fSJustin T. Gibbs
3454a775e8fSJustin T. Gibbsn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
3464a775e8fSJustin T. GibbsSLIST_INSERT_HEAD(&head, n1, entries);
3474a775e8fSJustin T. Gibbs
3484a775e8fSJustin T. Gibbsn2 = malloc(sizeof(struct entry));	/* Insert after. */
3494a775e8fSJustin T. GibbsSLIST_INSERT_AFTER(n1, n2, entries);
3504a775e8fSJustin T. Gibbs
3514a775e8fSJustin T. GibbsSLIST_REMOVE(&head, n2, entry, entries);/* Deletion. */
3524a775e8fSJustin T. Gibbsfree(n2);
3534a775e8fSJustin T. Gibbs
3544a775e8fSJustin T. Gibbsn3 = head.slh_first;
3554a775e8fSJustin T. GibbsSLIST_REMOVE_HEAD(&head, entries);	/* Deletion. */
3564a775e8fSJustin T. Gibbsfree(n3);
3574a775e8fSJustin T. Gibbs
3584a775e8fSJustin T. Gibbs					/* Forward traversal. */
3594a775e8fSJustin T. Gibbsfor (np = head.slh_first; np != NULL; np = np->entries.sle_next)
3604a775e8fSJustin T. Gibbs	np-> ...
3614a775e8fSJustin T. Gibbs
3624a775e8fSJustin T. Gibbswhile (head.slh_first != NULL) {	/* List Deletion. */
3634a775e8fSJustin T. Gibbs	n1 = head.slh_first;
3644a775e8fSJustin T. Gibbs	SLIST_REMOVE_HEAD(&head, entries);
3654a775e8fSJustin T. Gibbs	free(n1);
3664a775e8fSJustin T. Gibbs}
3674a775e8fSJustin T. Gibbs.Ed
3684a775e8fSJustin T. Gibbs.Sh SINGLY-LINKED TAIL QUEUES
3694a775e8fSJustin T. GibbsA singly-linked tail queue is headed by a structure defined by the
3704a775e8fSJustin T. Gibbs.Nm STAILQ_HEAD
3714a775e8fSJustin T. Gibbsmacro.
3724a775e8fSJustin T. GibbsThis structure contains a pair of pointers,
3734a775e8fSJustin T. Gibbsone to the first element in the tail queue and the other to
3744a775e8fSJustin T. Gibbsthe last element in the tail queue.
3754a775e8fSJustin T. GibbsThe elements are singly linked for minimum space and pointer
3764a775e8fSJustin T. Gibbsmanipulation overhead at the expense of O(n) removal for arbitrary
3774a775e8fSJustin T. Gibbselements.
3784a775e8fSJustin T. GibbsNew elements can be added to the tail queue after an existing element,
3794a775e8fSJustin T. Gibbsat the head of the tail queue, or at the end of the tail queue.
3804a775e8fSJustin T. GibbsA
3814a775e8fSJustin T. Gibbs.Fa STAILQ_HEAD
3824a775e8fSJustin T. Gibbsstructure is declared as follows:
3834a775e8fSJustin T. Gibbs.Bd -literal -offset indent
3844a775e8fSJustin T. GibbsSTAILQ_HEAD(HEADNAME, TYPE) head;
3854a775e8fSJustin T. Gibbs.Ed
3868f20a914SMike Pritchard.Pp
3874a775e8fSJustin T. Gibbswhere
3884a775e8fSJustin T. Gibbs.Li HEADNAME
3894a775e8fSJustin T. Gibbsis the name of the structure to be defined, and
3904a775e8fSJustin T. Gibbs.Li TYPE
3914a775e8fSJustin T. Gibbsis the type of the elements to be linked into the tail queue.
3924a775e8fSJustin T. GibbsA pointer to the head of the tail queue can later be declared as:
3934a775e8fSJustin T. Gibbs.Bd -literal -offset indent
3944a775e8fSJustin T. Gibbsstruct HEADNAME *headp;
3954a775e8fSJustin T. Gibbs.Ed
3968f20a914SMike Pritchard.Pp
3974a775e8fSJustin T. Gibbs(The names
3984a775e8fSJustin T. Gibbs.Li head
3994a775e8fSJustin T. Gibbsand
4004a775e8fSJustin T. Gibbs.Li headp
4014a775e8fSJustin T. Gibbsare user selectable.)
4024a775e8fSJustin T. Gibbs.Pp
4034a775e8fSJustin T. GibbsThe macro
4044a775e8fSJustin T. Gibbs.Nm STAILQ_ENTRY
4054a775e8fSJustin T. Gibbsdeclares a structure that connects the elements in
4064a775e8fSJustin T. Gibbsthe tail queue.
4074a775e8fSJustin T. Gibbs.Pp
4084a775e8fSJustin T. GibbsThe macro
4094a775e8fSJustin T. Gibbs.Nm STAILQ_INIT
4104a775e8fSJustin T. Gibbsinitializes the tail queue referenced by
4114a775e8fSJustin T. Gibbs.Fa head .
4124a775e8fSJustin T. Gibbs.Pp
4134a775e8fSJustin T. GibbsThe macro
4144a775e8fSJustin T. Gibbs.Nm STAILQ_INSERT_HEAD
4154a775e8fSJustin T. Gibbsinserts the new element
4164a775e8fSJustin T. Gibbs.Fa elm
4174a775e8fSJustin T. Gibbsat the head of the tail queue.
4184a775e8fSJustin T. Gibbs.Pp
4194a775e8fSJustin T. GibbsThe macro
4204a775e8fSJustin T. Gibbs.Nm STAILQ_INSERT_TAIL
4214a775e8fSJustin T. Gibbsinserts the new element
4224a775e8fSJustin T. Gibbs.Fa elm
4234a775e8fSJustin T. Gibbsat the end of the tail queue.
4244a775e8fSJustin T. Gibbs.Pp
4254a775e8fSJustin T. GibbsThe macro
4264a775e8fSJustin T. Gibbs.Nm STAILQ_INSERT_AFTER
4274a775e8fSJustin T. Gibbsinserts the new element
4284a775e8fSJustin T. Gibbs.Fa elm
4294a775e8fSJustin T. Gibbsafter the element
4304a775e8fSJustin T. Gibbs.Fa listelm .
4314a775e8fSJustin T. Gibbs.Pp
4324a775e8fSJustin T. GibbsThe macro
4334a775e8fSJustin T. Gibbs.Nm STAILQ_REMOVE_HEAD
4344a775e8fSJustin T. Gibbsremoves the element
4354a775e8fSJustin T. Gibbs.Fa elm
4364a775e8fSJustin T. Gibbsfrom the head of the tail queue.
4374a775e8fSJustin T. GibbsFor optimum efficiency,
4384a775e8fSJustin T. Gibbselements being removed from the head of the tail queue should
4394a775e8fSJustin T. Gibbsuse this macro explicitly rather than the generic
4404a775e8fSJustin T. Gibbs.Fa STAILQ_REMOVE
4414a775e8fSJustin T. Gibbsmacro.
4424a775e8fSJustin T. Gibbs.Pp
4434a775e8fSJustin T. GibbsThe macro
4444a775e8fSJustin T. Gibbs.Nm STAILQ_REMOVE
4454a775e8fSJustin T. Gibbsremoves the element
4464a775e8fSJustin T. Gibbs.Fa elm
4474a775e8fSJustin T. Gibbsfrom the tail queue.
4484a775e8fSJustin T. Gibbs.Sh SINGLY-LINKED TAIL QUEUE EXAMPLE
4494a775e8fSJustin T. Gibbs.Bd -literal
4504a775e8fSJustin T. GibbsSTAILQ_HEAD(stailhead, entry) head;
4514a775e8fSJustin T. Gibbsstruct stailhead *headp;		/* Singly-linked tail queue head. */
4524a775e8fSJustin T. Gibbsstruct entry {
4534a775e8fSJustin T. Gibbs	...
4544a775e8fSJustin T. Gibbs	STAILQ_ENTRY(entry) entries;	/* Tail queue. */
4554a775e8fSJustin T. Gibbs	...
4564a775e8fSJustin T. Gibbs} *n1, *n2, *n3, *np;
4574a775e8fSJustin T. Gibbs
4584a775e8fSJustin T. GibbsSTAILQ_INIT(&head);			/* Initialize the queue. */
4594a775e8fSJustin T. Gibbs
4604a775e8fSJustin T. Gibbsn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
4614a775e8fSJustin T. GibbsSTAILQ_INSERT_HEAD(&head, n1, entries);
4624a775e8fSJustin T. Gibbs
4634a775e8fSJustin T. Gibbsn1 = malloc(sizeof(struct entry));	/* Insert at the tail. */
4644a775e8fSJustin T. GibbsSTAILQ_INSERT_TAIL(&head, n1, entries);
4654a775e8fSJustin T. Gibbs
4664a775e8fSJustin T. Gibbsn2 = malloc(sizeof(struct entry));	/* Insert after. */
4674a775e8fSJustin T. GibbsSTAILQ_INSERT_AFTER(&head, n1, n2, entries);
4684a775e8fSJustin T. Gibbs
4694a775e8fSJustin T. Gibbs					/* Deletion. */
4704a775e8fSJustin T. GibbsSTAILQ_REMOVE(&head, n2, entry, entries);
4714a775e8fSJustin T. Gibbsfree(n2);
4724a775e8fSJustin T. Gibbs
4734a775e8fSJustin T. Gibbs					/* Deletion from the head */
4744a775e8fSJustin T. Gibbsn3 = head.stqh_first;
4754a775e8fSJustin T. GibbsSTAILQ_REMOVE_HEAD(&head, entries);
4764a775e8fSJustin T. Gibbsfree(n3);
4774a775e8fSJustin T. Gibbs
4784a775e8fSJustin T. Gibbs					/* Forward traversal. */
4794a775e8fSJustin T. Gibbsfor (np = head.stqh_first; np != NULL; np = np->entries.stqe_next)
4804a775e8fSJustin T. Gibbs	np-> ...
4814a775e8fSJustin T. Gibbs					/* TailQ Deletion. */
4824a775e8fSJustin T. Gibbswhile (head.stqh_first != NULL) {
4834a775e8fSJustin T. Gibbs	n1 = head.stqh_first;
4844a775e8fSJustin T. Gibbs	TAILQ_REMOVE_HEAD(&head, entries);
4854a775e8fSJustin T. Gibbs	free(n1);
4864a775e8fSJustin T. Gibbs}
4874a775e8fSJustin T. Gibbs					/* Faster TailQ Deletion. */
4884a775e8fSJustin T. Gibbsn1 = head.stqh_first;
4894a775e8fSJustin T. Gibbswhile (n1 != NULL) {
4904a775e8fSJustin T. Gibbs	n2 = n1->entries.stqe_next;
4914a775e8fSJustin T. Gibbs	free(n1);
4924a775e8fSJustin T. Gibbs	n1 = n2;
4934a775e8fSJustin T. Gibbs}
4944a775e8fSJustin T. GibbsSTAILQ_INIT(&head);
4954a775e8fSJustin T. Gibbs.Ed
496afe61c15SRodney W. Grimes.Sh LISTS
497afe61c15SRodney W. GrimesA list is headed by a structure defined by the
498afe61c15SRodney W. Grimes.Nm LIST_HEAD
499afe61c15SRodney W. Grimesmacro.
500afe61c15SRodney W. GrimesThis structure contains a single pointer to the first element
501afe61c15SRodney W. Grimeson the list.
502afe61c15SRodney W. GrimesThe elements are doubly linked so that an arbitrary element can be
503afe61c15SRodney W. Grimesremoved without traversing the list.
5044a775e8fSJustin T. GibbsNew elements can be added to the list after an existing element,
5054a775e8fSJustin T. Gibbsbefore an existing element, or at the head of the list.
506afe61c15SRodney W. GrimesA
507afe61c15SRodney W. Grimes.Fa LIST_HEAD
508afe61c15SRodney W. Grimesstructure is declared as follows:
509afe61c15SRodney W. Grimes.Bd -literal -offset indent
510afe61c15SRodney W. GrimesLIST_HEAD(HEADNAME, TYPE) head;
511afe61c15SRodney W. Grimes.Ed
5128f20a914SMike Pritchard.Pp
513afe61c15SRodney W. Grimeswhere
514afe61c15SRodney W. Grimes.Fa HEADNAME
515afe61c15SRodney W. Grimesis the name of the structure to be defined, and
516afe61c15SRodney W. Grimes.Fa TYPE
517afe61c15SRodney W. Grimesis the type of the elements to be linked into the list.
518afe61c15SRodney W. GrimesA pointer to the head of the list can later be declared as:
519afe61c15SRodney W. Grimes.Bd -literal -offset indent
520afe61c15SRodney W. Grimesstruct HEADNAME *headp;
521afe61c15SRodney W. Grimes.Ed
5228f20a914SMike Pritchard.Pp
523afe61c15SRodney W. Grimes(The names
524afe61c15SRodney W. Grimes.Li head
525afe61c15SRodney W. Grimesand
526afe61c15SRodney W. Grimes.Li headp
527afe61c15SRodney W. Grimesare user selectable.)
528afe61c15SRodney W. Grimes.Pp
529afe61c15SRodney W. GrimesThe macro
530afe61c15SRodney W. Grimes.Nm LIST_ENTRY
531afe61c15SRodney W. Grimesdeclares a structure that connects the elements in
532afe61c15SRodney W. Grimesthe list.
533afe61c15SRodney W. Grimes.Pp
534afe61c15SRodney W. GrimesThe macro
535afe61c15SRodney W. Grimes.Nm LIST_INIT
536afe61c15SRodney W. Grimesinitializes the list referenced by
537afe61c15SRodney W. Grimes.Fa head .
538afe61c15SRodney W. Grimes.Pp
539afe61c15SRodney W. GrimesThe macro
540afe61c15SRodney W. Grimes.Nm LIST_INSERT_HEAD
541afe61c15SRodney W. Grimesinserts the new element
542afe61c15SRodney W. Grimes.Fa elm
543afe61c15SRodney W. Grimesat the head of the list.
544afe61c15SRodney W. Grimes.Pp
545afe61c15SRodney W. GrimesThe macro
546afe61c15SRodney W. Grimes.Nm LIST_INSERT_AFTER
547afe61c15SRodney W. Grimesinserts the new element
548afe61c15SRodney W. Grimes.Fa elm
549afe61c15SRodney W. Grimesafter the element
550afe61c15SRodney W. Grimes.Fa listelm .
551afe61c15SRodney W. Grimes.Pp
552afe61c15SRodney W. GrimesThe macro
5537658b0a2SJustin T. Gibbs.Nm LIST_INSERT_BEFORE
5547658b0a2SJustin T. Gibbsinserts the new element
5557658b0a2SJustin T. Gibbs.Fa elm
5567658b0a2SJustin T. Gibbsbefore the element
5577658b0a2SJustin T. Gibbs.Fa listelm .
5587658b0a2SJustin T. Gibbs.Pp
5597658b0a2SJustin T. GibbsThe macro
560afe61c15SRodney W. Grimes.Nm LIST_REMOVE
561afe61c15SRodney W. Grimesremoves the element
562afe61c15SRodney W. Grimes.Fa elm
563afe61c15SRodney W. Grimesfrom the list.
564afe61c15SRodney W. Grimes.Sh LIST EXAMPLE
565afe61c15SRodney W. Grimes.Bd -literal
566afe61c15SRodney W. GrimesLIST_HEAD(listhead, entry) head;
567afe61c15SRodney W. Grimesstruct listhead *headp;		/* List head. */
568afe61c15SRodney W. Grimesstruct entry {
569afe61c15SRodney W. Grimes	...
570afe61c15SRodney W. Grimes	LIST_ENTRY(entry) entries;	/* List. */
571afe61c15SRodney W. Grimes	...
5727658b0a2SJustin T. Gibbs} *n1, *n2, *n3, *np;
573afe61c15SRodney W. Grimes
574afe61c15SRodney W. GrimesLIST_INIT(&head);			/* Initialize the list. */
575afe61c15SRodney W. Grimes
576afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
577afe61c15SRodney W. GrimesLIST_INSERT_HEAD(&head, n1, entries);
578afe61c15SRodney W. Grimes
579afe61c15SRodney W. Grimesn2 = malloc(sizeof(struct entry));	/* Insert after. */
580afe61c15SRodney W. GrimesLIST_INSERT_AFTER(n1, n2, entries);
5817658b0a2SJustin T. Gibbs
5827658b0a2SJustin T. Gibbsn3 = malloc(sizeof(struct entry));	/* Insert before. */
5837658b0a2SJustin T. GibbsLIST_INSERT_BEFORE(n2, n3, entries);
5847658b0a2SJustin T. Gibbs
5857658b0a2SJustin T. GibbsLIST_REMOVE(n2, entries);		/* Deletion. */
5867658b0a2SJustin T. Gibbsfree(n2);
5877658b0a2SJustin T. Gibbs
588afe61c15SRodney W. Grimes					/* Forward traversal. */
589afe61c15SRodney W. Grimesfor (np = head.lh_first; np != NULL; np = np->entries.le_next)
590afe61c15SRodney W. Grimes	np-> ...
591afe61c15SRodney W. Grimes
5927658b0a2SJustin T. Gibbswhile (head.lh_first != NULL) {		/* List Deletion. */
5937658b0a2SJustin T. Gibbs	n1 = head.lh_first;
5947658b0a2SJustin T. Gibbs	LIST_REMOVE(n1, entries);
5957658b0a2SJustin T. Gibbs	free(n1);
5967658b0a2SJustin T. Gibbs}
5977658b0a2SJustin T. Gibbs
5987658b0a2SJustin T. Gibbsn1 = head.lh_first;			/* Faster List Delete. */
5997658b0a2SJustin T. Gibbswhile (n1 != NULL) {
6007658b0a2SJustin T. Gibbs	n2 = n1->entires.le_next;
6017658b0a2SJustin T. Gibbs	free(n1);
6027658b0a2SJustin T. Gibbs	n1 = n2;
6037658b0a2SJustin T. Gibbs}
6047658b0a2SJustin T. GibbsLIST_INIT(&head);
6057658b0a2SJustin T. Gibbs
606afe61c15SRodney W. Grimes.Ed
607afe61c15SRodney W. Grimes.Sh TAIL QUEUES
608afe61c15SRodney W. GrimesA tail queue is headed by a structure defined by the
609afe61c15SRodney W. Grimes.Nm TAILQ_HEAD
610afe61c15SRodney W. Grimesmacro.
611afe61c15SRodney W. GrimesThis structure contains a pair of pointers,
612afe61c15SRodney W. Grimesone to the first element in the tail queue and the other to
613afe61c15SRodney W. Grimesthe last element in the tail queue.
614afe61c15SRodney W. GrimesThe elements are doubly linked so that an arbitrary element can be
615afe61c15SRodney W. Grimesremoved without traversing the tail queue.
616afe61c15SRodney W. GrimesNew elements can be added to the tail queue after an existing element,
6174a775e8fSJustin T. Gibbsbefore an existing element, at the head of the tail queue,
6184a775e8fSJustin T. Gibbsor at the end of the tail queue.
619afe61c15SRodney W. GrimesA
620afe61c15SRodney W. Grimes.Fa TAILQ_HEAD
621afe61c15SRodney W. Grimesstructure is declared as follows:
622afe61c15SRodney W. Grimes.Bd -literal -offset indent
623afe61c15SRodney W. GrimesTAILQ_HEAD(HEADNAME, TYPE) head;
624afe61c15SRodney W. Grimes.Ed
6258f20a914SMike Pritchard.Pp
626afe61c15SRodney W. Grimeswhere
627afe61c15SRodney W. Grimes.Li HEADNAME
628afe61c15SRodney W. Grimesis the name of the structure to be defined, and
629afe61c15SRodney W. Grimes.Li TYPE
630afe61c15SRodney W. Grimesis the type of the elements to be linked into the tail queue.
631afe61c15SRodney W. GrimesA pointer to the head of the tail queue can later be declared as:
632afe61c15SRodney W. Grimes.Bd -literal -offset indent
633afe61c15SRodney W. Grimesstruct HEADNAME *headp;
634afe61c15SRodney W. Grimes.Ed
6358f20a914SMike Pritchard.Pp
636afe61c15SRodney W. Grimes(The names
637afe61c15SRodney W. Grimes.Li head
638afe61c15SRodney W. Grimesand
639afe61c15SRodney W. Grimes.Li headp
640afe61c15SRodney W. Grimesare user selectable.)
641afe61c15SRodney W. Grimes.Pp
642afe61c15SRodney W. GrimesThe macro
643c5c15c16SPoul-Henning Kamp.Nm TAILQ_EMPTY
644c5c15c16SPoul-Henning Kampevaluates to true if there are no items on the tail queue.
645c5c15c16SPoul-Henning Kamp.Pp
646c5c15c16SPoul-Henning KampThe macro
647afe61c15SRodney W. Grimes.Nm TAILQ_ENTRY
648afe61c15SRodney W. Grimesdeclares a structure that connects the elements in
649afe61c15SRodney W. Grimesthe tail queue.
650afe61c15SRodney W. Grimes.Pp
651afe61c15SRodney W. GrimesThe macro
652c5c15c16SPoul-Henning Kamp.Nm TAILQ_FIRST
653c5c15c16SPoul-Henning Kampreturns the first item on the tail queue or NULL if the tail queue
654c5c15c16SPoul-Henning Kampis empty.
655c5c15c16SPoul-Henning Kamp.Pp
656c5c15c16SPoul-Henning KampThe macro
657afe61c15SRodney W. Grimes.Nm TAILQ_INIT
658afe61c15SRodney W. Grimesinitializes the tail queue referenced by
659afe61c15SRodney W. Grimes.Fa head .
660afe61c15SRodney W. Grimes.Pp
661afe61c15SRodney W. GrimesThe macro
662afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_HEAD
663afe61c15SRodney W. Grimesinserts the new element
664afe61c15SRodney W. Grimes.Fa elm
665afe61c15SRodney W. Grimesat the head of the tail queue.
666afe61c15SRodney W. Grimes.Pp
667afe61c15SRodney W. GrimesThe macro
668afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_TAIL
669afe61c15SRodney W. Grimesinserts the new element
670afe61c15SRodney W. Grimes.Fa elm
671afe61c15SRodney W. Grimesat the end of the tail queue.
672afe61c15SRodney W. Grimes.Pp
673afe61c15SRodney W. GrimesThe macro
674afe61c15SRodney W. Grimes.Nm TAILQ_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 TAILQ_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
688c5c15c16SPoul-Henning Kamp.Nm TAILQ_LAST
689c5c15c16SPoul-Henning Kampreturns the last item on the tail queue.
690c5c15c16SPoul-Henning KampIf the tail queue is empty the return value is undefined.
691c5c15c16SPoul-Henning Kamp.Pp
692c5c15c16SPoul-Henning KampThe macro
693c5c15c16SPoul-Henning Kamp.Nm TAILQ_NEXT
694c5c15c16SPoul-Henning Kampreturns the next item on the tail queue, or NULL this item is the last.
695c5c15c16SPoul-Henning Kamp.Pp
696c5c15c16SPoul-Henning KampThe macro
697afe61c15SRodney W. Grimes.Nm TAILQ_REMOVE
698afe61c15SRodney W. Grimesremoves the element
699afe61c15SRodney W. Grimes.Fa elm
700afe61c15SRodney W. Grimesfrom the tail queue.
701afe61c15SRodney W. Grimes.Sh TAIL QUEUE EXAMPLE
702afe61c15SRodney W. Grimes.Bd -literal
703afe61c15SRodney W. GrimesTAILQ_HEAD(tailhead, entry) head;
704afe61c15SRodney W. Grimesstruct tailhead *headp;		/* Tail queue head. */
705afe61c15SRodney W. Grimesstruct entry {
706afe61c15SRodney W. Grimes	...
707afe61c15SRodney W. Grimes	TAILQ_ENTRY(entry) entries;	/* Tail queue. */
708afe61c15SRodney W. Grimes	...
7097658b0a2SJustin T. Gibbs} *n1, *n2, *n3, *np;
710afe61c15SRodney W. Grimes
711afe61c15SRodney W. GrimesTAILQ_INIT(&head);			/* Initialize the queue. */
712afe61c15SRodney W. Grimes
713afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
714afe61c15SRodney W. GrimesTAILQ_INSERT_HEAD(&head, n1, entries);
715afe61c15SRodney W. Grimes
716afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the tail. */
717afe61c15SRodney W. GrimesTAILQ_INSERT_TAIL(&head, n1, entries);
718afe61c15SRodney W. Grimes
719afe61c15SRodney W. Grimesn2 = malloc(sizeof(struct entry));	/* Insert after. */
720afe61c15SRodney W. GrimesTAILQ_INSERT_AFTER(&head, n1, n2, entries);
7217658b0a2SJustin T. Gibbs
7227658b0a2SJustin T. Gibbsn3 = malloc(sizeof(struct entry));	/* Insert before. */
7233652ff55SJustin T. GibbsTAILQ_INSERT_BEFORE(n2, n3, entries);
7247658b0a2SJustin T. Gibbs
7257658b0a2SJustin T. GibbsTAILQ_REMOVE(&head, n2, entries);	/* Deletion. */
7267658b0a2SJustin T. Gibbsfree(n2);
727afe61c15SRodney W. Grimes					/* Forward traversal. */
728c5c15c16SPoul-Henning Kampfor (np = TAILQ_FIRST(&head); np != NULL; np = TAILQ_NEXT(np, entries))
729afe61c15SRodney W. Grimes	np-> ...
7307658b0a2SJustin T. Gibbs					/* TailQ Deletion. */
731c5c15c16SPoul-Henning Kampwhile (!TAILQ_EMPTY(head)) {
732c5c15c16SPoul-Henning Kamp	n1 = TAILQ_FIRST(&head);
733afe61c15SRodney W. Grimes	TAILQ_REMOVE(&head, head.tqh_first, entries);
7347658b0a2SJustin T. Gibbs	free(n1);
7357658b0a2SJustin T. Gibbs}
7367658b0a2SJustin T. Gibbs					/* Faster TailQ Deletion. */
737c5c15c16SPoul-Henning Kamp
738c5c15c16SPoul-Henning Kampn1 = TAILQ_FIRST(&head);
7397658b0a2SJustin T. Gibbswhile (n1 != NULL) {
740c5c15c16SPoul-Henning Kamp	n2 = TAILQ_NEXT(n1, entries);
7417658b0a2SJustin T. Gibbs	free(n1);
7427658b0a2SJustin T. Gibbs	n1 = n2;
7437658b0a2SJustin T. Gibbs}
7447658b0a2SJustin T. GibbsTAILQ_INIT(&head);
745afe61c15SRodney W. Grimes.Ed
746afe61c15SRodney W. Grimes.Sh CIRCULAR QUEUES
747afe61c15SRodney W. GrimesA circular queue is headed by a structure defined by the
748afe61c15SRodney W. Grimes.Nm CIRCLEQ_HEAD
749afe61c15SRodney W. Grimesmacro.
750afe61c15SRodney W. GrimesThis structure contains a pair of pointers,
751afe61c15SRodney W. Grimesone to the first element in the circular queue and the other to the
752afe61c15SRodney W. Grimeslast element in the circular queue.
753afe61c15SRodney W. GrimesThe elements are doubly linked so that an arbitrary element can be
754afe61c15SRodney W. Grimesremoved without traversing the queue.
755afe61c15SRodney W. GrimesNew elements can be added to the queue after an existing element,
756afe61c15SRodney W. Grimesbefore an existing element, at the head of the queue, or at the end
757afe61c15SRodney W. Grimesof the queue.
758afe61c15SRodney W. GrimesA
759afe61c15SRodney W. Grimes.Fa CIRCLEQ_HEAD
760afe61c15SRodney W. Grimesstructure is declared as follows:
761afe61c15SRodney W. Grimes.Bd -literal -offset indent
762afe61c15SRodney W. GrimesCIRCLEQ_HEAD(HEADNAME, TYPE) head;
763afe61c15SRodney W. Grimes.Ed
7648f20a914SMike Pritchard.Pp
765afe61c15SRodney W. Grimeswhere
766afe61c15SRodney W. Grimes.Li HEADNAME
767afe61c15SRodney W. Grimesis the name of the structure to be defined, and
768afe61c15SRodney W. Grimes.Li TYPE
769afe61c15SRodney W. Grimesis the type of the elements to be linked into the circular queue.
770afe61c15SRodney W. GrimesA pointer to the head of the circular queue can later be declared as:
771afe61c15SRodney W. Grimes.Bd -literal -offset indent
772afe61c15SRodney W. Grimesstruct HEADNAME *headp;
773afe61c15SRodney W. Grimes.Ed
7748f20a914SMike Pritchard.Pp
775afe61c15SRodney W. Grimes(The names
776afe61c15SRodney W. Grimes.Li head
777afe61c15SRodney W. Grimesand
778afe61c15SRodney W. Grimes.Li headp
779afe61c15SRodney W. Grimesare user selectable.)
780afe61c15SRodney W. Grimes.Pp
781afe61c15SRodney W. GrimesThe macro
782afe61c15SRodney W. Grimes.Nm CIRCLEQ_ENTRY
783afe61c15SRodney W. Grimesdeclares a structure that connects the elements in
784afe61c15SRodney W. Grimesthe circular queue.
785afe61c15SRodney W. Grimes.Pp
786afe61c15SRodney W. GrimesThe macro
787afe61c15SRodney W. Grimes.Nm CIRCLEQ_INIT
788afe61c15SRodney W. Grimesinitializes the circular queue referenced by
789afe61c15SRodney W. Grimes.Fa head .
790afe61c15SRodney W. Grimes.Pp
791afe61c15SRodney W. GrimesThe macro
792afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_HEAD
793afe61c15SRodney W. Grimesinserts the new element
794afe61c15SRodney W. Grimes.Fa elm
795afe61c15SRodney W. Grimesat the head of the circular queue.
796afe61c15SRodney W. Grimes.Pp
797afe61c15SRodney W. GrimesThe macro
798afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_TAIL
799afe61c15SRodney W. Grimesinserts the new element
800afe61c15SRodney W. Grimes.Fa elm
801afe61c15SRodney W. Grimesat the end of the circular queue.
802afe61c15SRodney W. Grimes.Pp
803afe61c15SRodney W. GrimesThe macro
804afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_AFTER
805afe61c15SRodney W. Grimesinserts the new element
806afe61c15SRodney W. Grimes.Fa elm
807afe61c15SRodney W. Grimesafter the element
808afe61c15SRodney W. Grimes.Fa listelm .
809afe61c15SRodney W. Grimes.Pp
810afe61c15SRodney W. GrimesThe macro
811afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_BEFORE
812afe61c15SRodney W. Grimesinserts the new element
813afe61c15SRodney W. Grimes.Fa elm
814afe61c15SRodney W. Grimesbefore the element
815afe61c15SRodney W. Grimes.Fa listelm .
816afe61c15SRodney W. Grimes.Pp
817afe61c15SRodney W. GrimesThe macro
818afe61c15SRodney W. Grimes.Nm CIRCLEQ_REMOVE
819afe61c15SRodney W. Grimesremoves the element
820afe61c15SRodney W. Grimes.Fa elm
821afe61c15SRodney W. Grimesfrom the circular queue.
822afe61c15SRodney W. Grimes.Sh CIRCULAR QUEUE EXAMPLE
823afe61c15SRodney W. Grimes.Bd -literal
824afe61c15SRodney W. GrimesCIRCLEQ_HEAD(circleq, entry) head;
825afe61c15SRodney W. Grimesstruct circleq *headp;			/* Circular queue head. */
826afe61c15SRodney W. Grimesstruct entry {
827afe61c15SRodney W. Grimes	...
828afe61c15SRodney W. Grimes	CIRCLEQ_ENTRY entries;		/* Circular queue. */
829afe61c15SRodney W. Grimes	...
830afe61c15SRodney W. Grimes} *n1, *n2, *np;
831afe61c15SRodney W. Grimes
832afe61c15SRodney W. GrimesCIRCLEQ_INIT(&head);			/* Initialize the circular queue. */
833afe61c15SRodney W. Grimes
834afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
835afe61c15SRodney W. GrimesCIRCLEQ_INSERT_HEAD(&head, n1, entries);
836afe61c15SRodney W. Grimes
837afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the tail. */
838afe61c15SRodney W. GrimesCIRCLEQ_INSERT_TAIL(&head, n1, entries);
839afe61c15SRodney W. Grimes
840afe61c15SRodney W. Grimesn2 = malloc(sizeof(struct entry));	/* Insert after. */
841afe61c15SRodney W. GrimesCIRCLEQ_INSERT_AFTER(&head, n1, n2, entries);
842afe61c15SRodney W. Grimes
843afe61c15SRodney W. Grimesn2 = malloc(sizeof(struct entry));	/* Insert before. */
844afe61c15SRodney W. GrimesCIRCLEQ_INSERT_BEFORE(&head, n1, n2, entries);
8457658b0a2SJustin T. Gibbs
8467658b0a2SJustin T. GibbsCIRCLEQ_REMOVE(&head, n1, entries);	/* Deletion. */
8477658b0a2SJustin T. Gibbsfree(n1);
848afe61c15SRodney W. Grimes					/* Forward traversal. */
849afe61c15SRodney W. Grimesfor (np = head.cqh_first; np != (void *)&head; np = np->entries.cqe_next)
850afe61c15SRodney W. Grimes	np-> ...
851afe61c15SRodney W. Grimes					/* Reverse traversal. */
852afe61c15SRodney W. Grimesfor (np = head.cqh_last; np != (void *)&head; np = np->entries.cqe_prev)
853afe61c15SRodney W. Grimes	np-> ...
8547658b0a2SJustin T. Gibbs					/* CircleQ Deletion. */
8557658b0a2SJustin T. Gibbswhile (head.cqh_first != (void *)&head) {
8567658b0a2SJustin T. Gibbs	n1 = head.cqh_first;
857afe61c15SRodney W. Grimes	CIRCLEQ_REMOVE(&head, head.cqh_first, entries);
8587658b0a2SJustin T. Gibbs	free(n1);
8597658b0a2SJustin T. Gibbs}
8607658b0a2SJustin T. Gibbs					/* Faster CircleQ Deletion. */
8617658b0a2SJustin T. Gibbsn1 = head.cqh_first;
8627658b0a2SJustin T. Gibbswhile (n1 != (void *)&head) {
8637658b0a2SJustin T. Gibbs	n2 = n1->entries.cqh_next;
8647658b0a2SJustin T. Gibbs	free(n1);
8657658b0a2SJustin T. Gibbs	n1 = n2;
8667658b0a2SJustin T. Gibbs}
8677658b0a2SJustin T. GibbsCIRCLEQ_INIT(&head);
868afe61c15SRodney W. Grimes.Ed
869afe61c15SRodney W. Grimes.Sh HISTORY
870afe61c15SRodney W. GrimesThe
871afe61c15SRodney W. Grimes.Nm queue
87221421932SMike Pritchardfunctions first appeared in
87321421932SMike Pritchard.Bx 4.4 .
874