xref: /freebsd/share/man/man3/queue.3 (revision c5c15c162fd21b8856beccb8d99eb033601fca33)
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 ,
60c5c15c16SPoul-Henning Kamp.Nm TAILQ_EMPTY ,
61afe61c15SRodney W. Grimes.Nm TAILQ_ENTRY ,
62c5c15c16SPoul-Henning Kamp.Nm TAILQ_FIRST ,
63afe61c15SRodney W. Grimes.Nm TAILQ_HEAD ,
64afe61c15SRodney W. Grimes.Nm TAILQ_INIT ,
65afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_AFTER ,
667658b0a2SJustin T. Gibbs.Nm TAILQ_INSERT_BEFORE ,
67afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_HEAD ,
68afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_TAIL ,
69c5c15c16SPoul-Henning Kamp.Nm TAILQ_LAST ,
70c5c15c16SPoul-Henning Kamp.Nm TAILQ_NEXT ,
71afe61c15SRodney W. Grimes.Nm TAILQ_REMOVE ,
72afe61c15SRodney W. Grimes.Nm CIRCLEQ_ENTRY ,
73afe61c15SRodney W. Grimes.Nm CIRCLEQ_HEAD ,
74afe61c15SRodney W. Grimes.Nm CIRCLEQ_INIT ,
75afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_AFTER ,
76afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_BEFORE ,
77afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_HEAD ,
78afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_TAIL ,
79afe61c15SRodney W. Grimes.Nm CIRCLEQ_REMOVE
804a775e8fSJustin T. Gibbs.Nd implementations of singly-linked lists, singly-linked tail queues,
814a775e8fSJustin T. Gibbslists, tail queues, and circular queues
82afe61c15SRodney W. Grimes.Sh SYNOPSIS
83afe61c15SRodney W. Grimes.Fd #include <sys/queue.h>
84afe61c15SRodney W. Grimes.sp
854a775e8fSJustin T. Gibbs.Fn SLIST_ENTRY "TYPE"
864a775e8fSJustin T. Gibbs.Fn SLIST_HEAD "HEADNAME" "TYPE"
874a775e8fSJustin T. Gibbs.Fn SLIST_INIT "SLIST_HEAD *head"
884a775e8fSJustin T. Gibbs.Fn SLIST_INSERT_AFTER "TYPE *listelm" "TYPE *elm" "SLIST_ENTRY NAME"
894a775e8fSJustin T. Gibbs.Fn SLIST_INSERT_HEAD "SLIST_HEAD *head" "TYPE *elm" "SLIST_ENTRY NAME"
904a775e8fSJustin T. Gibbs.Fn SLIST_REMOVE_HEAD "SLIST_HEAD *head" "SLIST_ENTRY NAME"
914a775e8fSJustin T. Gibbs.Fn SLIST_REMOVE "SLIST_HEAD *head" "TYPE *elm" "TYPE" "SLIST_ENTRY NAME"
924a775e8fSJustin T. Gibbs.sp
934a775e8fSJustin T. Gibbs.Fn STAILQ_ENTRY "TYPE"
944a775e8fSJustin T. Gibbs.Fn STAILQ_HEAD "HEADNAME" "TYPE"
954a775e8fSJustin T. Gibbs.Fn STAILQ_INIT "STAILQ_HEAD *head"
964a775e8fSJustin T. Gibbs.Fn STAILQ_INSERT_AFTER "STAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "STAILQ_ENTRY NAME"
974a775e8fSJustin T. Gibbs.Fn STAILQ_INSERT_HEAD "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
984a775e8fSJustin T. Gibbs.Fn STAILQ_INSERT_TAIL "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
994a775e8fSJustin T. Gibbs.Fn STAILQ_REMOVE_HEAD "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
1004a775e8fSJustin T. Gibbs.Fn STAILQ_REMOVE "STAILQ_HEAD *head" "TYPE *elm" "TYPE" "STAILQ_ENTRY NAME"
1014a775e8fSJustin T. Gibbs.sp
102afe61c15SRodney W. Grimes.Fn LIST_ENTRY "TYPE"
103afe61c15SRodney W. Grimes.Fn LIST_HEAD "HEADNAME" "TYPE"
104afe61c15SRodney W. Grimes.Fn LIST_INIT "LIST_HEAD *head"
1054a775e8fSJustin T. Gibbs.Fn LIST_INSERT_AFTER "TYPE *listelm" "TYPE *elm" "LIST_ENTRY NAME"
1064a775e8fSJustin T. Gibbs.Fn LIST_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "LIST_ENTRY NAME"
107afe61c15SRodney W. Grimes.Fn LIST_INSERT_HEAD "LIST_HEAD *head" "TYPE *elm" "LIST_ENTRY NAME"
108afe61c15SRodney W. Grimes.Fn LIST_REMOVE "TYPE *elm" "LIST_ENTRY NAME"
109afe61c15SRodney W. Grimes.sp
110c5c15c16SPoul-Henning Kamp.Fn TAILQ_EMPTY "TAILQ_HEAD *head"
111afe61c15SRodney W. Grimes.Fn TAILQ_ENTRY "TYPE"
112c5c15c16SPoul-Henning Kamp.Fn TAILQ_FIRST "TAILQ_HEAD *head"
113afe61c15SRodney W. Grimes.Fn TAILQ_HEAD "HEADNAME" "TYPE"
114afe61c15SRodney W. Grimes.Fn TAILQ_INIT "TAILQ_HEAD *head"
115afe61c15SRodney W. Grimes.Fn TAILQ_INSERT_AFTER "TAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME"
1163652ff55SJustin T. Gibbs.Fn TAILQ_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME"
117afe61c15SRodney W. Grimes.Fn TAILQ_INSERT_HEAD "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
118afe61c15SRodney W. Grimes.Fn TAILQ_INSERT_TAIL "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
119c5c15c16SPoul-Henning Kamp.Fn TAILQ_LAST "TAILQ_HEAD *head"
120c5c15c16SPoul-Henning Kamp.Fn TAILQ_NEXT "TYPE *elm" "TAILQ_ENTRY NAME"
121afe61c15SRodney W. Grimes.Fn TAILQ_REMOVE "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
122afe61c15SRodney W. Grimes.sp
123afe61c15SRodney W. Grimes.Fn CIRCLEQ_ENTRY "TYPE"
124afe61c15SRodney W. Grimes.Fn CIRCLEQ_HEAD "HEADNAME" "TYPE"
125afe61c15SRodney W. Grimes.Fn CIRCLEQ_INIT "CIRCLEQ_HEAD *head"
126afe61c15SRodney W. Grimes.Fn CIRCLEQ_INSERT_AFTER "CIRCLEQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
127afe61c15SRodney W. Grimes.Fn CIRCLEQ_INSERT_BEFORE "CIRCLEQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
128afe61c15SRodney W. Grimes.Fn CIRCLEQ_INSERT_HEAD "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
129afe61c15SRodney W. Grimes.Fn CIRCLEQ_INSERT_TAIL "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
130afe61c15SRodney W. Grimes.Fn CIRCLEQ_REMOVE "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
131afe61c15SRodney W. Grimes.Sh DESCRIPTION
1324a775e8fSJustin T. GibbsThese macros define and operate on five types of data structures:
1334a775e8fSJustin T. Gibbssingly-linked lists, singly-linked tail queues, lists, tail queues,
1344a775e8fSJustin T. Gibbsand circular queues.
1354a775e8fSJustin T. GibbsAll five structures support the following functionality:
136afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
137afe61c15SRodney W. Grimes.It
138afe61c15SRodney W. GrimesInsertion of a new entry at the head of the list.
139afe61c15SRodney W. Grimes.It
140afe61c15SRodney W. GrimesInsertion of a new entry after any element in the list.
141afe61c15SRodney W. Grimes.It
1424a775e8fSJustin T. GibbsO(1) removal of an entry from the head of the list.
1437658b0a2SJustin T. Gibbs.It
1444a775e8fSJustin T. GibbsO(n) removal of any entry in the list.
145afe61c15SRodney W. Grimes.It
146afe61c15SRodney W. GrimesForward traversal through the list.
147afe61c15SRodney W. Grimes.El
148afe61c15SRodney W. Grimes.Pp
1494a775e8fSJustin T. GibbsSingly-linked lists are the simplest of the five data structures
1504a775e8fSJustin T. Gibbsand support only the above functionality.
1514a775e8fSJustin T. GibbsSingly-linked lists are ideal for applications with large datasets
1524a775e8fSJustin T. Gibbsand few or no removals,
1534a775e8fSJustin T. Gibbsor for implementing a LIFO queue.
1544a775e8fSJustin T. Gibbs.Pp
1554a775e8fSJustin T. GibbsSingly-linked tail queues add the following functionality:
1564a775e8fSJustin T. Gibbs.Bl -enum -compact -offset indent
1574a775e8fSJustin T. Gibbs.It
1584a775e8fSJustin T. GibbsEntries can be added at the end of a list.
1594a775e8fSJustin T. Gibbs.El
1604a775e8fSJustin T. GibbsHowever:
1614a775e8fSJustin T. Gibbs.Bl -enum -compact -offset indent
1624a775e8fSJustin T. Gibbs.It
1634a775e8fSJustin T. GibbsAll list insertions must specify the head of the list.
1644a775e8fSJustin T. Gibbs.It
1654a775e8fSJustin T. GibbsEach head entry requires two pointers rather than one.
1664a775e8fSJustin T. Gibbs.It
1674a775e8fSJustin T. GibbsCode size is about 15% greater and operations run about 20% slower
1684a775e8fSJustin T. Gibbsthan singly-linked lists.
1694a775e8fSJustin T. Gibbs.El
1704a775e8fSJustin T. Gibbs.Pp
1714a775e8fSJustin T. GibbsSingly-linked tailqs are ideal for applications with large datasets and
1724a775e8fSJustin T. Gibbsfew or no removals,
1734a775e8fSJustin T. Gibbsor for implementing a FIFO queue.
1744a775e8fSJustin T. Gibbs.Pp
1754a775e8fSJustin T. GibbsAll doubly linked types of data structures (lists, tail queues, and circle
1764a775e8fSJustin T. Gibbsqueues) additionally allow:
1774a775e8fSJustin T. Gibbs.Bl -enum -compact -offset indent
1784a775e8fSJustin T. Gibbs.It
1794a775e8fSJustin T. GibbsInsertion of a new entry before any element in the list.
1804a775e8fSJustin T. Gibbs.It
1814a775e8fSJustin T. GibbsO(1) removal of any entry in the list.
1824a775e8fSJustin T. Gibbs.El
1834a775e8fSJustin T. GibbsHowever:
1844a775e8fSJustin T. Gibbs.Bl -enum -compact -offset indent
1854a775e8fSJustin T. Gibbs.It
1864a775e8fSJustin T. GibbsEach elements requires two pointers rather than one.
1874a775e8fSJustin T. Gibbs.It
1884a775e8fSJustin T. GibbsCode size and execution time of operations (except for removal) is about
1894a775e8fSJustin T. Gibbstwice that of the singly-linked data-structures.
1904a775e8fSJustin T. Gibbs.El
1914a775e8fSJustin T. Gibbs.Pp
1924a775e8fSJustin T. GibbsLinked lists are the simplest of the doubly linked data structures and support
1934a775e8fSJustin T. Gibbsonly the above functionality over singly-linked lists.
194afe61c15SRodney W. Grimes.Pp
195afe61c15SRodney W. GrimesTail queues add the following functionality:
196afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
197afe61c15SRodney W. Grimes.It
198afe61c15SRodney W. GrimesEntries can be added at the end of a list.
199afe61c15SRodney W. Grimes.El
200afe61c15SRodney W. GrimesHowever:
201afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
202afe61c15SRodney W. Grimes.It
203afe61c15SRodney W. GrimesAll list insertions and removals must specify the head of the list.
204afe61c15SRodney W. Grimes.It
205afe61c15SRodney W. GrimesEach head entry requires two pointers rather than one.
206afe61c15SRodney W. Grimes.It
207afe61c15SRodney W. GrimesCode size is about 15% greater and operations run about 20% slower
2084a775e8fSJustin T. Gibbsthan singly-linked lists.
209afe61c15SRodney W. Grimes.El
210afe61c15SRodney W. Grimes.Pp
211afe61c15SRodney W. GrimesCircular queues add the following functionality:
212afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
213afe61c15SRodney W. Grimes.It
214afe61c15SRodney W. GrimesEntries can be added at the end of a list.
215afe61c15SRodney W. Grimes.It
216afe61c15SRodney W. GrimesThey may be traversed backwards, from tail to head.
217afe61c15SRodney W. Grimes.El
218afe61c15SRodney W. GrimesHowever:
219afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
220afe61c15SRodney W. Grimes.It
221afe61c15SRodney W. GrimesAll list insertions and removals must specify the head of the list.
222afe61c15SRodney W. Grimes.It
223afe61c15SRodney W. GrimesEach head entry requires two pointers rather than one.
224afe61c15SRodney W. Grimes.It
225afe61c15SRodney W. GrimesThe termination condition for traversal is more complex.
226afe61c15SRodney W. Grimes.It
227afe61c15SRodney W. GrimesCode size is about 40% greater and operations run about 45% slower
228afe61c15SRodney W. Grimesthan lists.
229afe61c15SRodney W. Grimes.El
230afe61c15SRodney W. Grimes.Pp
231afe61c15SRodney W. GrimesIn the macro definitions,
232afe61c15SRodney W. Grimes.Fa TYPE
233afe61c15SRodney W. Grimesis the name of a user defined structure,
234afe61c15SRodney W. Grimesthat must contain a field of type
2354a775e8fSJustin T. Gibbs.Li SLIST_ENTRY ,
2364a775e8fSJustin T. Gibbs.Li STAILQ_ENTRY ,
237afe61c15SRodney W. Grimes.Li LIST_ENTRY ,
238afe61c15SRodney W. Grimes.Li TAILQ_ENTRY ,
239afe61c15SRodney W. Grimesor
240afe61c15SRodney W. Grimes.Li CIRCLEQ_ENTRY ,
241afe61c15SRodney W. Grimesnamed
242afe61c15SRodney W. Grimes.Fa NAME .
243afe61c15SRodney W. GrimesThe argument
244afe61c15SRodney W. Grimes.Fa HEADNAME
245afe61c15SRodney W. Grimesis the name of a user defined structure that must be declared
246afe61c15SRodney W. Grimesusing the macros
2474a775e8fSJustin T. Gibbs.Li SLIST_HEAD ,
2484a775e8fSJustin T. Gibbs.Li STAILQ_HEAD ,
249afe61c15SRodney W. Grimes.Li LIST_HEAD ,
250afe61c15SRodney W. Grimes.Li TAILQ_HEAD ,
251afe61c15SRodney W. Grimesor
252afe61c15SRodney W. Grimes.Li CIRCLEQ_HEAD .
253afe61c15SRodney W. GrimesSee the examples below for further explanation of how these
254afe61c15SRodney W. Grimesmacros are used.
2554a775e8fSJustin T. Gibbs.Sh SINGLY-LINKED LISTS
2564a775e8fSJustin T. GibbsA singly-linked list is headed by a structure defined by the
2574a775e8fSJustin T. Gibbs.Nm SLIST_HEAD
2584a775e8fSJustin T. Gibbsmacro.
2594a775e8fSJustin T. GibbsThis structure contains a single pointer to the first element
2604a775e8fSJustin T. Gibbson the list.
2614a775e8fSJustin T. GibbsThe elements are singly linked for minimum space and pointer manipulation
2624a775e8fSJustin T. Gibbsoverhead at the expense of O(n) removal for arbitrary elements.
2634a775e8fSJustin T. GibbsNew elements can be added to the list after an existing element or
2644a775e8fSJustin T. Gibbsat the head of the list.
2654a775e8fSJustin T. GibbsAn
2664a775e8fSJustin T. Gibbs.Fa SLIST_HEAD
2674a775e8fSJustin T. Gibbsstructure is declared as follows:
2684a775e8fSJustin T. Gibbs.Bd -literal -offset indent
2694a775e8fSJustin T. GibbsSLIST_HEAD(HEADNAME, TYPE) head;
2704a775e8fSJustin T. Gibbs.Ed
2714a775e8fSJustin T. Gibbs.sp
2724a775e8fSJustin T. Gibbswhere
2734a775e8fSJustin T. Gibbs.Fa HEADNAME
2744a775e8fSJustin T. Gibbsis the name of the structure to be defined, and
2754a775e8fSJustin T. Gibbs.Fa TYPE
2764a775e8fSJustin T. Gibbsis the type of the elements to be linked into the list.
2774a775e8fSJustin T. GibbsA pointer to the head of the list can later be declared as:
2784a775e8fSJustin T. Gibbs.Bd -literal -offset indent
2794a775e8fSJustin T. Gibbsstruct HEADNAME *headp;
2804a775e8fSJustin T. Gibbs.Ed
2814a775e8fSJustin T. Gibbs.sp
2824a775e8fSJustin T. Gibbs(The names
2834a775e8fSJustin T. Gibbs.Li head
2844a775e8fSJustin T. Gibbsand
2854a775e8fSJustin T. Gibbs.Li headp
2864a775e8fSJustin T. Gibbsare user selectable.)
2874a775e8fSJustin T. Gibbs.Pp
2884a775e8fSJustin T. GibbsThe macro
2894a775e8fSJustin T. Gibbs.Nm SLIST_ENTRY
2904a775e8fSJustin T. Gibbsdeclares a structure that connects the elements in
2914a775e8fSJustin T. Gibbsthe list.
2924a775e8fSJustin T. Gibbs.Pp
2934a775e8fSJustin T. GibbsThe macro
2944a775e8fSJustin T. Gibbs.Nm SLIST_INIT
2954a775e8fSJustin T. Gibbsinitializes the list referenced by
2964a775e8fSJustin T. Gibbs.Fa head .
2974a775e8fSJustin T. Gibbs.Pp
2984a775e8fSJustin T. GibbsThe macro
2994a775e8fSJustin T. Gibbs.Nm SLIST_INSERT_HEAD
3004a775e8fSJustin T. Gibbsinserts the new element
3014a775e8fSJustin T. Gibbs.Fa elm
3024a775e8fSJustin T. Gibbsat the head of the list.
3034a775e8fSJustin T. Gibbs.Pp
3044a775e8fSJustin T. GibbsThe macro
3054a775e8fSJustin T. Gibbs.Nm SLIST_INSERT_AFTER
3064a775e8fSJustin T. Gibbsinserts the new element
3074a775e8fSJustin T. Gibbs.Fa elm
3084a775e8fSJustin T. Gibbsafter the element
3094a775e8fSJustin T. Gibbs.Fa listelm .
3104a775e8fSJustin T. Gibbs.Pp
3114a775e8fSJustin T. GibbsThe macro
3124a775e8fSJustin T. Gibbs.Nm SLIST_REMOVE_HEAD
3134a775e8fSJustin T. Gibbsremoves the element
3144a775e8fSJustin T. Gibbs.Fa elm
3154a775e8fSJustin T. Gibbsfrom the head of the list.
3164a775e8fSJustin T. GibbsFor optimum efficiency,
3174a775e8fSJustin T. Gibbselements being removed from the head of the list should explicitly use
3184a775e8fSJustin T. Gibbsthis macro instead of the generic
3194a775e8fSJustin T. Gibbs.Fa SLIST_REMOVE
3204a775e8fSJustin T. Gibbsmacro.
3214a775e8fSJustin T. Gibbs.Pp
3224a775e8fSJustin T. GibbsThe macro
3234a775e8fSJustin T. Gibbs.Nm SLIST_REMOVE
3244a775e8fSJustin T. Gibbsremoves the element
3254a775e8fSJustin T. Gibbs.Fa elm
3264a775e8fSJustin T. Gibbsfrom the list.
3274a775e8fSJustin T. Gibbs.Sh SINGLY-LINKED LIST EXAMPLE
3284a775e8fSJustin T. Gibbs.Bd -literal
3294a775e8fSJustin T. GibbsSLIST_HEAD(slisthead, entry) head;
3304a775e8fSJustin T. Gibbsstruct slisthead *headp;		/* Singly-linked List head. */
3314a775e8fSJustin T. Gibbsstruct entry {
3324a775e8fSJustin T. Gibbs	...
3334a775e8fSJustin T. Gibbs	SLIST_ENTRY(entry) entries;	/* Singly-linked List. */
3344a775e8fSJustin T. Gibbs	...
3354a775e8fSJustin T. Gibbs} *n1, *n2, *n3, *np;
3364a775e8fSJustin T. Gibbs
3374a775e8fSJustin T. GibbsSLIST_INIT(&head);			/* Initialize the list. */
3384a775e8fSJustin T. Gibbs
3394a775e8fSJustin T. Gibbsn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
3404a775e8fSJustin T. GibbsSLIST_INSERT_HEAD(&head, n1, entries);
3414a775e8fSJustin T. Gibbs
3424a775e8fSJustin T. Gibbsn2 = malloc(sizeof(struct entry));	/* Insert after. */
3434a775e8fSJustin T. GibbsSLIST_INSERT_AFTER(n1, n2, entries);
3444a775e8fSJustin T. Gibbs
3454a775e8fSJustin T. GibbsSLIST_REMOVE(&head, n2, entry, entries);/* Deletion. */
3464a775e8fSJustin T. Gibbsfree(n2);
3474a775e8fSJustin T. Gibbs
3484a775e8fSJustin T. Gibbsn3 = head.slh_first;
3494a775e8fSJustin T. GibbsSLIST_REMOVE_HEAD(&head, entries);	/* Deletion. */
3504a775e8fSJustin T. Gibbsfree(n3);
3514a775e8fSJustin T. Gibbs
3524a775e8fSJustin T. Gibbs					/* Forward traversal. */
3534a775e8fSJustin T. Gibbsfor (np = head.slh_first; np != NULL; np = np->entries.sle_next)
3544a775e8fSJustin T. Gibbs	np-> ...
3554a775e8fSJustin T. Gibbs
3564a775e8fSJustin T. Gibbswhile (head.slh_first != NULL) {	/* List Deletion. */
3574a775e8fSJustin T. Gibbs	n1 = head.slh_first;
3584a775e8fSJustin T. Gibbs	SLIST_REMOVE_HEAD(&head, entries);
3594a775e8fSJustin T. Gibbs	free(n1);
3604a775e8fSJustin T. Gibbs}
3614a775e8fSJustin T. Gibbs.Ed
3624a775e8fSJustin T. Gibbs.Sh SINGLY-LINKED TAIL QUEUES
3634a775e8fSJustin T. GibbsA singly-linked tail queue is headed by a structure defined by the
3644a775e8fSJustin T. Gibbs.Nm STAILQ_HEAD
3654a775e8fSJustin T. Gibbsmacro.
3664a775e8fSJustin T. GibbsThis structure contains a pair of pointers,
3674a775e8fSJustin T. Gibbsone to the first element in the tail queue and the other to
3684a775e8fSJustin T. Gibbsthe last element in the tail queue.
3694a775e8fSJustin T. GibbsThe elements are singly linked for minimum space and pointer
3704a775e8fSJustin T. Gibbsmanipulation overhead at the expense of O(n) removal for arbitrary
3714a775e8fSJustin T. Gibbselements.
3724a775e8fSJustin T. GibbsNew elements can be added to the tail queue after an existing element,
3734a775e8fSJustin T. Gibbsat the head of the tail queue, or at the end of the tail queue.
3744a775e8fSJustin T. GibbsA
3754a775e8fSJustin T. Gibbs.Fa STAILQ_HEAD
3764a775e8fSJustin T. Gibbsstructure is declared as follows:
3774a775e8fSJustin T. Gibbs.Bd -literal -offset indent
3784a775e8fSJustin T. GibbsSTAILQ_HEAD(HEADNAME, TYPE) head;
3794a775e8fSJustin T. Gibbs.Ed
3804a775e8fSJustin T. Gibbs.sp
3814a775e8fSJustin T. Gibbswhere
3824a775e8fSJustin T. Gibbs.Li HEADNAME
3834a775e8fSJustin T. Gibbsis the name of the structure to be defined, and
3844a775e8fSJustin T. Gibbs.Li TYPE
3854a775e8fSJustin T. Gibbsis the type of the elements to be linked into the tail queue.
3864a775e8fSJustin T. GibbsA pointer to the head of the tail queue can later be declared as:
3874a775e8fSJustin T. Gibbs.Bd -literal -offset indent
3884a775e8fSJustin T. Gibbsstruct HEADNAME *headp;
3894a775e8fSJustin T. Gibbs.Ed
3904a775e8fSJustin T. Gibbs.sp
3914a775e8fSJustin T. Gibbs(The names
3924a775e8fSJustin T. Gibbs.Li head
3934a775e8fSJustin T. Gibbsand
3944a775e8fSJustin T. Gibbs.Li headp
3954a775e8fSJustin T. Gibbsare user selectable.)
3964a775e8fSJustin T. Gibbs.Pp
3974a775e8fSJustin T. GibbsThe macro
3984a775e8fSJustin T. Gibbs.Nm STAILQ_ENTRY
3994a775e8fSJustin T. Gibbsdeclares a structure that connects the elements in
4004a775e8fSJustin T. Gibbsthe tail queue.
4014a775e8fSJustin T. Gibbs.Pp
4024a775e8fSJustin T. GibbsThe macro
4034a775e8fSJustin T. Gibbs.Nm STAILQ_INIT
4044a775e8fSJustin T. Gibbsinitializes the tail queue referenced by
4054a775e8fSJustin T. Gibbs.Fa head .
4064a775e8fSJustin T. Gibbs.Pp
4074a775e8fSJustin T. GibbsThe macro
4084a775e8fSJustin T. Gibbs.Nm STAILQ_INSERT_HEAD
4094a775e8fSJustin T. Gibbsinserts the new element
4104a775e8fSJustin T. Gibbs.Fa elm
4114a775e8fSJustin T. Gibbsat the head of the tail queue.
4124a775e8fSJustin T. Gibbs.Pp
4134a775e8fSJustin T. GibbsThe macro
4144a775e8fSJustin T. Gibbs.Nm STAILQ_INSERT_TAIL
4154a775e8fSJustin T. Gibbsinserts the new element
4164a775e8fSJustin T. Gibbs.Fa elm
4174a775e8fSJustin T. Gibbsat the end of the tail queue.
4184a775e8fSJustin T. Gibbs.Pp
4194a775e8fSJustin T. GibbsThe macro
4204a775e8fSJustin T. Gibbs.Nm STAILQ_INSERT_AFTER
4214a775e8fSJustin T. Gibbsinserts the new element
4224a775e8fSJustin T. Gibbs.Fa elm
4234a775e8fSJustin T. Gibbsafter the element
4244a775e8fSJustin T. Gibbs.Fa listelm .
4254a775e8fSJustin T. Gibbs.Pp
4264a775e8fSJustin T. GibbsThe macro
4274a775e8fSJustin T. Gibbs.Nm STAILQ_REMOVE_HEAD
4284a775e8fSJustin T. Gibbsremoves the element
4294a775e8fSJustin T. Gibbs.Fa elm
4304a775e8fSJustin T. Gibbsfrom the head of the tail queue.
4314a775e8fSJustin T. GibbsFor optimum efficiency,
4324a775e8fSJustin T. Gibbselements being removed from the head of the tail queue should
4334a775e8fSJustin T. Gibbsuse this macro explicitly rather than the generic
4344a775e8fSJustin T. Gibbs.Fa STAILQ_REMOVE
4354a775e8fSJustin T. Gibbsmacro.
4364a775e8fSJustin T. Gibbs.Pp
4374a775e8fSJustin T. GibbsThe macro
4384a775e8fSJustin T. Gibbs.Nm STAILQ_REMOVE
4394a775e8fSJustin T. Gibbsremoves the element
4404a775e8fSJustin T. Gibbs.Fa elm
4414a775e8fSJustin T. Gibbsfrom the tail queue.
4424a775e8fSJustin T. Gibbs.Sh SINGLY-LINKED TAIL QUEUE EXAMPLE
4434a775e8fSJustin T. Gibbs.Bd -literal
4444a775e8fSJustin T. GibbsSTAILQ_HEAD(stailhead, entry) head;
4454a775e8fSJustin T. Gibbsstruct stailhead *headp;		/* Singly-linked tail queue head. */
4464a775e8fSJustin T. Gibbsstruct entry {
4474a775e8fSJustin T. Gibbs	...
4484a775e8fSJustin T. Gibbs	STAILQ_ENTRY(entry) entries;	/* Tail queue. */
4494a775e8fSJustin T. Gibbs	...
4504a775e8fSJustin T. Gibbs} *n1, *n2, *n3, *np;
4514a775e8fSJustin T. Gibbs
4524a775e8fSJustin T. GibbsSTAILQ_INIT(&head);			/* Initialize the queue. */
4534a775e8fSJustin T. Gibbs
4544a775e8fSJustin T. Gibbsn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
4554a775e8fSJustin T. GibbsSTAILQ_INSERT_HEAD(&head, n1, entries);
4564a775e8fSJustin T. Gibbs
4574a775e8fSJustin T. Gibbsn1 = malloc(sizeof(struct entry));	/* Insert at the tail. */
4584a775e8fSJustin T. GibbsSTAILQ_INSERT_TAIL(&head, n1, entries);
4594a775e8fSJustin T. Gibbs
4604a775e8fSJustin T. Gibbsn2 = malloc(sizeof(struct entry));	/* Insert after. */
4614a775e8fSJustin T. GibbsSTAILQ_INSERT_AFTER(&head, n1, n2, entries);
4624a775e8fSJustin T. Gibbs
4634a775e8fSJustin T. Gibbs					/* Deletion. */
4644a775e8fSJustin T. GibbsSTAILQ_REMOVE(&head, n2, entry, entries);
4654a775e8fSJustin T. Gibbsfree(n2);
4664a775e8fSJustin T. Gibbs
4674a775e8fSJustin T. Gibbs					/* Deletion from the head */
4684a775e8fSJustin T. Gibbsn3 = head.stqh_first;
4694a775e8fSJustin T. GibbsSTAILQ_REMOVE_HEAD(&head, entries);
4704a775e8fSJustin T. Gibbsfree(n3);
4714a775e8fSJustin T. Gibbs
4724a775e8fSJustin T. Gibbs					/* Forward traversal. */
4734a775e8fSJustin T. Gibbsfor (np = head.stqh_first; np != NULL; np = np->entries.stqe_next)
4744a775e8fSJustin T. Gibbs	np-> ...
4754a775e8fSJustin T. Gibbs					/* TailQ Deletion. */
4764a775e8fSJustin T. Gibbswhile (head.stqh_first != NULL) {
4774a775e8fSJustin T. Gibbs	n1 = head.stqh_first;
4784a775e8fSJustin T. Gibbs	TAILQ_REMOVE_HEAD(&head, entries);
4794a775e8fSJustin T. Gibbs	free(n1);
4804a775e8fSJustin T. Gibbs}
4814a775e8fSJustin T. Gibbs					/* Faster TailQ Deletion. */
4824a775e8fSJustin T. Gibbsn1 = head.stqh_first;
4834a775e8fSJustin T. Gibbswhile (n1 != NULL) {
4844a775e8fSJustin T. Gibbs	n2 = n1->entries.stqe_next;
4854a775e8fSJustin T. Gibbs	free(n1);
4864a775e8fSJustin T. Gibbs	n1 = n2;
4874a775e8fSJustin T. Gibbs}
4884a775e8fSJustin T. GibbsSTAILQ_INIT(&head);
4894a775e8fSJustin T. Gibbs.Ed
490afe61c15SRodney W. Grimes.Sh LISTS
491afe61c15SRodney W. GrimesA list is headed by a structure defined by the
492afe61c15SRodney W. Grimes.Nm LIST_HEAD
493afe61c15SRodney W. Grimesmacro.
494afe61c15SRodney W. GrimesThis structure contains a single pointer to the first element
495afe61c15SRodney W. Grimeson the list.
496afe61c15SRodney W. GrimesThe elements are doubly linked so that an arbitrary element can be
497afe61c15SRodney W. Grimesremoved without traversing the list.
4984a775e8fSJustin T. GibbsNew elements can be added to the list after an existing element,
4994a775e8fSJustin T. Gibbsbefore an existing element, or at the head of the list.
500afe61c15SRodney W. GrimesA
501afe61c15SRodney W. Grimes.Fa LIST_HEAD
502afe61c15SRodney W. Grimesstructure is declared as follows:
503afe61c15SRodney W. Grimes.Bd -literal -offset indent
504afe61c15SRodney W. GrimesLIST_HEAD(HEADNAME, TYPE) head;
505afe61c15SRodney W. Grimes.Ed
506afe61c15SRodney W. Grimes.sp
507afe61c15SRodney W. Grimeswhere
508afe61c15SRodney W. Grimes.Fa HEADNAME
509afe61c15SRodney W. Grimesis the name of the structure to be defined, and
510afe61c15SRodney W. Grimes.Fa TYPE
511afe61c15SRodney W. Grimesis the type of the elements to be linked into the list.
512afe61c15SRodney W. GrimesA pointer to the head of the list can later be declared as:
513afe61c15SRodney W. Grimes.Bd -literal -offset indent
514afe61c15SRodney W. Grimesstruct HEADNAME *headp;
515afe61c15SRodney W. Grimes.Ed
516afe61c15SRodney W. Grimes.sp
517afe61c15SRodney W. Grimes(The names
518afe61c15SRodney W. Grimes.Li head
519afe61c15SRodney W. Grimesand
520afe61c15SRodney W. Grimes.Li headp
521afe61c15SRodney W. Grimesare user selectable.)
522afe61c15SRodney W. Grimes.Pp
523afe61c15SRodney W. GrimesThe macro
524afe61c15SRodney W. Grimes.Nm LIST_ENTRY
525afe61c15SRodney W. Grimesdeclares a structure that connects the elements in
526afe61c15SRodney W. Grimesthe list.
527afe61c15SRodney W. Grimes.Pp
528afe61c15SRodney W. GrimesThe macro
529afe61c15SRodney W. Grimes.Nm LIST_INIT
530afe61c15SRodney W. Grimesinitializes the list referenced by
531afe61c15SRodney W. Grimes.Fa head .
532afe61c15SRodney W. Grimes.Pp
533afe61c15SRodney W. GrimesThe macro
534afe61c15SRodney W. Grimes.Nm LIST_INSERT_HEAD
535afe61c15SRodney W. Grimesinserts the new element
536afe61c15SRodney W. Grimes.Fa elm
537afe61c15SRodney W. Grimesat the head of the list.
538afe61c15SRodney W. Grimes.Pp
539afe61c15SRodney W. GrimesThe macro
540afe61c15SRodney W. Grimes.Nm LIST_INSERT_AFTER
541afe61c15SRodney W. Grimesinserts the new element
542afe61c15SRodney W. Grimes.Fa elm
543afe61c15SRodney W. Grimesafter the element
544afe61c15SRodney W. Grimes.Fa listelm .
545afe61c15SRodney W. Grimes.Pp
546afe61c15SRodney W. GrimesThe macro
5477658b0a2SJustin T. Gibbs.Nm LIST_INSERT_BEFORE
5487658b0a2SJustin T. Gibbsinserts the new element
5497658b0a2SJustin T. Gibbs.Fa elm
5507658b0a2SJustin T. Gibbsbefore the element
5517658b0a2SJustin T. Gibbs.Fa listelm .
5527658b0a2SJustin T. Gibbs.Pp
5537658b0a2SJustin T. GibbsThe macro
554afe61c15SRodney W. Grimes.Nm LIST_REMOVE
555afe61c15SRodney W. Grimesremoves the element
556afe61c15SRodney W. Grimes.Fa elm
557afe61c15SRodney W. Grimesfrom the list.
558afe61c15SRodney W. Grimes.Sh LIST EXAMPLE
559afe61c15SRodney W. Grimes.Bd -literal
560afe61c15SRodney W. GrimesLIST_HEAD(listhead, entry) head;
561afe61c15SRodney W. Grimesstruct listhead *headp;		/* List head. */
562afe61c15SRodney W. Grimesstruct entry {
563afe61c15SRodney W. Grimes	...
564afe61c15SRodney W. Grimes	LIST_ENTRY(entry) entries;	/* List. */
565afe61c15SRodney W. Grimes	...
5667658b0a2SJustin T. Gibbs} *n1, *n2, *n3, *np;
567afe61c15SRodney W. Grimes
568afe61c15SRodney W. GrimesLIST_INIT(&head);			/* Initialize the list. */
569afe61c15SRodney W. Grimes
570afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
571afe61c15SRodney W. GrimesLIST_INSERT_HEAD(&head, n1, entries);
572afe61c15SRodney W. Grimes
573afe61c15SRodney W. Grimesn2 = malloc(sizeof(struct entry));	/* Insert after. */
574afe61c15SRodney W. GrimesLIST_INSERT_AFTER(n1, n2, entries);
5757658b0a2SJustin T. Gibbs
5767658b0a2SJustin T. Gibbsn3 = malloc(sizeof(struct entry));	/* Insert before. */
5777658b0a2SJustin T. GibbsLIST_INSERT_BEFORE(n2, n3, entries);
5787658b0a2SJustin T. Gibbs
5797658b0a2SJustin T. GibbsLIST_REMOVE(n2, entries);		/* Deletion. */
5807658b0a2SJustin T. Gibbsfree(n2);
5817658b0a2SJustin T. Gibbs
582afe61c15SRodney W. Grimes					/* Forward traversal. */
583afe61c15SRodney W. Grimesfor (np = head.lh_first; np != NULL; np = np->entries.le_next)
584afe61c15SRodney W. Grimes	np-> ...
585afe61c15SRodney W. Grimes
5867658b0a2SJustin T. Gibbswhile (head.lh_first != NULL) {		/* List Deletion. */
5877658b0a2SJustin T. Gibbs	n1 = head.lh_first;
5887658b0a2SJustin T. Gibbs	LIST_REMOVE(n1, entries);
5897658b0a2SJustin T. Gibbs	free(n1);
5907658b0a2SJustin T. Gibbs}
5917658b0a2SJustin T. Gibbs
5927658b0a2SJustin T. Gibbsn1 = head.lh_first;			/* Faster List Delete. */
5937658b0a2SJustin T. Gibbswhile (n1 != NULL) {
5947658b0a2SJustin T. Gibbs	n2 = n1->entires.le_next;
5957658b0a2SJustin T. Gibbs	free(n1);
5967658b0a2SJustin T. Gibbs	n1 = n2;
5977658b0a2SJustin T. Gibbs}
5987658b0a2SJustin T. GibbsLIST_INIT(&head);
5997658b0a2SJustin T. Gibbs
600afe61c15SRodney W. Grimes.Ed
601afe61c15SRodney W. Grimes.Sh TAIL QUEUES
602afe61c15SRodney W. GrimesA tail queue is headed by a structure defined by the
603afe61c15SRodney W. Grimes.Nm TAILQ_HEAD
604afe61c15SRodney W. Grimesmacro.
605afe61c15SRodney W. GrimesThis structure contains a pair of pointers,
606afe61c15SRodney W. Grimesone to the first element in the tail queue and the other to
607afe61c15SRodney W. Grimesthe last element in the tail queue.
608afe61c15SRodney W. GrimesThe elements are doubly linked so that an arbitrary element can be
609afe61c15SRodney W. Grimesremoved without traversing the tail queue.
610afe61c15SRodney W. GrimesNew elements can be added to the tail queue after an existing element,
6114a775e8fSJustin T. Gibbsbefore an existing element, at the head of the tail queue,
6124a775e8fSJustin T. Gibbsor at the end of the tail queue.
613afe61c15SRodney W. GrimesA
614afe61c15SRodney W. Grimes.Fa TAILQ_HEAD
615afe61c15SRodney W. Grimesstructure is declared as follows:
616afe61c15SRodney W. Grimes.Bd -literal -offset indent
617afe61c15SRodney W. GrimesTAILQ_HEAD(HEADNAME, TYPE) head;
618afe61c15SRodney W. Grimes.Ed
619afe61c15SRodney W. Grimes.sp
620afe61c15SRodney W. Grimeswhere
621afe61c15SRodney W. Grimes.Li HEADNAME
622afe61c15SRodney W. Grimesis the name of the structure to be defined, and
623afe61c15SRodney W. Grimes.Li TYPE
624afe61c15SRodney W. Grimesis the type of the elements to be linked into the tail queue.
625afe61c15SRodney W. GrimesA pointer to the head of the tail queue can later be declared as:
626afe61c15SRodney W. Grimes.Bd -literal -offset indent
627afe61c15SRodney W. Grimesstruct HEADNAME *headp;
628afe61c15SRodney W. Grimes.Ed
629afe61c15SRodney W. Grimes.sp
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
637c5c15c16SPoul-Henning Kamp.Nm TAILQ_EMPTY
638c5c15c16SPoul-Henning Kampevaluates to true if there are no items on the tail queue.
639c5c15c16SPoul-Henning Kamp.Pp
640c5c15c16SPoul-Henning KampThe macro
641afe61c15SRodney W. Grimes.Nm TAILQ_ENTRY
642afe61c15SRodney W. Grimesdeclares a structure that connects the elements in
643afe61c15SRodney W. Grimesthe tail queue.
644afe61c15SRodney W. Grimes.Pp
645afe61c15SRodney W. GrimesThe macro
646c5c15c16SPoul-Henning Kamp.Nm TAILQ_FIRST
647c5c15c16SPoul-Henning Kampreturns the first item on the tail queue or NULL if the tail queue
648c5c15c16SPoul-Henning Kampis empty.
649c5c15c16SPoul-Henning Kamp.Pp
650c5c15c16SPoul-Henning KampThe macro
651afe61c15SRodney W. Grimes.Nm TAILQ_INIT
652afe61c15SRodney W. Grimesinitializes the tail queue referenced by
653afe61c15SRodney W. Grimes.Fa head .
654afe61c15SRodney W. Grimes.Pp
655afe61c15SRodney W. GrimesThe macro
656afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_HEAD
657afe61c15SRodney W. Grimesinserts the new element
658afe61c15SRodney W. Grimes.Fa elm
659afe61c15SRodney W. Grimesat the head of the tail queue.
660afe61c15SRodney W. Grimes.Pp
661afe61c15SRodney W. GrimesThe macro
662afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_TAIL
663afe61c15SRodney W. Grimesinserts the new element
664afe61c15SRodney W. Grimes.Fa elm
665afe61c15SRodney W. Grimesat the end of the tail queue.
666afe61c15SRodney W. Grimes.Pp
667afe61c15SRodney W. GrimesThe macro
668afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_AFTER
669afe61c15SRodney W. Grimesinserts the new element
670afe61c15SRodney W. Grimes.Fa elm
671afe61c15SRodney W. Grimesafter the element
672afe61c15SRodney W. Grimes.Fa listelm .
673afe61c15SRodney W. Grimes.Pp
674afe61c15SRodney W. GrimesThe macro
6757658b0a2SJustin T. Gibbs.Nm TAILQ_INSERT_BEFORE
6767658b0a2SJustin T. Gibbsinserts the new element
6777658b0a2SJustin T. Gibbs.Fa elm
6787658b0a2SJustin T. Gibbsbefore the element
6797658b0a2SJustin T. Gibbs.Fa listelm .
6807658b0a2SJustin T. Gibbs.Pp
6817658b0a2SJustin T. GibbsThe macro
682c5c15c16SPoul-Henning Kamp.Nm TAILQ_LAST
683c5c15c16SPoul-Henning Kampreturns the last item on the tail queue.
684c5c15c16SPoul-Henning KampIf the tail queue is empty the return value is undefined.
685c5c15c16SPoul-Henning Kamp.Pp
686c5c15c16SPoul-Henning KampThe macro
687c5c15c16SPoul-Henning Kamp.Nm TAILQ_NEXT
688c5c15c16SPoul-Henning Kampreturns the next item on the tail queue, or NULL this item is the last.
689c5c15c16SPoul-Henning Kamp.Pp
690c5c15c16SPoul-Henning KampThe macro
691afe61c15SRodney W. Grimes.Nm TAILQ_REMOVE
692afe61c15SRodney W. Grimesremoves the element
693afe61c15SRodney W. Grimes.Fa elm
694afe61c15SRodney W. Grimesfrom the tail queue.
695afe61c15SRodney W. Grimes.Sh TAIL QUEUE EXAMPLE
696afe61c15SRodney W. Grimes.Bd -literal
697afe61c15SRodney W. GrimesTAILQ_HEAD(tailhead, entry) head;
698afe61c15SRodney W. Grimesstruct tailhead *headp;		/* Tail queue head. */
699afe61c15SRodney W. Grimesstruct entry {
700afe61c15SRodney W. Grimes	...
701afe61c15SRodney W. Grimes	TAILQ_ENTRY(entry) entries;	/* Tail queue. */
702afe61c15SRodney W. Grimes	...
7037658b0a2SJustin T. Gibbs} *n1, *n2, *n3, *np;
704afe61c15SRodney W. Grimes
705afe61c15SRodney W. GrimesTAILQ_INIT(&head);			/* Initialize the queue. */
706afe61c15SRodney W. Grimes
707afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
708afe61c15SRodney W. GrimesTAILQ_INSERT_HEAD(&head, n1, entries);
709afe61c15SRodney W. Grimes
710afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the tail. */
711afe61c15SRodney W. GrimesTAILQ_INSERT_TAIL(&head, n1, entries);
712afe61c15SRodney W. Grimes
713afe61c15SRodney W. Grimesn2 = malloc(sizeof(struct entry));	/* Insert after. */
714afe61c15SRodney W. GrimesTAILQ_INSERT_AFTER(&head, n1, n2, entries);
7157658b0a2SJustin T. Gibbs
7167658b0a2SJustin T. Gibbsn3 = malloc(sizeof(struct entry));	/* Insert before. */
7173652ff55SJustin T. GibbsTAILQ_INSERT_BEFORE(n2, n3, entries);
7187658b0a2SJustin T. Gibbs
7197658b0a2SJustin T. GibbsTAILQ_REMOVE(&head, n2, entries);	/* Deletion. */
7207658b0a2SJustin T. Gibbsfree(n2);
721afe61c15SRodney W. Grimes					/* Forward traversal. */
722c5c15c16SPoul-Henning Kampfor (np = TAILQ_FIRST(&head); np != NULL; np = TAILQ_NEXT(np, entries))
723afe61c15SRodney W. Grimes	np-> ...
7247658b0a2SJustin T. Gibbs					/* TailQ Deletion. */
725c5c15c16SPoul-Henning Kampwhile (!TAILQ_EMPTY(head)) {
726c5c15c16SPoul-Henning Kamp	n1 = TAILQ_FIRST(&head);
727afe61c15SRodney W. Grimes	TAILQ_REMOVE(&head, head.tqh_first, entries);
7287658b0a2SJustin T. Gibbs	free(n1);
7297658b0a2SJustin T. Gibbs}
7307658b0a2SJustin T. Gibbs					/* Faster TailQ Deletion. */
731c5c15c16SPoul-Henning Kamp
732c5c15c16SPoul-Henning Kampn1 = TAILQ_FIRST(&head);
7337658b0a2SJustin T. Gibbswhile (n1 != NULL) {
734c5c15c16SPoul-Henning Kamp	n2 = TAILQ_NEXT(n1, entries);
7357658b0a2SJustin T. Gibbs	free(n1);
7367658b0a2SJustin T. Gibbs	n1 = n2;
7377658b0a2SJustin T. Gibbs}
7387658b0a2SJustin T. GibbsTAILQ_INIT(&head);
739afe61c15SRodney W. Grimes.Ed
740afe61c15SRodney W. Grimes.Sh CIRCULAR QUEUES
741afe61c15SRodney W. GrimesA circular queue is headed by a structure defined by the
742afe61c15SRodney W. Grimes.Nm CIRCLEQ_HEAD
743afe61c15SRodney W. Grimesmacro.
744afe61c15SRodney W. GrimesThis structure contains a pair of pointers,
745afe61c15SRodney W. Grimesone to the first element in the circular queue and the other to the
746afe61c15SRodney W. Grimeslast element in the circular queue.
747afe61c15SRodney W. GrimesThe elements are doubly linked so that an arbitrary element can be
748afe61c15SRodney W. Grimesremoved without traversing the queue.
749afe61c15SRodney W. GrimesNew elements can be added to the queue after an existing element,
750afe61c15SRodney W. Grimesbefore an existing element, at the head of the queue, or at the end
751afe61c15SRodney W. Grimesof the queue.
752afe61c15SRodney W. GrimesA
753afe61c15SRodney W. Grimes.Fa CIRCLEQ_HEAD
754afe61c15SRodney W. Grimesstructure is declared as follows:
755afe61c15SRodney W. Grimes.Bd -literal -offset indent
756afe61c15SRodney W. GrimesCIRCLEQ_HEAD(HEADNAME, TYPE) head;
757afe61c15SRodney W. Grimes.Ed
758afe61c15SRodney W. Grimes.sp
759afe61c15SRodney W. Grimeswhere
760afe61c15SRodney W. Grimes.Li HEADNAME
761afe61c15SRodney W. Grimesis the name of the structure to be defined, and
762afe61c15SRodney W. Grimes.Li TYPE
763afe61c15SRodney W. Grimesis the type of the elements to be linked into the circular queue.
764afe61c15SRodney W. GrimesA pointer to the head of the circular queue can later be declared as:
765afe61c15SRodney W. Grimes.Bd -literal -offset indent
766afe61c15SRodney W. Grimesstruct HEADNAME *headp;
767afe61c15SRodney W. Grimes.Ed
768afe61c15SRodney W. Grimes.sp
769afe61c15SRodney W. Grimes(The names
770afe61c15SRodney W. Grimes.Li head
771afe61c15SRodney W. Grimesand
772afe61c15SRodney W. Grimes.Li headp
773afe61c15SRodney W. Grimesare user selectable.)
774afe61c15SRodney W. Grimes.Pp
775afe61c15SRodney W. GrimesThe macro
776afe61c15SRodney W. Grimes.Nm CIRCLEQ_ENTRY
777afe61c15SRodney W. Grimesdeclares a structure that connects the elements in
778afe61c15SRodney W. Grimesthe circular queue.
779afe61c15SRodney W. Grimes.Pp
780afe61c15SRodney W. GrimesThe macro
781afe61c15SRodney W. Grimes.Nm CIRCLEQ_INIT
782afe61c15SRodney W. Grimesinitializes the circular queue referenced by
783afe61c15SRodney W. Grimes.Fa head .
784afe61c15SRodney W. Grimes.Pp
785afe61c15SRodney W. GrimesThe macro
786afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_HEAD
787afe61c15SRodney W. Grimesinserts the new element
788afe61c15SRodney W. Grimes.Fa elm
789afe61c15SRodney W. Grimesat the head of the circular queue.
790afe61c15SRodney W. Grimes.Pp
791afe61c15SRodney W. GrimesThe macro
792afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_TAIL
793afe61c15SRodney W. Grimesinserts the new element
794afe61c15SRodney W. Grimes.Fa elm
795afe61c15SRodney W. Grimesat the end of the circular queue.
796afe61c15SRodney W. Grimes.Pp
797afe61c15SRodney W. GrimesThe macro
798afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_AFTER
799afe61c15SRodney W. Grimesinserts the new element
800afe61c15SRodney W. Grimes.Fa elm
801afe61c15SRodney W. Grimesafter the element
802afe61c15SRodney W. Grimes.Fa listelm .
803afe61c15SRodney W. Grimes.Pp
804afe61c15SRodney W. GrimesThe macro
805afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_BEFORE
806afe61c15SRodney W. Grimesinserts the new element
807afe61c15SRodney W. Grimes.Fa elm
808afe61c15SRodney W. Grimesbefore the element
809afe61c15SRodney W. Grimes.Fa listelm .
810afe61c15SRodney W. Grimes.Pp
811afe61c15SRodney W. GrimesThe macro
812afe61c15SRodney W. Grimes.Nm CIRCLEQ_REMOVE
813afe61c15SRodney W. Grimesremoves the element
814afe61c15SRodney W. Grimes.Fa elm
815afe61c15SRodney W. Grimesfrom the circular queue.
816afe61c15SRodney W. Grimes.Sh CIRCULAR QUEUE EXAMPLE
817afe61c15SRodney W. Grimes.Bd -literal
818afe61c15SRodney W. GrimesCIRCLEQ_HEAD(circleq, entry) head;
819afe61c15SRodney W. Grimesstruct circleq *headp;			/* Circular queue head. */
820afe61c15SRodney W. Grimesstruct entry {
821afe61c15SRodney W. Grimes	...
822afe61c15SRodney W. Grimes	CIRCLEQ_ENTRY entries;		/* Circular queue. */
823afe61c15SRodney W. Grimes	...
824afe61c15SRodney W. Grimes} *n1, *n2, *np;
825afe61c15SRodney W. Grimes
826afe61c15SRodney W. GrimesCIRCLEQ_INIT(&head);			/* Initialize the circular queue. */
827afe61c15SRodney W. Grimes
828afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
829afe61c15SRodney W. GrimesCIRCLEQ_INSERT_HEAD(&head, n1, entries);
830afe61c15SRodney W. Grimes
831afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the tail. */
832afe61c15SRodney W. GrimesCIRCLEQ_INSERT_TAIL(&head, n1, entries);
833afe61c15SRodney W. Grimes
834afe61c15SRodney W. Grimesn2 = malloc(sizeof(struct entry));	/* Insert after. */
835afe61c15SRodney W. GrimesCIRCLEQ_INSERT_AFTER(&head, n1, n2, entries);
836afe61c15SRodney W. Grimes
837afe61c15SRodney W. Grimesn2 = malloc(sizeof(struct entry));	/* Insert before. */
838afe61c15SRodney W. GrimesCIRCLEQ_INSERT_BEFORE(&head, n1, n2, entries);
8397658b0a2SJustin T. Gibbs
8407658b0a2SJustin T. GibbsCIRCLEQ_REMOVE(&head, n1, entries);	/* Deletion. */
8417658b0a2SJustin T. Gibbsfree(n1);
842afe61c15SRodney W. Grimes					/* Forward traversal. */
843afe61c15SRodney W. Grimesfor (np = head.cqh_first; np != (void *)&head; np = np->entries.cqe_next)
844afe61c15SRodney W. Grimes	np-> ...
845afe61c15SRodney W. Grimes					/* Reverse traversal. */
846afe61c15SRodney W. Grimesfor (np = head.cqh_last; np != (void *)&head; np = np->entries.cqe_prev)
847afe61c15SRodney W. Grimes	np-> ...
8487658b0a2SJustin T. Gibbs					/* CircleQ Deletion. */
8497658b0a2SJustin T. Gibbswhile (head.cqh_first != (void *)&head) {
8507658b0a2SJustin T. Gibbs	n1 = head.cqh_first;
851afe61c15SRodney W. Grimes	CIRCLEQ_REMOVE(&head, head.cqh_first, entries);
8527658b0a2SJustin T. Gibbs	free(n1);
8537658b0a2SJustin T. Gibbs}
8547658b0a2SJustin T. Gibbs					/* Faster CircleQ Deletion. */
8557658b0a2SJustin T. Gibbsn1 = head.cqh_first;
8567658b0a2SJustin T. Gibbswhile (n1 != (void *)&head) {
8577658b0a2SJustin T. Gibbs	n2 = n1->entries.cqh_next;
8587658b0a2SJustin T. Gibbs	free(n1);
8597658b0a2SJustin T. Gibbs	n1 = n2;
8607658b0a2SJustin T. Gibbs}
8617658b0a2SJustin T. GibbsCIRCLEQ_INIT(&head);
862afe61c15SRodney W. Grimes.Ed
863afe61c15SRodney W. Grimes.Sh HISTORY
864afe61c15SRodney W. GrimesThe
865afe61c15SRodney W. Grimes.Nm queue
866afe61c15SRodney W. Grimesfunctions first appeared in 4.4BSD.
867