xref: /freebsd/share/man/man3/queue.3 (revision ed741d4e2df893bf9a78016eee08a469056846e8)
1afe61c15SRodney W. Grimes.\" Copyright (c) 1993
2afe61c15SRodney W. Grimes.\"	The Regents of the University of California.  All rights reserved.
3afe61c15SRodney W. Grimes.\"
4afe61c15SRodney W. Grimes.\" Redistribution and use in source and binary forms, with or without
5afe61c15SRodney W. Grimes.\" modification, are permitted provided that the following conditions
6afe61c15SRodney W. Grimes.\" are met:
7afe61c15SRodney W. Grimes.\" 1. Redistributions of source code must retain the above copyright
8afe61c15SRodney W. Grimes.\"    notice, this list of conditions and the following disclaimer.
9afe61c15SRodney W. Grimes.\" 2. Redistributions in binary form must reproduce the above copyright
10afe61c15SRodney W. Grimes.\"    notice, this list of conditions and the following disclaimer in the
11afe61c15SRodney W. Grimes.\"    documentation and/or other materials provided with the distribution.
12afe61c15SRodney W. Grimes.\" 3. All advertising materials mentioning features or use of this software
13afe61c15SRodney W. Grimes.\"    must display the following acknowledgement:
14afe61c15SRodney W. Grimes.\"	This product includes software developed by the University of
15afe61c15SRodney W. Grimes.\"	California, Berkeley and its contributors.
16afe61c15SRodney W. Grimes.\" 4. Neither the name of the University nor the names of its contributors
17afe61c15SRodney W. Grimes.\"    may be used to endorse or promote products derived from this software
18afe61c15SRodney W. Grimes.\"    without specific prior written permission.
19afe61c15SRodney W. Grimes.\"
20afe61c15SRodney W. Grimes.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21afe61c15SRodney W. Grimes.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22afe61c15SRodney W. Grimes.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23afe61c15SRodney W. Grimes.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24afe61c15SRodney W. Grimes.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25afe61c15SRodney W. Grimes.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26afe61c15SRodney W. Grimes.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27afe61c15SRodney W. Grimes.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28afe61c15SRodney W. Grimes.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29afe61c15SRodney W. Grimes.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30afe61c15SRodney W. Grimes.\" SUCH DAMAGE.
31afe61c15SRodney W. Grimes.\"
32afe61c15SRodney W. Grimes.\"	@(#)queue.3	8.2 (Berkeley) 1/24/94
337f3dea24SPeter Wemm.\" $FreeBSD$
34afe61c15SRodney W. Grimes.\"
3581ae4b8dSRuslan Ermilov.Dd March 24, 2006
36afe61c15SRodney W. Grimes.Dt QUEUE 3
373d45e180SRuslan Ermilov.Os
38afe61c15SRodney W. Grimes.Sh NAME
39aea88892SPoul-Henning Kamp.Nm SLIST_EMPTY ,
404a775e8fSJustin T. Gibbs.Nm SLIST_ENTRY ,
41aea88892SPoul-Henning Kamp.Nm SLIST_FIRST ,
4279ea9bc4SAlexey Zelkin.Nm SLIST_FOREACH ,
432724bce2SAlexander Kabaev.Nm SLIST_FOREACH_SAFE ,
444a775e8fSJustin T. Gibbs.Nm SLIST_HEAD ,
4503763fe0SJake Burkholder.Nm SLIST_HEAD_INITIALIZER ,
464a775e8fSJustin T. Gibbs.Nm SLIST_INIT ,
474a775e8fSJustin T. Gibbs.Nm SLIST_INSERT_AFTER ,
484a775e8fSJustin T. Gibbs.Nm SLIST_INSERT_HEAD ,
49aea88892SPoul-Henning Kamp.Nm SLIST_NEXT ,
504a775e8fSJustin T. Gibbs.Nm SLIST_REMOVE_HEAD ,
514a775e8fSJustin T. Gibbs.Nm SLIST_REMOVE ,
52d57e28adSThomas Moestl.Nm STAILQ_CONCAT ,
5379ea9bc4SAlexey Zelkin.Nm STAILQ_EMPTY ,
544a775e8fSJustin T. Gibbs.Nm STAILQ_ENTRY ,
5579ea9bc4SAlexey Zelkin.Nm STAILQ_FIRST ,
5679ea9bc4SAlexey Zelkin.Nm STAILQ_FOREACH ,
572724bce2SAlexander Kabaev.Nm STAILQ_FOREACH_SAFE ,
584a775e8fSJustin T. Gibbs.Nm STAILQ_HEAD ,
5903763fe0SJake Burkholder.Nm STAILQ_HEAD_INITIALIZER ,
604a775e8fSJustin T. Gibbs.Nm STAILQ_INIT ,
614a775e8fSJustin T. Gibbs.Nm STAILQ_INSERT_AFTER ,
624a775e8fSJustin T. Gibbs.Nm STAILQ_INSERT_HEAD ,
634a775e8fSJustin T. Gibbs.Nm STAILQ_INSERT_TAIL ,
6479ea9bc4SAlexey Zelkin.Nm STAILQ_LAST ,
6579ea9bc4SAlexey Zelkin.Nm STAILQ_NEXT ,
664a775e8fSJustin T. Gibbs.Nm STAILQ_REMOVE_HEAD ,
674a775e8fSJustin T. Gibbs.Nm STAILQ_REMOVE ,
6879ea9bc4SAlexey Zelkin.Nm LIST_EMPTY ,
69afe61c15SRodney W. Grimes.Nm LIST_ENTRY ,
7079ea9bc4SAlexey Zelkin.Nm LIST_FIRST ,
7179ea9bc4SAlexey Zelkin.Nm LIST_FOREACH ,
724250a68eSBosko Milekic.Nm LIST_FOREACH_SAFE ,
73afe61c15SRodney W. Grimes.Nm LIST_HEAD ,
7403763fe0SJake Burkholder.Nm LIST_HEAD_INITIALIZER ,
75afe61c15SRodney W. Grimes.Nm LIST_INIT ,
76afe61c15SRodney W. Grimes.Nm LIST_INSERT_AFTER ,
777658b0a2SJustin T. Gibbs.Nm LIST_INSERT_BEFORE ,
78afe61c15SRodney W. Grimes.Nm LIST_INSERT_HEAD ,
7979ea9bc4SAlexey Zelkin.Nm LIST_NEXT ,
80afe61c15SRodney W. Grimes.Nm LIST_REMOVE ,
81d57e28adSThomas Moestl.Nm TAILQ_CONCAT ,
82c5c15c16SPoul-Henning Kamp.Nm TAILQ_EMPTY ,
83afe61c15SRodney W. Grimes.Nm TAILQ_ENTRY ,
84c5c15c16SPoul-Henning Kamp.Nm TAILQ_FIRST ,
8579ea9bc4SAlexey Zelkin.Nm TAILQ_FOREACH ,
862724bce2SAlexander Kabaev.Nm TAILQ_FOREACH_SAFE ,
876c1d0fbfSArchie Cobbs.Nm TAILQ_FOREACH_REVERSE ,
882724bce2SAlexander Kabaev.Nm TAILQ_FOREACH_REVERSE_SAFE ,
89afe61c15SRodney W. Grimes.Nm TAILQ_HEAD ,
9003763fe0SJake Burkholder.Nm TAILQ_HEAD_INITIALIZER ,
91afe61c15SRodney W. Grimes.Nm TAILQ_INIT ,
92afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_AFTER ,
937658b0a2SJustin T. Gibbs.Nm TAILQ_INSERT_BEFORE ,
94afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_HEAD ,
95afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_TAIL ,
96c5c15c16SPoul-Henning Kamp.Nm TAILQ_LAST ,
97c5c15c16SPoul-Henning Kamp.Nm TAILQ_NEXT ,
9879ea9bc4SAlexey Zelkin.Nm TAILQ_PREV ,
99b4660c37SBen Smithurst.Nm TAILQ_REMOVE
1004a775e8fSJustin T. Gibbs.Nd implementations of singly-linked lists, singly-linked tail queues,
10124b85d18SPoul-Henning Kamplists and tail queues
102afe61c15SRodney W. Grimes.Sh SYNOPSIS
10332eef9aeSRuslan Ermilov.In sys/queue.h
1048f20a914SMike Pritchard.\"
105aea88892SPoul-Henning Kamp.Fn SLIST_EMPTY "SLIST_HEAD *head"
1064a775e8fSJustin T. Gibbs.Fn SLIST_ENTRY "TYPE"
107aea88892SPoul-Henning Kamp.Fn SLIST_FIRST "SLIST_HEAD *head"
10879ea9bc4SAlexey Zelkin.Fn SLIST_FOREACH "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME"
1092724bce2SAlexander Kabaev.Fn SLIST_FOREACH_SAFE "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME" "TYPE *temp_var"
1104a775e8fSJustin T. Gibbs.Fn SLIST_HEAD "HEADNAME" "TYPE"
11103763fe0SJake Burkholder.Fn SLIST_HEAD_INITIALIZER "SLIST_HEAD head"
1124a775e8fSJustin T. Gibbs.Fn SLIST_INIT "SLIST_HEAD *head"
1134a775e8fSJustin T. Gibbs.Fn SLIST_INSERT_AFTER "TYPE *listelm" "TYPE *elm" "SLIST_ENTRY NAME"
1144a775e8fSJustin T. Gibbs.Fn SLIST_INSERT_HEAD "SLIST_HEAD *head" "TYPE *elm" "SLIST_ENTRY NAME"
115aea88892SPoul-Henning Kamp.Fn SLIST_NEXT "TYPE *elm" "SLIST_ENTRY NAME"
1164a775e8fSJustin T. Gibbs.Fn SLIST_REMOVE_HEAD "SLIST_HEAD *head" "SLIST_ENTRY NAME"
1174a775e8fSJustin T. Gibbs.Fn SLIST_REMOVE "SLIST_HEAD *head" "TYPE *elm" "TYPE" "SLIST_ENTRY NAME"
1188f20a914SMike Pritchard.\"
119d57e28adSThomas Moestl.Fn STAILQ_CONCAT "STAILQ_HEAD *head1" "STAILQ_HEAD *head2"
12079ea9bc4SAlexey Zelkin.Fn STAILQ_EMPTY "STAILQ_HEAD *head"
1214a775e8fSJustin T. Gibbs.Fn STAILQ_ENTRY "TYPE"
12279ea9bc4SAlexey Zelkin.Fn STAILQ_FIRST "STAILQ_HEAD *head"
12379ea9bc4SAlexey Zelkin.Fn STAILQ_FOREACH "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME"
1242724bce2SAlexander Kabaev.Fn STAILQ_FOREACH_SAFE "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" "TYPE *temp_var"
1254a775e8fSJustin T. Gibbs.Fn STAILQ_HEAD "HEADNAME" "TYPE"
12603763fe0SJake Burkholder.Fn STAILQ_HEAD_INITIALIZER "STAILQ_HEAD head"
1274a775e8fSJustin T. Gibbs.Fn STAILQ_INIT "STAILQ_HEAD *head"
1284a775e8fSJustin T. Gibbs.Fn STAILQ_INSERT_AFTER "STAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "STAILQ_ENTRY NAME"
1294a775e8fSJustin T. Gibbs.Fn STAILQ_INSERT_HEAD "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
1304a775e8fSJustin T. Gibbs.Fn STAILQ_INSERT_TAIL "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
131f36b6e4bSMaxim Sobolev.Fn STAILQ_LAST "STAILQ_HEAD *head" "TYPE" "STAILQ_ENTRY NAME"
13279ea9bc4SAlexey Zelkin.Fn STAILQ_NEXT "TYPE *elm" "STAILQ_ENTRY NAME"
13302a98699SBruce Evans.Fn STAILQ_REMOVE_HEAD "STAILQ_HEAD *head" "STAILQ_ENTRY NAME"
1344a775e8fSJustin T. Gibbs.Fn STAILQ_REMOVE "STAILQ_HEAD *head" "TYPE *elm" "TYPE" "STAILQ_ENTRY NAME"
1358f20a914SMike Pritchard.\"
13679ea9bc4SAlexey Zelkin.Fn LIST_EMPTY "LIST_HEAD *head"
137afe61c15SRodney W. Grimes.Fn LIST_ENTRY "TYPE"
13879ea9bc4SAlexey Zelkin.Fn LIST_FIRST "LIST_HEAD *head"
13979ea9bc4SAlexey Zelkin.Fn LIST_FOREACH "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME"
1404250a68eSBosko Milekic.Fn LIST_FOREACH_SAFE "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME" "TYPE *temp_var"
141afe61c15SRodney W. Grimes.Fn LIST_HEAD "HEADNAME" "TYPE"
14203763fe0SJake Burkholder.Fn LIST_HEAD_INITIALIZER "LIST_HEAD head"
143afe61c15SRodney W. Grimes.Fn LIST_INIT "LIST_HEAD *head"
1444a775e8fSJustin T. Gibbs.Fn LIST_INSERT_AFTER "TYPE *listelm" "TYPE *elm" "LIST_ENTRY NAME"
1454a775e8fSJustin T. Gibbs.Fn LIST_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "LIST_ENTRY NAME"
146afe61c15SRodney W. Grimes.Fn LIST_INSERT_HEAD "LIST_HEAD *head" "TYPE *elm" "LIST_ENTRY NAME"
14779ea9bc4SAlexey Zelkin.Fn LIST_NEXT "TYPE *elm" "LIST_ENTRY NAME"
148afe61c15SRodney W. Grimes.Fn LIST_REMOVE "TYPE *elm" "LIST_ENTRY NAME"
1498f20a914SMike Pritchard.\"
150d57e28adSThomas Moestl.Fn TAILQ_CONCAT "TAILQ_HEAD *head1" "TAILQ_HEAD *head2" "TAILQ_ENTRY NAME"
151c5c15c16SPoul-Henning Kamp.Fn TAILQ_EMPTY "TAILQ_HEAD *head"
152afe61c15SRodney W. Grimes.Fn TAILQ_ENTRY "TYPE"
153c5c15c16SPoul-Henning Kamp.Fn TAILQ_FIRST "TAILQ_HEAD *head"
15479ea9bc4SAlexey Zelkin.Fn TAILQ_FOREACH "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME"
1552724bce2SAlexander Kabaev.Fn TAILQ_FOREACH_SAFE "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME" "TYPE *temp_var"
1566c1d0fbfSArchie Cobbs.Fn TAILQ_FOREACH_REVERSE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME"
1572724bce2SAlexander Kabaev.Fn TAILQ_FOREACH_REVERSE_SAFE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME" "TYPE *temp_var"
158afe61c15SRodney W. Grimes.Fn TAILQ_HEAD "HEADNAME" "TYPE"
15903763fe0SJake Burkholder.Fn TAILQ_HEAD_INITIALIZER "TAILQ_HEAD head"
160afe61c15SRodney W. Grimes.Fn TAILQ_INIT "TAILQ_HEAD *head"
161afe61c15SRodney W. Grimes.Fn TAILQ_INSERT_AFTER "TAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME"
1623652ff55SJustin T. Gibbs.Fn TAILQ_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME"
163afe61c15SRodney W. Grimes.Fn TAILQ_INSERT_HEAD "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
164afe61c15SRodney W. Grimes.Fn TAILQ_INSERT_TAIL "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
16579ea9bc4SAlexey Zelkin.Fn TAILQ_LAST "TAILQ_HEAD *head" "HEADNAME"
166c5c15c16SPoul-Henning Kamp.Fn TAILQ_NEXT "TYPE *elm" "TAILQ_ENTRY NAME"
16779ea9bc4SAlexey Zelkin.Fn TAILQ_PREV "TYPE *elm" "HEADNAME" "TAILQ_ENTRY NAME"
168afe61c15SRodney W. Grimes.Fn TAILQ_REMOVE "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
1698f20a914SMike Pritchard.\"
170afe61c15SRodney W. Grimes.Sh DESCRIPTION
171b86388c1SDima DorfmanThese macros define and operate on four types of data structures:
172b86388c1SDima Dorfmansingly-linked lists, singly-linked tail queues, lists, and tail queues.
173b86388c1SDima DorfmanAll four structures support the following functionality:
174afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
175afe61c15SRodney W. Grimes.It
176afe61c15SRodney W. GrimesInsertion of a new entry at the head of the list.
177afe61c15SRodney W. Grimes.It
178afe61c15SRodney W. GrimesInsertion of a new entry after any element in the list.
179afe61c15SRodney W. Grimes.It
1804a775e8fSJustin T. GibbsO(1) removal of an entry from the head of the list.
1817658b0a2SJustin T. Gibbs.It
182afe61c15SRodney W. GrimesForward traversal through the list.
183afe61c15SRodney W. Grimes.El
184afe61c15SRodney W. Grimes.Pp
185ed741d4eSDavid E. O'BrienO(n) removal of any entry in the list.
186d5fd66e1SEd MasteSingly-linked lists are the simplest of the four data structures
1874a775e8fSJustin T. Gibbsand support only the above functionality.
1884a775e8fSJustin T. GibbsSingly-linked lists are ideal for applications with large datasets
1894a775e8fSJustin T. Gibbsand few or no removals,
1904a775e8fSJustin T. Gibbsor for implementing a LIFO queue.
191ed741d4eSDavid E. O'BrienSingly-linked lists add the following functionality:
192ed741d4eSDavid E. O'Brien.Bl -enum -compact -offset indent
193ed741d4eSDavid E. O'Brien.It
194ed741d4eSDavid E. O'BrienO(n) removal of any entry in the list.
195ed741d4eSDavid E. O'Brien.El
1964a775e8fSJustin T. Gibbs.Pp
1974a775e8fSJustin T. GibbsSingly-linked tail queues add the following functionality:
1984a775e8fSJustin T. Gibbs.Bl -enum -compact -offset indent
1994a775e8fSJustin T. Gibbs.It
2004a775e8fSJustin T. GibbsEntries can be added at the end of a list.
201d57e28adSThomas Moestl.It
202ed741d4eSDavid E. O'BrienO(n) removal of any entry in the list.
203ed741d4eSDavid E. O'Brien.It
204d57e28adSThomas MoestlThey may be concatenated.
2054a775e8fSJustin T. Gibbs.El
2064a775e8fSJustin T. GibbsHowever:
2074a775e8fSJustin T. Gibbs.Bl -enum -compact -offset indent
2084a775e8fSJustin T. Gibbs.It
2094a775e8fSJustin T. GibbsAll list insertions must specify the head of the list.
2104a775e8fSJustin T. Gibbs.It
2114a775e8fSJustin T. GibbsEach head entry requires two pointers rather than one.
2124a775e8fSJustin T. Gibbs.It
2134a775e8fSJustin T. GibbsCode size is about 15% greater and operations run about 20% slower
2144a775e8fSJustin T. Gibbsthan singly-linked lists.
2154a775e8fSJustin T. Gibbs.El
2164a775e8fSJustin T. Gibbs.Pp
2174a775e8fSJustin T. GibbsSingly-linked tailqs are ideal for applications with large datasets and
2184a775e8fSJustin T. Gibbsfew or no removals,
2194a775e8fSJustin T. Gibbsor for implementing a FIFO queue.
2204a775e8fSJustin T. Gibbs.Pp
221b86388c1SDima DorfmanAll doubly linked types of data structures (lists and tail queues)
222b86388c1SDima Dorfmanadditionally allow:
2234a775e8fSJustin T. Gibbs.Bl -enum -compact -offset indent
2244a775e8fSJustin T. Gibbs.It
2254a775e8fSJustin T. GibbsInsertion of a new entry before any element in the list.
2264a775e8fSJustin T. Gibbs.It
2274a775e8fSJustin T. GibbsO(1) removal of any entry in the list.
2284a775e8fSJustin T. Gibbs.El
2294a775e8fSJustin T. GibbsHowever:
2304a775e8fSJustin T. Gibbs.Bl -enum -compact -offset indent
2314a775e8fSJustin T. Gibbs.It
2324a775e8fSJustin T. GibbsEach elements requires two pointers rather than one.
2334a775e8fSJustin T. Gibbs.It
2344a775e8fSJustin T. GibbsCode size and execution time of operations (except for removal) is about
2354a775e8fSJustin T. Gibbstwice that of the singly-linked data-structures.
2364a775e8fSJustin T. Gibbs.El
2374a775e8fSJustin T. Gibbs.Pp
2384a775e8fSJustin T. GibbsLinked lists are the simplest of the doubly linked data structures and support
2394a775e8fSJustin T. Gibbsonly the above functionality over singly-linked lists.
240afe61c15SRodney W. Grimes.Pp
241afe61c15SRodney W. GrimesTail queues add the following functionality:
242afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
243afe61c15SRodney W. Grimes.It
244afe61c15SRodney W. GrimesEntries can be added at the end of a list.
2456c1d0fbfSArchie Cobbs.It
2466c1d0fbfSArchie CobbsThey may be traversed backwards, from tail to head.
247d57e28adSThomas Moestl.It
248d57e28adSThomas MoestlThey may be concatenated.
249afe61c15SRodney W. Grimes.El
250afe61c15SRodney W. GrimesHowever:
251afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
252afe61c15SRodney W. Grimes.It
253afe61c15SRodney W. GrimesAll list insertions and removals must specify the head of the list.
254afe61c15SRodney W. Grimes.It
255afe61c15SRodney W. GrimesEach head entry requires two pointers rather than one.
256afe61c15SRodney W. Grimes.It
257afe61c15SRodney W. GrimesCode size is about 15% greater and operations run about 20% slower
2584a775e8fSJustin T. Gibbsthan singly-linked lists.
259afe61c15SRodney W. Grimes.El
260afe61c15SRodney W. Grimes.Pp
261afe61c15SRodney W. GrimesIn the macro definitions,
262afe61c15SRodney W. Grimes.Fa TYPE
263afe61c15SRodney W. Grimesis the name of a user defined structure,
264afe61c15SRodney W. Grimesthat must contain a field of type
2654a775e8fSJustin T. Gibbs.Li SLIST_ENTRY ,
2664a775e8fSJustin T. Gibbs.Li STAILQ_ENTRY ,
267afe61c15SRodney W. Grimes.Li LIST_ENTRY ,
268afe61c15SRodney W. Grimesor
26924b85d18SPoul-Henning Kamp.Li TAILQ_ENTRY ,
270afe61c15SRodney W. Grimesnamed
271afe61c15SRodney W. Grimes.Fa NAME .
272afe61c15SRodney W. GrimesThe argument
273afe61c15SRodney W. Grimes.Fa HEADNAME
274afe61c15SRodney W. Grimesis the name of a user defined structure that must be declared
275afe61c15SRodney W. Grimesusing the macros
2764a775e8fSJustin T. Gibbs.Li SLIST_HEAD ,
2774a775e8fSJustin T. Gibbs.Li STAILQ_HEAD ,
278afe61c15SRodney W. Grimes.Li LIST_HEAD ,
279afe61c15SRodney W. Grimesor
28024b85d18SPoul-Henning Kamp.Li TAILQ_HEAD .
281afe61c15SRodney W. GrimesSee the examples below for further explanation of how these
282afe61c15SRodney W. Grimesmacros are used.
2834a775e8fSJustin T. Gibbs.Sh SINGLY-LINKED LISTS
2844a775e8fSJustin T. GibbsA singly-linked list is headed by a structure defined by the
2854a775e8fSJustin T. Gibbs.Nm SLIST_HEAD
2864a775e8fSJustin T. Gibbsmacro.
2874a775e8fSJustin T. GibbsThis structure contains a single pointer to the first element
2884a775e8fSJustin T. Gibbson the list.
2894a775e8fSJustin T. GibbsThe elements are singly linked for minimum space and pointer manipulation
2904a775e8fSJustin T. Gibbsoverhead at the expense of O(n) removal for arbitrary elements.
2914a775e8fSJustin T. GibbsNew elements can be added to the list after an existing element or
2924a775e8fSJustin T. Gibbsat the head of the list.
2934a775e8fSJustin T. GibbsAn
2944a775e8fSJustin T. Gibbs.Fa SLIST_HEAD
2954a775e8fSJustin T. Gibbsstructure is declared as follows:
2964a775e8fSJustin T. Gibbs.Bd -literal -offset indent
2974a775e8fSJustin T. GibbsSLIST_HEAD(HEADNAME, TYPE) head;
2984a775e8fSJustin T. Gibbs.Ed
2998f20a914SMike Pritchard.Pp
3004a775e8fSJustin T. Gibbswhere
3014a775e8fSJustin T. Gibbs.Fa HEADNAME
3024a775e8fSJustin T. Gibbsis the name of the structure to be defined, and
3034a775e8fSJustin T. Gibbs.Fa TYPE
3044a775e8fSJustin T. Gibbsis the type of the elements to be linked into the list.
3054a775e8fSJustin T. GibbsA pointer to the head of the list can later be declared as:
3064a775e8fSJustin T. Gibbs.Bd -literal -offset indent
3074a775e8fSJustin T. Gibbsstruct HEADNAME *headp;
3084a775e8fSJustin T. Gibbs.Ed
3098f20a914SMike Pritchard.Pp
3104a775e8fSJustin T. Gibbs(The names
3114a775e8fSJustin T. Gibbs.Li head
3124a775e8fSJustin T. Gibbsand
3134a775e8fSJustin T. Gibbs.Li headp
3144a775e8fSJustin T. Gibbsare user selectable.)
3154a775e8fSJustin T. Gibbs.Pp
3164a775e8fSJustin T. GibbsThe macro
31703763fe0SJake Burkholder.Nm SLIST_HEAD_INITIALIZER
31803763fe0SJake Burkholderevaluates to an initializer for the list
31903763fe0SJake Burkholder.Fa head .
32003763fe0SJake Burkholder.Pp
32103763fe0SJake BurkholderThe macro
32279ea9bc4SAlexey Zelkin.Nm SLIST_EMPTY
32379ea9bc4SAlexey Zelkinevaluates to true if there are no elements in the list.
32479ea9bc4SAlexey Zelkin.Pp
32579ea9bc4SAlexey ZelkinThe macro
3264a775e8fSJustin T. Gibbs.Nm SLIST_ENTRY
3274a775e8fSJustin T. Gibbsdeclares a structure that connects the elements in
3284a775e8fSJustin T. Gibbsthe list.
3294a775e8fSJustin T. Gibbs.Pp
3304a775e8fSJustin T. GibbsThe macro
33179ea9bc4SAlexey Zelkin.Nm SLIST_FIRST
33279ea9bc4SAlexey Zelkinreturns the first element in the list or NULL if the list is empty.
33379ea9bc4SAlexey Zelkin.Pp
33479ea9bc4SAlexey ZelkinThe macro
33579ea9bc4SAlexey Zelkin.Nm SLIST_FOREACH
33679ea9bc4SAlexey Zelkintraverses the list referenced by
33779ea9bc4SAlexey Zelkin.Fa head
33879ea9bc4SAlexey Zelkinin the forward direction, assigning each element in
33979ea9bc4SAlexey Zelkinturn to
34079ea9bc4SAlexey Zelkin.Fa var .
34179ea9bc4SAlexey Zelkin.Pp
34279ea9bc4SAlexey ZelkinThe macro
3432724bce2SAlexander Kabaev.Nm SLIST_FOREACH_SAFE
3442724bce2SAlexander Kabaevtraverses the list referenced by
3452724bce2SAlexander Kabaev.Fa head
3462724bce2SAlexander Kabaevin the forward direction, assigning each element in
3472724bce2SAlexander Kabaevturn to
3482724bce2SAlexander Kabaev.Fa var .
3492724bce2SAlexander KabaevHowever, unlike
3502724bce2SAlexander Kabaev.Fn SLIST_FOREACH
3512724bce2SAlexander Kabaevhere it is permitted to both remove
3522724bce2SAlexander Kabaev.Fa var
3532724bce2SAlexander Kabaevas well as free it from within the loop safely without interfering with the
3542724bce2SAlexander Kabaevtraversal.
3552724bce2SAlexander Kabaev.Pp
3562724bce2SAlexander KabaevThe macro
3574a775e8fSJustin T. Gibbs.Nm SLIST_INIT
3584a775e8fSJustin T. Gibbsinitializes the list referenced by
3594a775e8fSJustin T. Gibbs.Fa head .
3604a775e8fSJustin T. Gibbs.Pp
3614a775e8fSJustin T. GibbsThe macro
3624a775e8fSJustin T. Gibbs.Nm SLIST_INSERT_HEAD
3634a775e8fSJustin T. Gibbsinserts the new element
3644a775e8fSJustin T. Gibbs.Fa elm
3654a775e8fSJustin T. Gibbsat the head of the list.
3664a775e8fSJustin T. Gibbs.Pp
3674a775e8fSJustin T. GibbsThe macro
3684a775e8fSJustin T. Gibbs.Nm SLIST_INSERT_AFTER
3694a775e8fSJustin T. Gibbsinserts the new element
3704a775e8fSJustin T. Gibbs.Fa elm
3714a775e8fSJustin T. Gibbsafter the element
3724a775e8fSJustin T. Gibbs.Fa listelm .
3734a775e8fSJustin T. Gibbs.Pp
3744a775e8fSJustin T. GibbsThe macro
37579ea9bc4SAlexey Zelkin.Nm SLIST_NEXT
37679ea9bc4SAlexey Zelkinreturns the next element in the list.
37779ea9bc4SAlexey Zelkin.Pp
37879ea9bc4SAlexey ZelkinThe macro
3794a775e8fSJustin T. Gibbs.Nm SLIST_REMOVE_HEAD
3804a775e8fSJustin T. Gibbsremoves the element
3814a775e8fSJustin T. Gibbs.Fa elm
3824a775e8fSJustin T. Gibbsfrom the head of the list.
3834a775e8fSJustin T. GibbsFor optimum efficiency,
3844a775e8fSJustin T. Gibbselements being removed from the head of the list should explicitly use
3854a775e8fSJustin T. Gibbsthis macro instead of the generic
3864a775e8fSJustin T. Gibbs.Fa SLIST_REMOVE
3874a775e8fSJustin T. Gibbsmacro.
3884a775e8fSJustin T. Gibbs.Pp
3894a775e8fSJustin T. GibbsThe macro
3904a775e8fSJustin T. Gibbs.Nm SLIST_REMOVE
3914a775e8fSJustin T. Gibbsremoves the element
3924a775e8fSJustin T. Gibbs.Fa elm
3934a775e8fSJustin T. Gibbsfrom the list.
3944a775e8fSJustin T. Gibbs.Sh SINGLY-LINKED LIST EXAMPLE
3954a775e8fSJustin T. Gibbs.Bd -literal
39603763fe0SJake BurkholderSLIST_HEAD(slisthead, entry) head =
39703763fe0SJake Burkholder    SLIST_HEAD_INITIALIZER(head);
3984a775e8fSJustin T. Gibbsstruct slisthead *headp;		/* Singly-linked List head. */
3994a775e8fSJustin T. Gibbsstruct entry {
4004a775e8fSJustin T. Gibbs	...
4014a775e8fSJustin T. Gibbs	SLIST_ENTRY(entry) entries;	/* Singly-linked List. */
4024a775e8fSJustin T. Gibbs	...
4034a775e8fSJustin T. Gibbs} *n1, *n2, *n3, *np;
4044a775e8fSJustin T. Gibbs
4054a775e8fSJustin T. GibbsSLIST_INIT(&head);			/* Initialize the list. */
4064a775e8fSJustin T. Gibbs
4074a775e8fSJustin T. Gibbsn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
4084a775e8fSJustin T. GibbsSLIST_INSERT_HEAD(&head, n1, entries);
4094a775e8fSJustin T. Gibbs
4104a775e8fSJustin T. Gibbsn2 = malloc(sizeof(struct entry));	/* Insert after. */
4114a775e8fSJustin T. GibbsSLIST_INSERT_AFTER(n1, n2, entries);
4124a775e8fSJustin T. Gibbs
4134a775e8fSJustin T. GibbsSLIST_REMOVE(&head, n2, entry, entries);/* Deletion. */
4144a775e8fSJustin T. Gibbsfree(n2);
4154a775e8fSJustin T. Gibbs
41679ea9bc4SAlexey Zelkinn3 = SLIST_FIRST(&head);
41703763fe0SJake BurkholderSLIST_REMOVE_HEAD(&head, entries);	/* Deletion from the head. */
4184a775e8fSJustin T. Gibbsfree(n3);
4194a775e8fSJustin T. Gibbs					/* Forward traversal. */
42079ea9bc4SAlexey ZelkinSLIST_FOREACH(np, &head, entries)
4214a775e8fSJustin T. Gibbs	np-> ...
4222724bce2SAlexander Kabaev					/* Safe forward traversal. */
4232724bce2SAlexander KabaevSLIST_FOREACH_SAFE(np, &head, entries, np_temp) {
4242724bce2SAlexander Kabaev	np->do_stuff();
4252724bce2SAlexander Kabaev	...
4262724bce2SAlexander Kabaev	SLIST_REMOVE(&head, np, entry, entries);
4272724bce2SAlexander Kabaev	free(np);
4282724bce2SAlexander Kabaev}
4294a775e8fSJustin T. Gibbs
43079ea9bc4SAlexey Zelkinwhile (!SLIST_EMPTY(&head)) {		/* List Deletion. */
43179ea9bc4SAlexey Zelkin	n1 = SLIST_FIRST(&head);
4324a775e8fSJustin T. Gibbs	SLIST_REMOVE_HEAD(&head, entries);
4334a775e8fSJustin T. Gibbs	free(n1);
4344a775e8fSJustin T. Gibbs}
4354a775e8fSJustin T. Gibbs.Ed
4364a775e8fSJustin T. Gibbs.Sh SINGLY-LINKED TAIL QUEUES
4374a775e8fSJustin T. GibbsA singly-linked tail queue is headed by a structure defined by the
4384a775e8fSJustin T. Gibbs.Nm STAILQ_HEAD
4394a775e8fSJustin T. Gibbsmacro.
4404a775e8fSJustin T. GibbsThis structure contains a pair of pointers,
4414a775e8fSJustin T. Gibbsone to the first element in the tail queue and the other to
4424a775e8fSJustin T. Gibbsthe last element in the tail queue.
4434a775e8fSJustin T. GibbsThe elements are singly linked for minimum space and pointer
4444a775e8fSJustin T. Gibbsmanipulation overhead at the expense of O(n) removal for arbitrary
4454a775e8fSJustin T. Gibbselements.
4464a775e8fSJustin T. GibbsNew elements can be added to the tail queue after an existing element,
4474a775e8fSJustin T. Gibbsat the head of the tail queue, or at the end of the tail queue.
4484a775e8fSJustin T. GibbsA
4494a775e8fSJustin T. Gibbs.Fa STAILQ_HEAD
4504a775e8fSJustin T. Gibbsstructure is declared as follows:
4514a775e8fSJustin T. Gibbs.Bd -literal -offset indent
4524a775e8fSJustin T. GibbsSTAILQ_HEAD(HEADNAME, TYPE) head;
4534a775e8fSJustin T. Gibbs.Ed
4548f20a914SMike Pritchard.Pp
4554a775e8fSJustin T. Gibbswhere
4564a775e8fSJustin T. Gibbs.Li HEADNAME
4574a775e8fSJustin T. Gibbsis the name of the structure to be defined, and
4584a775e8fSJustin T. Gibbs.Li TYPE
4594a775e8fSJustin T. Gibbsis the type of the elements to be linked into the tail queue.
4604a775e8fSJustin T. GibbsA pointer to the head of the tail queue can later be declared as:
4614a775e8fSJustin T. Gibbs.Bd -literal -offset indent
4624a775e8fSJustin T. Gibbsstruct HEADNAME *headp;
4634a775e8fSJustin T. Gibbs.Ed
4648f20a914SMike Pritchard.Pp
4654a775e8fSJustin T. Gibbs(The names
4664a775e8fSJustin T. Gibbs.Li head
4674a775e8fSJustin T. Gibbsand
4684a775e8fSJustin T. Gibbs.Li headp
4694a775e8fSJustin T. Gibbsare user selectable.)
4704a775e8fSJustin T. Gibbs.Pp
4714a775e8fSJustin T. GibbsThe macro
47203763fe0SJake Burkholder.Nm STAILQ_HEAD_INITIALIZER
47303763fe0SJake Burkholderevaluates to an initializer for the tail queue
47403763fe0SJake Burkholder.Fa head .
47503763fe0SJake Burkholder.Pp
47603763fe0SJake BurkholderThe macro
477d57e28adSThomas Moestl.Nm STAILQ_CONCAT
478d57e28adSThomas Moestlconcatenates the tail queue headed by
479d57e28adSThomas Moestl.Fa head2
480d57e28adSThomas Moestlonto the end of the one headed by
481d57e28adSThomas Moestl.Fa head1
482d57e28adSThomas Moestlremoving all entries from the former.
483d57e28adSThomas Moestl.Pp
484d57e28adSThomas MoestlThe macro
48579ea9bc4SAlexey Zelkin.Nm STAILQ_EMPTY
48679ea9bc4SAlexey Zelkinevaluates to true if there are no items on the tail queue.
48779ea9bc4SAlexey Zelkin.Pp
48879ea9bc4SAlexey ZelkinThe macro
4894a775e8fSJustin T. Gibbs.Nm STAILQ_ENTRY
4904a775e8fSJustin T. Gibbsdeclares a structure that connects the elements in
4914a775e8fSJustin T. Gibbsthe tail queue.
4924a775e8fSJustin T. Gibbs.Pp
4934a775e8fSJustin T. GibbsThe macro
49479ea9bc4SAlexey Zelkin.Nm STAILQ_FIRST
49579ea9bc4SAlexey Zelkinreturns the first item on the tail queue or NULL if the tail queue
49679ea9bc4SAlexey Zelkinis empty.
49779ea9bc4SAlexey Zelkin.Pp
49879ea9bc4SAlexey ZelkinThe macro
49979ea9bc4SAlexey Zelkin.Nm STAILQ_FOREACH
50079ea9bc4SAlexey Zelkintraverses the tail queue referenced by
50179ea9bc4SAlexey Zelkin.Fa head
50279ea9bc4SAlexey Zelkinin the forward direction, assigning each element
50379ea9bc4SAlexey Zelkinin turn to
50479ea9bc4SAlexey Zelkin.Fa var .
50579ea9bc4SAlexey Zelkin.Pp
50679ea9bc4SAlexey ZelkinThe macro
5072724bce2SAlexander Kabaev.Nm STAILQ_FOREACH_SAFE
5082724bce2SAlexander Kabaevtraverses the tail queue referenced by
5092724bce2SAlexander Kabaev.Fa head
5102724bce2SAlexander Kabaevin the forward direction, assigning each element
5112724bce2SAlexander Kabaevin turn to
5122724bce2SAlexander Kabaev.Fa var .
5132724bce2SAlexander KabaevHowever, unlike
5142724bce2SAlexander Kabaev.Fn STAILQ_FOREACH
5152724bce2SAlexander Kabaevhere it is permitted to both remove
5162724bce2SAlexander Kabaev.Fa var
5172724bce2SAlexander Kabaevas well as free it from within the loop safely without interfering with the
5182724bce2SAlexander Kabaevtraversal.
5192724bce2SAlexander Kabaev.Pp
5202724bce2SAlexander KabaevThe macro
5214a775e8fSJustin T. Gibbs.Nm STAILQ_INIT
5224a775e8fSJustin T. Gibbsinitializes the tail queue referenced by
5234a775e8fSJustin T. Gibbs.Fa head .
5244a775e8fSJustin T. Gibbs.Pp
5254a775e8fSJustin T. GibbsThe macro
5264a775e8fSJustin T. Gibbs.Nm STAILQ_INSERT_HEAD
5274a775e8fSJustin T. Gibbsinserts the new element
5284a775e8fSJustin T. Gibbs.Fa elm
5294a775e8fSJustin T. Gibbsat the head of the tail queue.
5304a775e8fSJustin T. Gibbs.Pp
5314a775e8fSJustin T. GibbsThe macro
5324a775e8fSJustin T. Gibbs.Nm STAILQ_INSERT_TAIL
5334a775e8fSJustin T. Gibbsinserts the new element
5344a775e8fSJustin T. Gibbs.Fa elm
5354a775e8fSJustin T. Gibbsat the end of the tail queue.
5364a775e8fSJustin T. Gibbs.Pp
5374a775e8fSJustin T. GibbsThe macro
5384a775e8fSJustin T. Gibbs.Nm STAILQ_INSERT_AFTER
5394a775e8fSJustin T. Gibbsinserts the new element
5404a775e8fSJustin T. Gibbs.Fa elm
5414a775e8fSJustin T. Gibbsafter the element
5424a775e8fSJustin T. Gibbs.Fa listelm .
5434a775e8fSJustin T. Gibbs.Pp
5444a775e8fSJustin T. GibbsThe macro
54579ea9bc4SAlexey Zelkin.Nm STAILQ_LAST
54679ea9bc4SAlexey Zelkinreturns the last item on the tail queue.
547982ba1cbSKirk McKusickIf the tail queue is empty the return value is
548982ba1cbSKirk McKusick.Dv NULL .
54979ea9bc4SAlexey Zelkin.Pp
55079ea9bc4SAlexey ZelkinThe macro
55179ea9bc4SAlexey Zelkin.Nm STAILQ_NEXT
55279ea9bc4SAlexey Zelkinreturns the next item on the tail queue, or NULL this item is the last.
55379ea9bc4SAlexey Zelkin.Pp
55479ea9bc4SAlexey ZelkinThe macro
5554a775e8fSJustin T. Gibbs.Nm STAILQ_REMOVE_HEAD
556ce900f03SAlfred Perlsteinremoves the element at the head of the tail queue.
5574a775e8fSJustin T. GibbsFor optimum efficiency,
5584a775e8fSJustin T. Gibbselements being removed from the head of the tail queue should
5594a775e8fSJustin T. Gibbsuse this macro explicitly rather than the generic
5604a775e8fSJustin T. Gibbs.Fa STAILQ_REMOVE
5614a775e8fSJustin T. Gibbsmacro.
5624a775e8fSJustin T. Gibbs.Pp
5634a775e8fSJustin T. GibbsThe macro
5644a775e8fSJustin T. Gibbs.Nm STAILQ_REMOVE
5654a775e8fSJustin T. Gibbsremoves the element
5664a775e8fSJustin T. Gibbs.Fa elm
5674a775e8fSJustin T. Gibbsfrom the tail queue.
5684a775e8fSJustin T. Gibbs.Sh SINGLY-LINKED TAIL QUEUE EXAMPLE
5694a775e8fSJustin T. Gibbs.Bd -literal
57003763fe0SJake BurkholderSTAILQ_HEAD(stailhead, entry) head =
57103763fe0SJake Burkholder    STAILQ_HEAD_INITIALIZER(head);
5724a775e8fSJustin T. Gibbsstruct stailhead *headp;		/* Singly-linked tail queue head. */
5734a775e8fSJustin T. Gibbsstruct entry {
5744a775e8fSJustin T. Gibbs	...
5754a775e8fSJustin T. Gibbs	STAILQ_ENTRY(entry) entries;	/* Tail queue. */
5764a775e8fSJustin T. Gibbs	...
5774a775e8fSJustin T. Gibbs} *n1, *n2, *n3, *np;
5784a775e8fSJustin T. Gibbs
5794a775e8fSJustin T. GibbsSTAILQ_INIT(&head);			/* Initialize the queue. */
5804a775e8fSJustin T. Gibbs
5814a775e8fSJustin T. Gibbsn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
5824a775e8fSJustin T. GibbsSTAILQ_INSERT_HEAD(&head, n1, entries);
5834a775e8fSJustin T. Gibbs
5844a775e8fSJustin T. Gibbsn1 = malloc(sizeof(struct entry));	/* Insert at the tail. */
5854a775e8fSJustin T. GibbsSTAILQ_INSERT_TAIL(&head, n1, entries);
5864a775e8fSJustin T. Gibbs
5874a775e8fSJustin T. Gibbsn2 = malloc(sizeof(struct entry));	/* Insert after. */
5884a775e8fSJustin T. GibbsSTAILQ_INSERT_AFTER(&head, n1, n2, entries);
5894a775e8fSJustin T. Gibbs					/* Deletion. */
5904a775e8fSJustin T. GibbsSTAILQ_REMOVE(&head, n2, entry, entries);
5914a775e8fSJustin T. Gibbsfree(n2);
59203763fe0SJake Burkholder					/* Deletion from the head. */
59379ea9bc4SAlexey Zelkinn3 = STAILQ_FIRST(&head);
5944a775e8fSJustin T. GibbsSTAILQ_REMOVE_HEAD(&head, entries);
5954a775e8fSJustin T. Gibbsfree(n3);
5964a775e8fSJustin T. Gibbs					/* Forward traversal. */
59779ea9bc4SAlexey ZelkinSTAILQ_FOREACH(np, &head, entries)
5984a775e8fSJustin T. Gibbs	np-> ...
5992724bce2SAlexander Kabaev					/* Safe forward traversal. */
6002724bce2SAlexander KabaevSTAILQ_FOREACH_SAFE(np, &head, entries, np_temp) {
6012724bce2SAlexander Kabaev	np->do_stuff();
6022724bce2SAlexander Kabaev	...
6032724bce2SAlexander Kabaev	STAILQ_REMOVE(&head, np, entry, entries);
6042724bce2SAlexander Kabaev	free(np);
6052724bce2SAlexander Kabaev}
6064a775e8fSJustin T. Gibbs					/* TailQ Deletion. */
60779ea9bc4SAlexey Zelkinwhile (!STAILQ_EMPTY(&head)) {
60803763fe0SJake Burkholder	n1 = STAILQ_FIRST(&head);
609266e33fdSJohn Baldwin	STAILQ_REMOVE_HEAD(&head, entries);
6104a775e8fSJustin T. Gibbs	free(n1);
6114a775e8fSJustin T. Gibbs}
6124a775e8fSJustin T. Gibbs					/* Faster TailQ Deletion. */
61379ea9bc4SAlexey Zelkinn1 = STAILQ_FIRST(&head);
6144a775e8fSJustin T. Gibbswhile (n1 != NULL) {
61579ea9bc4SAlexey Zelkin	n2 = STAILQ_NEXT(n1, entries);
6164a775e8fSJustin T. Gibbs	free(n1);
6174a775e8fSJustin T. Gibbs	n1 = n2;
6184a775e8fSJustin T. Gibbs}
6194a775e8fSJustin T. GibbsSTAILQ_INIT(&head);
6204a775e8fSJustin T. Gibbs.Ed
621afe61c15SRodney W. Grimes.Sh LISTS
622afe61c15SRodney W. GrimesA list is headed by a structure defined by the
623afe61c15SRodney W. Grimes.Nm LIST_HEAD
624afe61c15SRodney W. Grimesmacro.
625afe61c15SRodney W. GrimesThis structure contains a single pointer to the first element
626afe61c15SRodney W. Grimeson the list.
627afe61c15SRodney W. GrimesThe elements are doubly linked so that an arbitrary element can be
628afe61c15SRodney W. Grimesremoved without traversing the list.
6294a775e8fSJustin T. GibbsNew elements can be added to the list after an existing element,
6304a775e8fSJustin T. Gibbsbefore an existing element, or at the head of the list.
631afe61c15SRodney W. GrimesA
632afe61c15SRodney W. Grimes.Fa LIST_HEAD
633afe61c15SRodney W. Grimesstructure is declared as follows:
634afe61c15SRodney W. Grimes.Bd -literal -offset indent
635afe61c15SRodney W. GrimesLIST_HEAD(HEADNAME, TYPE) head;
636afe61c15SRodney W. Grimes.Ed
6378f20a914SMike Pritchard.Pp
638afe61c15SRodney W. Grimeswhere
639afe61c15SRodney W. Grimes.Fa HEADNAME
640afe61c15SRodney W. Grimesis the name of the structure to be defined, and
641afe61c15SRodney W. Grimes.Fa TYPE
642afe61c15SRodney W. Grimesis the type of the elements to be linked into the list.
643afe61c15SRodney W. GrimesA pointer to the head of the list can later be declared as:
644afe61c15SRodney W. Grimes.Bd -literal -offset indent
645afe61c15SRodney W. Grimesstruct HEADNAME *headp;
646afe61c15SRodney W. Grimes.Ed
6478f20a914SMike Pritchard.Pp
648afe61c15SRodney W. Grimes(The names
649afe61c15SRodney W. Grimes.Li head
650afe61c15SRodney W. Grimesand
651afe61c15SRodney W. Grimes.Li headp
652afe61c15SRodney W. Grimesare user selectable.)
653afe61c15SRodney W. Grimes.Pp
654afe61c15SRodney W. GrimesThe macro
65503763fe0SJake Burkholder.Nm LIST_HEAD_INITIALIZER
65603763fe0SJake Burkholderevaluates to an initializer for the list
65703763fe0SJake Burkholder.Fa head .
65803763fe0SJake Burkholder.Pp
65903763fe0SJake BurkholderThe macro
66079ea9bc4SAlexey Zelkin.Nm LIST_EMPTY
661ddbb94adSTom Rhodesevaluates to true if there are no elements in the list.
66279ea9bc4SAlexey Zelkin.Pp
66379ea9bc4SAlexey ZelkinThe macro
664afe61c15SRodney W. Grimes.Nm LIST_ENTRY
665afe61c15SRodney W. Grimesdeclares a structure that connects the elements in
666afe61c15SRodney W. Grimesthe list.
667afe61c15SRodney W. Grimes.Pp
668afe61c15SRodney W. GrimesThe macro
66979ea9bc4SAlexey Zelkin.Nm LIST_FIRST
67079ea9bc4SAlexey Zelkinreturns the first element in the list or NULL if the list
67179ea9bc4SAlexey Zelkinis empty.
67279ea9bc4SAlexey Zelkin.Pp
67379ea9bc4SAlexey ZelkinThe macro
67479ea9bc4SAlexey Zelkin.Nm LIST_FOREACH
67579ea9bc4SAlexey Zelkintraverses the list referenced by
67679ea9bc4SAlexey Zelkin.Fa head
67779ea9bc4SAlexey Zelkinin the forward direction, assigning each element in turn to
67879ea9bc4SAlexey Zelkin.Fa var .
67979ea9bc4SAlexey Zelkin.Pp
68079ea9bc4SAlexey ZelkinThe macro
6814250a68eSBosko Milekic.Nm LIST_FOREACH_SAFE
6824250a68eSBosko Milekictraverses the list referenced by
6834250a68eSBosko Milekic.Fa head
6844250a68eSBosko Milekicin the forward direction, assigning each element in turn to
6854250a68eSBosko Milekic.Fa var .
6864250a68eSBosko MilekicHowever, unlike
6874250a68eSBosko Milekic.Fn LIST_FOREACH
6884250a68eSBosko Milekichere it is permitted to both remove
6894250a68eSBosko Milekic.Fa var
6904250a68eSBosko Milekicas well as free it from within the loop safely without interfering with the
6914250a68eSBosko Milekictraversal.
6924250a68eSBosko Milekic.Pp
6934250a68eSBosko MilekicThe macro
694afe61c15SRodney W. Grimes.Nm LIST_INIT
695afe61c15SRodney W. Grimesinitializes the list referenced by
696afe61c15SRodney W. Grimes.Fa head .
697afe61c15SRodney W. Grimes.Pp
698afe61c15SRodney W. GrimesThe macro
699afe61c15SRodney W. Grimes.Nm LIST_INSERT_HEAD
700afe61c15SRodney W. Grimesinserts the new element
701afe61c15SRodney W. Grimes.Fa elm
702afe61c15SRodney W. Grimesat the head of the list.
703afe61c15SRodney W. Grimes.Pp
704afe61c15SRodney W. GrimesThe macro
705afe61c15SRodney W. Grimes.Nm LIST_INSERT_AFTER
706afe61c15SRodney W. Grimesinserts the new element
707afe61c15SRodney W. Grimes.Fa elm
708afe61c15SRodney W. Grimesafter the element
709afe61c15SRodney W. Grimes.Fa listelm .
710afe61c15SRodney W. Grimes.Pp
711afe61c15SRodney W. GrimesThe macro
7127658b0a2SJustin T. Gibbs.Nm LIST_INSERT_BEFORE
7137658b0a2SJustin T. Gibbsinserts the new element
7147658b0a2SJustin T. Gibbs.Fa elm
7157658b0a2SJustin T. Gibbsbefore the element
7167658b0a2SJustin T. Gibbs.Fa listelm .
7177658b0a2SJustin T. Gibbs.Pp
7187658b0a2SJustin T. GibbsThe macro
71979ea9bc4SAlexey Zelkin.Nm LIST_NEXT
72079ea9bc4SAlexey Zelkinreturns the next element in the list, or NULL if this is the last.
72179ea9bc4SAlexey Zelkin.Pp
72279ea9bc4SAlexey ZelkinThe macro
723afe61c15SRodney W. Grimes.Nm LIST_REMOVE
724afe61c15SRodney W. Grimesremoves the element
725afe61c15SRodney W. Grimes.Fa elm
726afe61c15SRodney W. Grimesfrom the list.
727afe61c15SRodney W. Grimes.Sh LIST EXAMPLE
728afe61c15SRodney W. Grimes.Bd -literal
72903763fe0SJake BurkholderLIST_HEAD(listhead, entry) head =
73003763fe0SJake Burkholder    LIST_HEAD_INITIALIZER(head);
731afe61c15SRodney W. Grimesstruct listhead *headp;			/* List head. */
732afe61c15SRodney W. Grimesstruct entry {
733afe61c15SRodney W. Grimes	...
734afe61c15SRodney W. Grimes	LIST_ENTRY(entry) entries;	/* List. */
735afe61c15SRodney W. Grimes	...
7364250a68eSBosko Milekic} *n1, *n2, *n3, *np, *np_temp;
737afe61c15SRodney W. Grimes
738afe61c15SRodney W. GrimesLIST_INIT(&head);			/* Initialize the list. */
739afe61c15SRodney W. Grimes
740afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
741afe61c15SRodney W. GrimesLIST_INSERT_HEAD(&head, n1, entries);
742afe61c15SRodney W. Grimes
743afe61c15SRodney W. Grimesn2 = malloc(sizeof(struct entry));	/* Insert after. */
744afe61c15SRodney W. GrimesLIST_INSERT_AFTER(n1, n2, entries);
7457658b0a2SJustin T. Gibbs
7467658b0a2SJustin T. Gibbsn3 = malloc(sizeof(struct entry));	/* Insert before. */
7477658b0a2SJustin T. GibbsLIST_INSERT_BEFORE(n2, n3, entries);
7487658b0a2SJustin T. Gibbs
7497658b0a2SJustin T. GibbsLIST_REMOVE(n2, entries);		/* Deletion. */
7507658b0a2SJustin T. Gibbsfree(n2);
751afe61c15SRodney W. Grimes					/* Forward traversal. */
75279ea9bc4SAlexey ZelkinLIST_FOREACH(np, &head, entries)
753afe61c15SRodney W. Grimes	np-> ...
754afe61c15SRodney W. Grimes
7554250a68eSBosko Milekic					/* Safe forward traversal. */
7564250a68eSBosko MilekicLIST_FOREACH_SAFE(np, &head, entries, np_temp) {
7574250a68eSBosko Milekic	np->do_stuff();
7584250a68eSBosko Milekic	...
7594250a68eSBosko Milekic	LIST_REMOVE(np, entries);
7604250a68eSBosko Milekic	free(np);
7614250a68eSBosko Milekic}
7624250a68eSBosko Milekic
76379ea9bc4SAlexey Zelkinwhile (!LIST_EMPTY(&head)) {		/* List Deletion. */
76479ea9bc4SAlexey Zelkin	n1 = LIST_FIRST(&head);
7657658b0a2SJustin T. Gibbs	LIST_REMOVE(n1, entries);
7667658b0a2SJustin T. Gibbs	free(n1);
7677658b0a2SJustin T. Gibbs}
7687658b0a2SJustin T. Gibbs
76903763fe0SJake Burkholdern1 = LIST_FIRST(&head);			/* Faster List Deletion. */
7707658b0a2SJustin T. Gibbswhile (n1 != NULL) {
77179ea9bc4SAlexey Zelkin	n2 = LIST_NEXT(n1, entries);
7727658b0a2SJustin T. Gibbs	free(n1);
7737658b0a2SJustin T. Gibbs	n1 = n2;
7747658b0a2SJustin T. Gibbs}
7757658b0a2SJustin T. GibbsLIST_INIT(&head);
776afe61c15SRodney W. Grimes.Ed
777afe61c15SRodney W. Grimes.Sh TAIL QUEUES
778afe61c15SRodney W. GrimesA tail queue is headed by a structure defined by the
779afe61c15SRodney W. Grimes.Nm TAILQ_HEAD
780afe61c15SRodney W. Grimesmacro.
781afe61c15SRodney W. GrimesThis structure contains a pair of pointers,
782afe61c15SRodney W. Grimesone to the first element in the tail queue and the other to
783afe61c15SRodney W. Grimesthe last element in the tail queue.
784afe61c15SRodney W. GrimesThe elements are doubly linked so that an arbitrary element can be
785afe61c15SRodney W. Grimesremoved without traversing the tail queue.
786afe61c15SRodney W. GrimesNew elements can be added to the tail queue after an existing element,
7874a775e8fSJustin T. Gibbsbefore an existing element, at the head of the tail queue,
7884a775e8fSJustin T. Gibbsor at the end of the tail queue.
789afe61c15SRodney W. GrimesA
790afe61c15SRodney W. Grimes.Fa TAILQ_HEAD
791afe61c15SRodney W. Grimesstructure is declared as follows:
792afe61c15SRodney W. Grimes.Bd -literal -offset indent
793afe61c15SRodney W. GrimesTAILQ_HEAD(HEADNAME, TYPE) head;
794afe61c15SRodney W. Grimes.Ed
7958f20a914SMike Pritchard.Pp
796afe61c15SRodney W. Grimeswhere
797afe61c15SRodney W. Grimes.Li HEADNAME
798afe61c15SRodney W. Grimesis the name of the structure to be defined, and
799afe61c15SRodney W. Grimes.Li TYPE
800afe61c15SRodney W. Grimesis the type of the elements to be linked into the tail queue.
801afe61c15SRodney W. GrimesA pointer to the head of the tail queue can later be declared as:
802afe61c15SRodney W. Grimes.Bd -literal -offset indent
803afe61c15SRodney W. Grimesstruct HEADNAME *headp;
804afe61c15SRodney W. Grimes.Ed
8058f20a914SMike Pritchard.Pp
806afe61c15SRodney W. Grimes(The names
807afe61c15SRodney W. Grimes.Li head
808afe61c15SRodney W. Grimesand
809afe61c15SRodney W. Grimes.Li headp
810afe61c15SRodney W. Grimesare user selectable.)
811afe61c15SRodney W. Grimes.Pp
812afe61c15SRodney W. GrimesThe macro
81303763fe0SJake Burkholder.Nm TAILQ_HEAD_INITIALIZER
81403763fe0SJake Burkholderevaluates to an initializer for the tail queue
81503763fe0SJake Burkholder.Fa head .
81603763fe0SJake Burkholder.Pp
81703763fe0SJake BurkholderThe macro
818d57e28adSThomas Moestl.Nm TAILQ_CONCAT
819d57e28adSThomas Moestlconcatenates the tail queue headed by
820d57e28adSThomas Moestl.Fa head2
821d57e28adSThomas Moestlonto the end of the one headed by
822d57e28adSThomas Moestl.Fa head1
823d57e28adSThomas Moestlremoving all entries from the former.
824d57e28adSThomas Moestl.Pp
825d57e28adSThomas MoestlThe macro
826c5c15c16SPoul-Henning Kamp.Nm TAILQ_EMPTY
827c5c15c16SPoul-Henning Kampevaluates to true if there are no items on the tail queue.
828c5c15c16SPoul-Henning Kamp.Pp
829c5c15c16SPoul-Henning KampThe macro
830afe61c15SRodney W. Grimes.Nm TAILQ_ENTRY
831afe61c15SRodney W. Grimesdeclares a structure that connects the elements in
832afe61c15SRodney W. Grimesthe tail queue.
833afe61c15SRodney W. Grimes.Pp
834afe61c15SRodney W. GrimesThe macro
835c5c15c16SPoul-Henning Kamp.Nm TAILQ_FIRST
836c5c15c16SPoul-Henning Kampreturns the first item on the tail queue or NULL if the tail queue
837c5c15c16SPoul-Henning Kampis empty.
838c5c15c16SPoul-Henning Kamp.Pp
839c5c15c16SPoul-Henning KampThe macro
84079ea9bc4SAlexey Zelkin.Nm TAILQ_FOREACH
84179ea9bc4SAlexey Zelkintraverses the tail queue referenced by
84279ea9bc4SAlexey Zelkin.Fa head
84379ea9bc4SAlexey Zelkinin the forward direction, assigning each element in turn to
84479ea9bc4SAlexey Zelkin.Fa var .
845fb5293cfSRuslan Ermilov.Fa var
846fb5293cfSRuslan Ermilovis set to
847fb5293cfSRuslan Ermilov.Dv NULL
848fb5293cfSRuslan Ermilovif the loop completes normally, or if there were no elements.
84979ea9bc4SAlexey Zelkin.Pp
85079ea9bc4SAlexey ZelkinThe macro
8516c1d0fbfSArchie Cobbs.Nm TAILQ_FOREACH_REVERSE
8526c1d0fbfSArchie Cobbstraverses the tail queue referenced by
8536c1d0fbfSArchie Cobbs.Fa head
8546c1d0fbfSArchie Cobbsin the reverse direction, assigning each element in turn to
8556c1d0fbfSArchie Cobbs.Fa var .
8566c1d0fbfSArchie Cobbs.Pp
8572724bce2SAlexander KabaevThe macros
8582724bce2SAlexander Kabaev.Nm TAILQ_FOREACH_SAFE
8592724bce2SAlexander Kabaevand
8602724bce2SAlexander Kabaev.Nm TAILQ_FOREACH_REVERSE_SAFE
8612724bce2SAlexander Kabaevtraverse the list referenced by
8622724bce2SAlexander Kabaev.Fa head
8632724bce2SAlexander Kabaevin the forward or reverse direction respectively,
8642724bce2SAlexander Kabaevassigning each element in turn to
8652724bce2SAlexander Kabaev.Fa var .
8663b96c71fSMike PritchardHowever, unlike their unsafe counterparts,
8672724bce2SAlexander Kabaev.Nm TAILQ_FOREACH
8682724bce2SAlexander Kabaevand
8692724bce2SAlexander Kabaev.Nm TAILQ_FOREACH_REVERSE
8702724bce2SAlexander Kabaevpermit to both remove
8712724bce2SAlexander Kabaev.Fa var
8722724bce2SAlexander Kabaevas well as free it from within the loop safely without interfering with the
8732724bce2SAlexander Kabaevtraversal.
8742724bce2SAlexander Kabaev.Pp
8756c1d0fbfSArchie CobbsThe macro
876afe61c15SRodney W. Grimes.Nm TAILQ_INIT
877afe61c15SRodney W. Grimesinitializes the tail queue referenced by
878afe61c15SRodney W. Grimes.Fa head .
879afe61c15SRodney W. Grimes.Pp
880afe61c15SRodney W. GrimesThe macro
881afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_HEAD
882afe61c15SRodney W. Grimesinserts the new element
883afe61c15SRodney W. Grimes.Fa elm
884afe61c15SRodney W. Grimesat the head of the tail queue.
885afe61c15SRodney W. Grimes.Pp
886afe61c15SRodney W. GrimesThe macro
887afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_TAIL
888afe61c15SRodney W. Grimesinserts the new element
889afe61c15SRodney W. Grimes.Fa elm
890afe61c15SRodney W. Grimesat the end of the tail queue.
891afe61c15SRodney W. Grimes.Pp
892afe61c15SRodney W. GrimesThe macro
893afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_AFTER
894afe61c15SRodney W. Grimesinserts the new element
895afe61c15SRodney W. Grimes.Fa elm
896afe61c15SRodney W. Grimesafter the element
897afe61c15SRodney W. Grimes.Fa listelm .
898afe61c15SRodney W. Grimes.Pp
899afe61c15SRodney W. GrimesThe macro
9007658b0a2SJustin T. Gibbs.Nm TAILQ_INSERT_BEFORE
9017658b0a2SJustin T. Gibbsinserts the new element
9027658b0a2SJustin T. Gibbs.Fa elm
9037658b0a2SJustin T. Gibbsbefore the element
9047658b0a2SJustin T. Gibbs.Fa listelm .
9057658b0a2SJustin T. Gibbs.Pp
9067658b0a2SJustin T. GibbsThe macro
907c5c15c16SPoul-Henning Kamp.Nm TAILQ_LAST
908c5c15c16SPoul-Henning Kampreturns the last item on the tail queue.
909982ba1cbSKirk McKusickIf the tail queue is empty the return value is
910982ba1cbSKirk McKusick.Dv NULL .
911c5c15c16SPoul-Henning Kamp.Pp
912c5c15c16SPoul-Henning KampThe macro
913c5c15c16SPoul-Henning Kamp.Nm TAILQ_NEXT
91479ea9bc4SAlexey Zelkinreturns the next item on the tail queue, or NULL if this item is the last.
91579ea9bc4SAlexey Zelkin.Pp
91679ea9bc4SAlexey ZelkinThe macro
91779ea9bc4SAlexey Zelkin.Nm TAILQ_PREV
91879ea9bc4SAlexey Zelkinreturns the previous item on the tail queue, or NULL if this item
91979ea9bc4SAlexey Zelkinis the first.
920c5c15c16SPoul-Henning Kamp.Pp
921c5c15c16SPoul-Henning KampThe macro
922afe61c15SRodney W. Grimes.Nm TAILQ_REMOVE
923afe61c15SRodney W. Grimesremoves the element
924afe61c15SRodney W. Grimes.Fa elm
925afe61c15SRodney W. Grimesfrom the tail queue.
926afe61c15SRodney W. Grimes.Sh TAIL QUEUE EXAMPLE
927afe61c15SRodney W. Grimes.Bd -literal
92803763fe0SJake BurkholderTAILQ_HEAD(tailhead, entry) head =
92903763fe0SJake Burkholder    TAILQ_HEAD_INITIALIZER(head);
930afe61c15SRodney W. Grimesstruct tailhead *headp;			/* Tail queue head. */
931afe61c15SRodney W. Grimesstruct entry {
932afe61c15SRodney W. Grimes	...
933afe61c15SRodney W. Grimes	TAILQ_ENTRY(entry) entries;	/* Tail queue. */
934afe61c15SRodney W. Grimes	...
9357658b0a2SJustin T. Gibbs} *n1, *n2, *n3, *np;
936afe61c15SRodney W. Grimes
937afe61c15SRodney W. GrimesTAILQ_INIT(&head);			/* Initialize the queue. */
938afe61c15SRodney W. Grimes
939afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
940afe61c15SRodney W. GrimesTAILQ_INSERT_HEAD(&head, n1, entries);
941afe61c15SRodney W. Grimes
942afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the tail. */
943afe61c15SRodney W. GrimesTAILQ_INSERT_TAIL(&head, n1, entries);
944afe61c15SRodney W. Grimes
945afe61c15SRodney W. Grimesn2 = malloc(sizeof(struct entry));	/* Insert after. */
946afe61c15SRodney W. GrimesTAILQ_INSERT_AFTER(&head, n1, n2, entries);
9477658b0a2SJustin T. Gibbs
9487658b0a2SJustin T. Gibbsn3 = malloc(sizeof(struct entry));	/* Insert before. */
9493652ff55SJustin T. GibbsTAILQ_INSERT_BEFORE(n2, n3, entries);
9507658b0a2SJustin T. Gibbs
9517658b0a2SJustin T. GibbsTAILQ_REMOVE(&head, n2, entries);	/* Deletion. */
9527658b0a2SJustin T. Gibbsfree(n2);
953afe61c15SRodney W. Grimes					/* Forward traversal. */
95479ea9bc4SAlexey ZelkinTAILQ_FOREACH(np, &head, entries)
955afe61c15SRodney W. Grimes	np-> ...
9562724bce2SAlexander Kabaev					/* Safe forward traversal. */
9572724bce2SAlexander KabaevTAILQ_FOREACH_SAFE(np, &head, entries, np_temp) {
9582724bce2SAlexander Kabaev	np->do_stuff();
9592724bce2SAlexander Kabaev	...
9602724bce2SAlexander Kabaev	TAILQ_REMOVE(&head, np, entries);
9612724bce2SAlexander Kabaev	free(np);
9622724bce2SAlexander Kabaev}
9636c1d0fbfSArchie Cobbs					/* Reverse traversal. */
9646c1d0fbfSArchie CobbsTAILQ_FOREACH_REVERSE(np, &head, tailhead, entries)
9656c1d0fbfSArchie Cobbs	np-> ...
9667658b0a2SJustin T. Gibbs					/* TailQ Deletion. */
967d6c63818SMark Murraywhile (!TAILQ_EMPTY(&head)) {
968c5c15c16SPoul-Henning Kamp	n1 = TAILQ_FIRST(&head);
96979ea9bc4SAlexey Zelkin	TAILQ_REMOVE(&head, n1, entries);
9707658b0a2SJustin T. Gibbs	free(n1);
9717658b0a2SJustin T. Gibbs}
9727658b0a2SJustin T. Gibbs					/* Faster TailQ Deletion. */
973c5c15c16SPoul-Henning Kampn1 = TAILQ_FIRST(&head);
9747658b0a2SJustin T. Gibbswhile (n1 != NULL) {
975c5c15c16SPoul-Henning Kamp	n2 = TAILQ_NEXT(n1, entries);
9767658b0a2SJustin T. Gibbs	free(n1);
9777658b0a2SJustin T. Gibbs	n1 = n2;
9787658b0a2SJustin T. Gibbs}
9797658b0a2SJustin T. GibbsTAILQ_INIT(&head);
980afe61c15SRodney W. Grimes.Ed
981afe61c15SRodney W. Grimes.Sh HISTORY
982afe61c15SRodney W. GrimesThe
983afe61c15SRodney W. Grimes.Nm queue
98421421932SMike Pritchardfunctions first appeared in
98521421932SMike Pritchard.Bx 4.4 .
986