1*4bc2832dSnaddy.\" $OpenBSD: queue.3,v 1.70 2022/03/29 18:15:52 naddy Exp $ 2df930be7Sderaadt.\" $NetBSD: queue.3,v 1.4 1995/07/03 00:25:36 mycroft Exp $ 3df930be7Sderaadt.\" 4df930be7Sderaadt.\" Copyright (c) 1993 The Regents of the University of California. 5df930be7Sderaadt.\" All rights reserved. 6df930be7Sderaadt.\" 7df930be7Sderaadt.\" Redistribution and use in source and binary forms, with or without 8df930be7Sderaadt.\" modification, are permitted provided that the following conditions 9df930be7Sderaadt.\" are met: 10df930be7Sderaadt.\" 1. Redistributions of source code must retain the above copyright 11df930be7Sderaadt.\" notice, this list of conditions and the following disclaimer. 12df930be7Sderaadt.\" 2. Redistributions in binary form must reproduce the above copyright 13df930be7Sderaadt.\" notice, this list of conditions and the following disclaimer in the 14df930be7Sderaadt.\" documentation and/or other materials provided with the distribution. 1529295d1cSmillert.\" 3. Neither the name of the University nor the names of its contributors 16df930be7Sderaadt.\" may be used to endorse or promote products derived from this software 17df930be7Sderaadt.\" without specific prior written permission. 18df930be7Sderaadt.\" 19df930be7Sderaadt.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20df930be7Sderaadt.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21df930be7Sderaadt.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22df930be7Sderaadt.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23df930be7Sderaadt.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24df930be7Sderaadt.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25df930be7Sderaadt.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26df930be7Sderaadt.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27df930be7Sderaadt.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28df930be7Sderaadt.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29df930be7Sderaadt.\" SUCH DAMAGE. 30df930be7Sderaadt.\" 31df930be7Sderaadt.\" @(#)queue.3 8.1 (Berkeley) 12/13/93 32df930be7Sderaadt.\" 333fd951e6Snaddy.Dd $Mdocdate: March 29 2022 $ 34d04ba2ccSjmc.Dt SLIST_INIT 3 35c0e8509eSaaron.Os 36df930be7Sderaadt.Sh NAME 379237eaaaSespie.Nm SLIST_ENTRY , 389237eaaaSespie.Nm SLIST_HEAD , 399237eaaaSespie.Nm SLIST_HEAD_INITIALIZER , 409237eaaaSespie.Nm SLIST_FIRST , 419237eaaaSespie.Nm SLIST_NEXT , 429237eaaaSespie.Nm SLIST_EMPTY , 439237eaaaSespie.Nm SLIST_FOREACH , 442acff70eSpirofti.Nm SLIST_FOREACH_SAFE , 459237eaaaSespie.Nm SLIST_INIT , 469237eaaaSespie.Nm SLIST_INSERT_AFTER , 479237eaaaSespie.Nm SLIST_INSERT_HEAD , 4861f9916fSnaddy.Nm SLIST_REMOVE_AFTER , 499237eaaaSespie.Nm SLIST_REMOVE_HEAD , 5014bdd124Sjason.Nm SLIST_REMOVE , 51df930be7Sderaadt.Nm LIST_ENTRY , 52df930be7Sderaadt.Nm LIST_HEAD , 530868d64cSespie.Nm LIST_HEAD_INITIALIZER , 540868d64cSespie.Nm LIST_FIRST , 550868d64cSespie.Nm LIST_NEXT , 569237eaaaSespie.Nm LIST_EMPTY , 579237eaaaSespie.Nm LIST_FOREACH , 582acff70eSpirofti.Nm LIST_FOREACH_SAFE , 59df930be7Sderaadt.Nm LIST_INIT , 60df930be7Sderaadt.Nm LIST_INSERT_AFTER , 61df930be7Sderaadt.Nm LIST_INSERT_BEFORE , 62df930be7Sderaadt.Nm LIST_INSERT_HEAD , 63df930be7Sderaadt.Nm LIST_REMOVE , 64df7c2479Sangelos.Nm LIST_REPLACE , 650868d64cSespie.Nm SIMPLEQ_ENTRY , 660868d64cSespie.Nm SIMPLEQ_HEAD , 670868d64cSespie.Nm SIMPLEQ_HEAD_INITIALIZER , 680868d64cSespie.Nm SIMPLEQ_FIRST , 690868d64cSespie.Nm SIMPLEQ_NEXT , 709237eaaaSespie.Nm SIMPLEQ_EMPTY , 719237eaaaSespie.Nm SIMPLEQ_FOREACH , 722acff70eSpirofti.Nm SIMPLEQ_FOREACH_SAFE , 730868d64cSespie.Nm SIMPLEQ_INIT , 7461f9916fSnaddy.Nm SIMPLEQ_INSERT_AFTER , 750868d64cSespie.Nm SIMPLEQ_INSERT_HEAD , 760868d64cSespie.Nm SIMPLEQ_INSERT_TAIL , 7761f9916fSnaddy.Nm SIMPLEQ_REMOVE_AFTER , 780868d64cSespie.Nm SIMPLEQ_REMOVE_HEAD , 7944ab62a3Smillert.Nm SIMPLEQ_CONCAT , 809322932cSmillert.Nm STAILQ_ENTRY , 819322932cSmillert.Nm STAILQ_HEAD , 829322932cSmillert.Nm STAILQ_HEAD_INITIALIZER , 839322932cSmillert.Nm STAILQ_FIRST , 849322932cSmillert.Nm STAILQ_NEXT , 859322932cSmillert.Nm STAILQ_LAST , 869322932cSmillert.Nm STAILQ_EMPTY , 879322932cSmillert.Nm STAILQ_FOREACH , 889322932cSmillert.Nm STAILQ_FOREACH_SAFE , 899322932cSmillert.Nm STAILQ_INIT , 909322932cSmillert.Nm STAILQ_INSERT_AFTER , 919322932cSmillert.Nm STAILQ_INSERT_HEAD , 929322932cSmillert.Nm STAILQ_INSERT_TAIL , 939322932cSmillert.Nm STAILQ_REMOVE , 949322932cSmillert.Nm STAILQ_REMOVE_AFTER , 959322932cSmillert.Nm STAILQ_REMOVE_HEAD , 969322932cSmillert.Nm STAILQ_CONCAT , 97df930be7Sderaadt.Nm TAILQ_ENTRY , 98df930be7Sderaadt.Nm TAILQ_HEAD , 990868d64cSespie.Nm TAILQ_HEAD_INITIALIZER , 1000868d64cSespie.Nm TAILQ_FIRST , 1010868d64cSespie.Nm TAILQ_NEXT , 1020868d64cSespie.Nm TAILQ_LAST , 1030868d64cSespie.Nm TAILQ_PREV , 1049237eaaaSespie.Nm TAILQ_EMPTY , 1059237eaaaSespie.Nm TAILQ_FOREACH , 1062acff70eSpirofti.Nm TAILQ_FOREACH_SAFE , 107c9cbb67dSderaadt.Nm TAILQ_FOREACH_REVERSE , 1082acff70eSpirofti.Nm TAILQ_FOREACH_REVERSE_SAFE , 109df930be7Sderaadt.Nm TAILQ_INIT , 110df930be7Sderaadt.Nm TAILQ_INSERT_AFTER , 111df930be7Sderaadt.Nm TAILQ_INSERT_BEFORE , 112df930be7Sderaadt.Nm TAILQ_INSERT_HEAD , 113df930be7Sderaadt.Nm TAILQ_INSERT_TAIL , 114df930be7Sderaadt.Nm TAILQ_REMOVE , 11544ab62a3Smillert.Nm TAILQ_REPLACE , 11644ab62a3Smillert.Nm TAILQ_CONCAT 1179322932cSmillert.Nd intrusive singly-linked and doubly-linked lists, simple queues, singly-linked and doubly-linked tail queues 118df930be7Sderaadt.Sh SYNOPSIS 119cfcc6981Stedu.In sys/queue.h 120431305c8Saaron.Pp 1219237eaaaSespie.Fn SLIST_ENTRY "TYPE" 1229237eaaaSespie.Fn SLIST_HEAD "HEADNAME" "TYPE" 1239237eaaaSespie.Fn SLIST_HEAD_INITIALIZER "SLIST_HEAD head" 1249237eaaaSespie.Ft "struct TYPE *" 1259237eaaaSespie.Fn SLIST_FIRST "SLIST_HEAD *head" 1269237eaaaSespie.Ft "struct TYPE *" 1275479c038Sguenther.Fn SLIST_NEXT "struct TYPE *listelm" "FIELDNAME" 128652a0345Sjmc.Ft int 1299237eaaaSespie.Fn SLIST_EMPTY "SLIST_HEAD *head" 1305479c038Sguenther.Fn SLIST_FOREACH "VARNAME" "SLIST_HEAD *head" "FIELDNAME" 1315479c038Sguenther.Fn SLIST_FOREACH_SAFE "VARNAME" "SLIST_HEAD *head" "FIELDNAME" "TEMP_VARNAME" 1329237eaaaSespie.Ft void 1339237eaaaSespie.Fn SLIST_INIT "SLIST_HEAD *head" 1349237eaaaSespie.Ft void 1355479c038Sguenther.Fn SLIST_INSERT_AFTER "struct TYPE *listelm" "struct TYPE *elm" "FIELDNAME" 1369237eaaaSespie.Ft void 1375479c038Sguenther.Fn SLIST_INSERT_HEAD "SLIST_HEAD *head" "struct TYPE *elm" "FIELDNAME" 1389237eaaaSespie.Ft void 1395479c038Sguenther.Fn SLIST_REMOVE_AFTER "struct TYPE *elm" "FIELDNAME" 14014bdd124Sjason.Ft void 1415479c038Sguenther.Fn SLIST_REMOVE_HEAD "SLIST_HEAD *head" "FIELDNAME" 142d377bb64Smillert.Ft void 1435479c038Sguenther.Fn SLIST_REMOVE "SLIST_HEAD *head" "struct TYPE *elm" "TYPE" "FIELDNAME" 144431305c8Saaron.Pp 145df930be7Sderaadt.Fn LIST_ENTRY "TYPE" 146df930be7Sderaadt.Fn LIST_HEAD "HEADNAME" "TYPE" 1470868d64cSespie.Fn LIST_HEAD_INITIALIZER "LIST_HEAD head" 1480868d64cSespie.Ft "struct TYPE *" 1490868d64cSespie.Fn LIST_FIRST "LIST_HEAD *head" 1500868d64cSespie.Ft "struct TYPE *" 1515479c038Sguenther.Fn LIST_NEXT "struct TYPE *listelm" "FIELDNAME" 152652a0345Sjmc.Ft int 1539237eaaaSespie.Fn LIST_EMPTY "LIST_HEAD *head" 1545479c038Sguenther.Fn LIST_FOREACH "VARNAME" "LIST_HEAD *head" "FIELDNAME" 1555479c038Sguenther.Fn LIST_FOREACH_SAFE "VARNAME" "LIST_HEAD *head" "FIELDNAME" "TEMP_VARNAME" 1560868d64cSespie.Ft void 157df930be7Sderaadt.Fn LIST_INIT "LIST_HEAD *head" 1580868d64cSespie.Ft void 1595479c038Sguenther.Fn LIST_INSERT_AFTER "struct TYPE *listelm" "struct TYPE *elm" "FIELDNAME" 1600868d64cSespie.Ft void 1615479c038Sguenther.Fn LIST_INSERT_BEFORE "struct TYPE *listelm" "struct TYPE *elm" "FIELDNAME" 1620868d64cSespie.Ft void 1635479c038Sguenther.Fn LIST_INSERT_HEAD "LIST_HEAD *head" "struct TYPE *elm" "FIELDNAME" 1640868d64cSespie.Ft void 1655479c038Sguenther.Fn LIST_REMOVE "struct TYPE *elm" "FIELDNAME" 166df7c2479Sangelos.Ft void 1675479c038Sguenther.Fn LIST_REPLACE "struct TYPE *elm" "struct TYPE *elm2" "FIELDNAME" 168431305c8Saaron.Pp 1690868d64cSespie.Fn SIMPLEQ_ENTRY "TYPE" 1700868d64cSespie.Fn SIMPLEQ_HEAD "HEADNAME" "TYPE" 1710868d64cSespie.Fn SIMPLEQ_HEAD_INITIALIZER "SIMPLEQ_HEAD head" 1720868d64cSespie.Ft "struct TYPE *" 1730868d64cSespie.Fn SIMPLEQ_FIRST "SIMPLEQ_HEAD *head" 1740868d64cSespie.Ft "struct TYPE *" 1755479c038Sguenther.Fn SIMPLEQ_NEXT "struct TYPE *listelm" "FIELDNAME" 176652a0345Sjmc.Ft int 177652a0345Sjmc.Fn SIMPLEQ_EMPTY "SIMPLEQ_HEAD *head" 1785479c038Sguenther.Fn SIMPLEQ_FOREACH "VARNAME" "SIMPLEQ_HEAD *head" "FIELDNAME" 1795479c038Sguenther.Fn SIMPLEQ_FOREACH_SAFE "VARNAME" "SIMPLEQ_HEAD *head" "FIELDNAME" "TEMP_VARNAME" 1800868d64cSespie.Ft void 1810868d64cSespie.Fn SIMPLEQ_INIT "SIMPLEQ_HEAD *head" 1820868d64cSespie.Ft void 1835479c038Sguenther.Fn SIMPLEQ_INSERT_AFTER "SIMPLEQ_HEAD *head" "struct TYPE *listelm" "struct TYPE *elm" "FIELDNAME" 18461f9916fSnaddy.Ft void 1855479c038Sguenther.Fn SIMPLEQ_INSERT_HEAD "SIMPLEQ_HEAD *head" "struct TYPE *elm" "FIELDNAME" 1860868d64cSespie.Ft void 1875479c038Sguenther.Fn SIMPLEQ_INSERT_TAIL "SIMPLEQ_HEAD *head" "struct TYPE *elm" "FIELDNAME" 1880868d64cSespie.Ft void 1895479c038Sguenther.Fn SIMPLEQ_REMOVE_AFTER "SIMPLEQ_HEAD *head" "struct TYPE *elm" "FIELDNAME" 1900868d64cSespie.Ft void 1915479c038Sguenther.Fn SIMPLEQ_REMOVE_HEAD "SIMPLEQ_HEAD *head" "FIELDNAME" 19244ab62a3Smillert.Fn SIMPLEQ_CONCAT "SIMPLEQ_HEAD *head1" "SIMPLEQ_HEAD *head2" 193431305c8Saaron.Pp 1949322932cSmillert.Fn STAILQ_ENTRY "TYPE" 1959322932cSmillert.Fn STAILQ_HEAD "HEADNAME" "TYPE" 1969322932cSmillert.Fn STAILQ_HEAD_INITIALIZER "STAILQ_HEAD head" 1979322932cSmillert.Fn STAILQ_FIRST "STAILQ_HEAD *head" 1989322932cSmillert.Fn STAILQ_NEXT "TYPE *elm" "STAILQ_ENTRY NAME" 1999322932cSmillert.Fn STAILQ_LAST "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME" 2009322932cSmillert.Fn STAILQ_EMPTY "STAILQ_HEAD *head" 2019322932cSmillert.Fn STAILQ_FOREACH "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" 2029322932cSmillert.Fn STAILQ_FOREACH_SAFE "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" "TYPE *temp_var" 2039322932cSmillert.Fn STAILQ_INIT "STAILQ_HEAD *head" 2049322932cSmillert.Fn STAILQ_INSERT_AFTER "STAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "STAILQ_ENTRY NAME" 2059322932cSmillert.Fn STAILQ_INSERT_HEAD "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME" 2069322932cSmillert.Fn STAILQ_INSERT_TAIL "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME" 2079322932cSmillert.Fn STAILQ_REMOVE "STAILQ_HEAD *head" "TYPE *elm" "TYPE" "STAILQ_ENTRY NAME" 2089322932cSmillert.Fn STAILQ_REMOVE_AFTER "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME" 2099322932cSmillert.Fn STAILQ_REMOVE_HEAD "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" 2109322932cSmillert.Fn STAILQ_CONCAT "STAILQ_HEAD *head1" "STAILQ_HEAD *head2" 2119322932cSmillert.Pp 212df930be7Sderaadt.Fn TAILQ_ENTRY "TYPE" 213df930be7Sderaadt.Fn TAILQ_HEAD "HEADNAME" "TYPE" 2140868d64cSespie.Fn TAILQ_HEAD_INITIALIZER "TAILQ_HEAD head" 2150868d64cSespie.Ft "struct TYPE *" 2160868d64cSespie.Fn TAILQ_FIRST "TAILQ_HEAD *head" 2170868d64cSespie.Ft "struct TYPE *" 2185479c038Sguenther.Fn TAILQ_NEXT "struct TYPE *listelm" "FIELDNAME" 2190868d64cSespie.Ft "struct TYPE *" 2205479c038Sguenther.Fn TAILQ_LAST "TAILQ_HEAD *head" "HEADNAME" 221a3d4d7bcSjmc.Ft "struct TYPE *" 2225479c038Sguenther.Fn TAILQ_PREV "struct TYPE *listelm" "HEADNAME" "FIELDNAME" 223652a0345Sjmc.Ft int 224c9cbb67dSderaadt.Fn TAILQ_EMPTY "TAILQ_HEAD *head" 2255479c038Sguenther.Fn TAILQ_FOREACH "VARNAME" "TAILQ_HEAD *head" "FIELDNAME" 2265479c038Sguenther.Fn TAILQ_FOREACH_SAFE "VARNAME" "TAILQ_HEAD *head" "FIELDNAME" "TEMP_VARNAME" 2275479c038Sguenther.Fn TAILQ_FOREACH_REVERSE "VARNAME" "TAILQ_HEAD *head" "HEADNAME" "FIELDNAME" 2285479c038Sguenther.Fn TAILQ_FOREACH_REVERSE_SAFE "VARNAME" "TAILQ_HEAD *head" "HEADNAME" "FIELDNAME" "TEMP_VARNAME" 2290868d64cSespie.Ft void 230df930be7Sderaadt.Fn TAILQ_INIT "TAILQ_HEAD *head" 2310868d64cSespie.Ft void 2325479c038Sguenther.Fn TAILQ_INSERT_AFTER "TAILQ_HEAD *head" "struct TYPE *listelm" "struct TYPE *elm" "FIELDNAME" 2330868d64cSespie.Ft void 2345479c038Sguenther.Fn TAILQ_INSERT_BEFORE "struct TYPE *listelm" "struct TYPE *elm" "FIELDNAME" 2350868d64cSespie.Ft void 2365479c038Sguenther.Fn TAILQ_INSERT_HEAD "TAILQ_HEAD *head" "struct TYPE *elm" "FIELDNAME" 2370868d64cSespie.Ft void 2385479c038Sguenther.Fn TAILQ_INSERT_TAIL "TAILQ_HEAD *head" "struct TYPE *elm" "FIELDNAME" 2390868d64cSespie.Ft void 2405479c038Sguenther.Fn TAILQ_REMOVE "TAILQ_HEAD *head" "struct TYPE *elm" "FIELDNAME" 24128601b65Sjmc.Ft void 2425479c038Sguenther.Fn TAILQ_REPLACE "TAILQ_HEAD *head" "struct TYPE *elm" "struct TYPE *elm2" "FIELDNAME" 243f21864e4Smpi.Fn TAILQ_CONCAT "TAILQ_HEAD *head1" "TAILQ_HEAD *head2" "FIELDNAME" 244df930be7Sderaadt.Sh DESCRIPTION 2459322932cSmillertThese macros define and operate on five types of data structures: 2469322932cSmillertsingly-linked lists, simple queues, lists, singly-linked tail queues, 2479322932cSmillertand tail queues. 2489322932cSmillertAll five structures support the following functionality: 249f33e0097Saaron.Pp 250df930be7Sderaadt.Bl -enum -compact -offset indent 251df930be7Sderaadt.It 252df930be7SderaadtInsertion of a new entry at the head of the list. 253df930be7Sderaadt.It 2549237eaaaSespieInsertion of a new entry after any element in the list. 255df930be7Sderaadt.It 2569237eaaaSespieRemoval of an entry from the head of the list. 257df930be7Sderaadt.It 258df930be7SderaadtForward traversal through the list. 259df930be7Sderaadt.El 260df930be7Sderaadt.Pp 26191c1d590SschwarzeThe following table provides a quick overview 26291c1d590Sschwarzeof which types support which additional macros: 2639322932cSmillert.Bl -column -offset 6n "LAST, PREV, FOREACH_REVERSE" SLIST LIST SIMPLEQ STAILQ TAILQ 2649322932cSmillert.It LAST, PREV, FOREACH_REVERSE Ta - Ta - Ta - Ta - Ta TAILQ 2659322932cSmillert.It INSERT_BEFORE, REPLACE Ta - Ta LIST Ta - Ta - Ta TAILQ 2669322932cSmillert.It INSERT_TAIL, CONCAT Ta - Ta - Ta SIMPLEQ Ta STAILQ Ta TAILQ 2679322932cSmillert.It REMOVE_AFTER, REMOVE_HEAD Ta SLIST Ta - Ta SIMPLEQ Ta STAILQ Ta - 2689322932cSmillert.It REMOVE Ta SLIST Ta LIST Ta - Ta STAILQ Ta TAILQ 26991c1d590Sschwarze.El 27091c1d590Sschwarze.Pp 2719322932cSmillertSingly-linked lists are the simplest of the five data structures 2729237eaaaSespieand support only the above functionality. 2739237eaaaSespieSingly-linked lists are ideal for applications with large datasets 274431305c8Saaronand few or no removals, or for implementing a LIFO queue. 2750868d64cSespie.Pp 2769322932cSmillertSimple queues and singly-linked tail queues add the following functionality: 2770868d64cSespie.Pp 2780868d64cSespie.Bl -enum -compact -offset indent 2790868d64cSespie.It 2809237eaaaSespieEntries can be added at the end of a list. 281df930be7Sderaadt.El 282f33e0097Saaron.Pp 283df930be7SderaadtHowever: 284f33e0097Saaron.Pp 285df930be7Sderaadt.Bl -enum -compact -offset indent 286df930be7Sderaadt.It 2879237eaaaSespieAll list insertions must specify the head of the list. 288df930be7Sderaadt.It 289df930be7SderaadtEach head entry requires two pointers rather than one. 290df930be7Sderaadt.It 291df930be7SderaadtCode size is about 15% greater and operations run about 20% slower 2929237eaaaSespiethan singly-linked lists. 2939237eaaaSespie.El 2949237eaaaSespie.Pp 2959322932cSmillertSimple queues and singly-linked tail queues are ideal for applications with 2969322932cSmillertlarge datasets and few or no removals, or for implementing a FIFO queue. 2979237eaaaSespie.Pp 298b9b58a6dSguentherAll doubly linked types of data structures (lists and tail queues) 299b9b58a6dSguentheradditionally allow: 3009237eaaaSespie.Pp 3019237eaaaSespie.Bl -enum -compact -offset indent 3029237eaaaSespie.It 3039237eaaaSespieInsertion of a new entry before any element in the list. 3049237eaaaSespie.It 3059237eaaaSespieRemoval of any entry in the list. 3069237eaaaSespie.El 3079237eaaaSespie.Pp 3089237eaaaSespieHowever: 3099237eaaaSespie.Pp 3109237eaaaSespie.Bl -enum -compact -offset indent 3119237eaaaSespie.It 312cc405d09SjmcEach element requires two pointers rather than one. 3139237eaaaSespie.It 3149237eaaaSespieCode size and execution time of operations (except for removal) is about 3159237eaaaSespietwice that of the singly-linked data-structures. 3169237eaaaSespie.El 3179237eaaaSespie.Pp 3189237eaaaSespieLists are the simplest of the doubly linked data structures and support 3199237eaaaSespieonly the above functionality over singly-linked lists. 3209237eaaaSespie.Pp 3219237eaaaSespieTail queues add the following functionality: 3229237eaaaSespie.Pp 3239237eaaaSespie.Bl -enum -compact -offset indent 3249237eaaaSespie.It 3259237eaaaSespieEntries can be added at the end of a list. 3269237eaaaSespie.It 3279237eaaaSespieThey may be traversed backwards, at a cost. 3289237eaaaSespie.El 3299237eaaaSespie.Pp 3309237eaaaSespieHowever: 3319237eaaaSespie.Pp 3329237eaaaSespie.Bl -enum -compact -offset indent 3339237eaaaSespie.It 3349237eaaaSespieAll list insertions and removals must specify the head of the list. 3359237eaaaSespie.It 3369237eaaaSespieEach head entry requires two pointers rather than one. 3379237eaaaSespie.It 3389237eaaaSespieCode size is about 15% greater and operations run about 20% slower 3399237eaaaSespiethan singly-linked lists. 340df930be7Sderaadt.El 341df930be7Sderaadt.Pp 342b9b58a6dSguentherAn additional type of data structure, circular queues, violated the C 343b9b58a6dSguentherlanguage aliasing rules and were miscompiled as a result. 344b9b58a6dSguentherAll code using them should be converted to another structure; 345b9b58a6dSguenthertail queues are usually the easiest to convert to. 346df930be7Sderaadt.Pp 34724e04962SschwarzeAll these lists and queues are intrusive: they link together user 34824e04962Sschwarzedefined structures containing a field of type 3499237eaaaSespie.Li SLIST_ENTRY , 350df930be7Sderaadt.Li LIST_ENTRY , 3510868d64cSespie.Li SIMPLEQ_ENTRY , 3529322932cSmillert.Li STAILQ_ENTRY , 353df930be7Sderaadtor 35424e04962Sschwarze.Li TAILQ_ENTRY . 35524e04962SschwarzeIn the macro definitions, 35624e04962Sschwarze.Fa TYPE 35724e04962Sschwarzeis the name tag of the user defined structure and 35824e04962Sschwarze.Fa FIELDNAME 35924e04962Sschwarzeis the name of the 36024e04962Sschwarze.Li *_ENTRY 36124e04962Sschwarzefield. 36224e04962SschwarzeIf an instance of the user defined structure needs to be a member of 36324e04962Sschwarzemultiple lists at the same time, the structure requires multiple 36424e04962Sschwarze.Li *_ENTRY 36524e04962Sschwarzefields, one for each list. 36624e04962Sschwarze.Pp 367df930be7SderaadtThe argument 368df930be7Sderaadt.Fa HEADNAME 3690868d64cSespieis the name tag of a user defined structure that must be declared 370df930be7Sderaadtusing the macros 3719237eaaaSespie.Fn SLIST_HEAD , 372f33e0097Saaron.Fn LIST_HEAD , 3730868d64cSespie.Fn SIMPLEQ_HEAD , 3749322932cSmillert.Fn STAILQ_HEAD , 375df930be7Sderaadtor 376b9b58a6dSguenther.Fn TAILQ_HEAD . 377431305c8SaaronSee the examples below for further explanation of how these macros are used. 378c8ff027bSjaredy.Sh SINGLY-LINKED LISTS 3799237eaaaSespieA singly-linked list is headed by a structure defined by the 3809237eaaaSespie.Fn SLIST_HEAD 3819237eaaaSespiemacro. 382431305c8SaaronThis structure contains a single pointer to the first element on the list. 3839237eaaaSespieThe elements are singly linked for minimum space and pointer manipulation 3849237eaaaSespieoverhead at the expense of O(n) removal for arbitrary elements. 3859237eaaaSespieNew elements can be added to the list after an existing element or 3869237eaaaSespieat the head of the list. 3879237eaaaSespieA 3889237eaaaSespie.Fa SLIST_HEAD 3899237eaaaSespiestructure is declared as follows: 3909237eaaaSespie.Bd -literal -offset indent 3919237eaaaSespieSLIST_HEAD(HEADNAME, TYPE) head; 3929237eaaaSespie.Ed 393431305c8Saaron.Pp 3949237eaaaSespiewhere 3959237eaaaSespie.Fa HEADNAME 3969237eaaaSespieis the name of the structure to be defined, and struct 3979237eaaaSespie.Fa TYPE 3989237eaaaSespieis the type of the elements to be linked into the list. 3999237eaaaSespieA pointer to the head of the list can later be declared as: 4009237eaaaSespie.Bd -literal -offset indent 4019237eaaaSespiestruct HEADNAME *headp; 4029237eaaaSespie.Ed 403431305c8Saaron.Pp 4049237eaaaSespie(The names 4059237eaaaSespie.Li head 4069237eaaaSespieand 4079237eaaaSespie.Li headp 4089237eaaaSespieare user selectable.) 409431305c8Saaron.Pp 4109237eaaaSespieThe 4119237eaaaSespie.Fa HEADNAME 4129237eaaaSespiefacility is often not used, leading to the following bizarre code: 4139237eaaaSespie.Bd -literal -offset indent 4149237eaaaSespieSLIST_HEAD(, TYPE) head, *headp; 4159237eaaaSespie.Ed 4169237eaaaSespie.Pp 4179237eaaaSespieThe 4189237eaaaSespie.Fn SLIST_ENTRY 419431305c8Saaronmacro declares a structure that connects the elements in the list. 4209237eaaaSespie.Pp 4219237eaaaSespieThe 4229237eaaaSespie.Fn SLIST_INIT 4239237eaaaSespiemacro initializes the list referenced by 4249237eaaaSespie.Fa head . 4259237eaaaSespie.Pp 4269237eaaaSespieThe list can also be initialized statically by using the 4279237eaaaSespie.Fn SLIST_HEAD_INITIALIZER 4289237eaaaSespiemacro like this: 4299237eaaaSespie.Bd -literal -offset indent 4309237eaaaSespieSLIST_HEAD(HEADNAME, TYPE) head = SLIST_HEAD_INITIALIZER(head); 4319237eaaaSespie.Ed 4329237eaaaSespie.Pp 4339237eaaaSespieThe 4349237eaaaSespie.Fn SLIST_INSERT_HEAD 4359237eaaaSespiemacro inserts the new element 4369237eaaaSespie.Fa elm 4379237eaaaSespieat the head of the list. 4389237eaaaSespie.Pp 4399237eaaaSespieThe 4409237eaaaSespie.Fn SLIST_INSERT_AFTER 4419237eaaaSespiemacro inserts the new element 4429237eaaaSespie.Fa elm 4439237eaaaSespieafter the element 4449237eaaaSespie.Fa listelm . 4459237eaaaSespie.Pp 4469237eaaaSespieThe 4479237eaaaSespie.Fn SLIST_REMOVE_HEAD 4489237eaaaSespiemacro removes the first element of the list pointed by 4499237eaaaSespie.Fa head . 4509237eaaaSespie.Pp 4519237eaaaSespieThe 45261f9916fSnaddy.Fn SLIST_REMOVE_AFTER 453d377bb64Smillertmacro removes the list element immediately following 454d377bb64Smillert.Fa elm . 455d377bb64Smillert.Pp 456d377bb64SmillertThe 45714bdd124Sjason.Fn SLIST_REMOVE 45814bdd124Sjasonmacro removes the element 45914bdd124Sjason.Fa elm 46014bdd124Sjasonof the list pointed by 46114bdd124Sjason.Fa head . 46214bdd124Sjason.Pp 46314bdd124SjasonThe 464cc405d09Sjmc.Fn SLIST_FIRST 4659237eaaaSespieand 4669237eaaaSespie.Fn SLIST_NEXT 4679237eaaaSespiemacros can be used to traverse the list: 4689237eaaaSespie.Bd -literal -offset indent 4695479c038Sguentherfor (np = SLIST_FIRST(&head); np != NULL; np = SLIST_NEXT(np, FIELDNAME)) 4709237eaaaSespie.Ed 4711f53fde1Saaron.Pp 4729237eaaaSespieOr, for simplicity, one can use the 4739237eaaaSespie.Fn SLIST_FOREACH 4749237eaaaSespiemacro: 4759237eaaaSespie.Bd -literal -offset indent 4765479c038SguentherSLIST_FOREACH(np, head, FIELDNAME) 4779237eaaaSespie.Ed 4789237eaaaSespie.Pp 479658b0e47SbluhmThe macro 480658b0e47Sbluhm.Fn SLIST_FOREACH_SAFE 481658b0e47Sbluhmtraverses the list referenced by head in a 482d2ad55b1Sjmcforward direction, assigning each element in turn to var. 483d2ad55b1SjmcHowever, unlike 484d2ad55b1Sjmc.Fn SLIST_FOREACH 485d2ad55b1Sjmcit is permitted to remove var as well 4862acff70eSpiroftias free it from within the loop safely without interfering with the traversal. 4872acff70eSpirofti.Pp 4889237eaaaSespieThe 4899237eaaaSespie.Fn SLIST_EMPTY 4909237eaaaSespiemacro should be used to check whether a simple list is empty. 491d8e11b2fSjmc.Sh SINGLY-LINKED LIST EXAMPLE 492d8e11b2fSjmc.Bd -literal 493d8e11b2fSjmcSLIST_HEAD(listhead, entry) head; 494d8e11b2fSjmcstruct entry { 495d8e11b2fSjmc ... 496d8e11b2fSjmc SLIST_ENTRY(entry) entries; /* Simple list. */ 497d8e11b2fSjmc ... 498d8e11b2fSjmc} *n1, *n2, *np; 499d8e11b2fSjmc 500d8e11b2fSjmcSLIST_INIT(&head); /* Initialize simple list. */ 501d8e11b2fSjmc 502d8e11b2fSjmcn1 = malloc(sizeof(struct entry)); /* Insert at the head. */ 503d8e11b2fSjmcSLIST_INSERT_HEAD(&head, n1, entries); 504d8e11b2fSjmc 505d8e11b2fSjmcn2 = malloc(sizeof(struct entry)); /* Insert after. */ 506d8e11b2fSjmcSLIST_INSERT_AFTER(n1, n2, entries); 507d8e11b2fSjmc 508d8e11b2fSjmcSLIST_FOREACH(np, &head, entries) /* Forward traversal. */ 509d8e11b2fSjmc np-> ... 510d8e11b2fSjmc 51175fe3d80Sbeckwhile (!SLIST_EMPTY(&head)) { /* Delete. */ 51275fe3d80Sbeck n1 = SLIST_FIRST(&head); 513d8e11b2fSjmc SLIST_REMOVE_HEAD(&head, entries); 51475fe3d80Sbeck free(n1); 51575fe3d80Sbeck} 51675fe3d80Sbeck 517d8e11b2fSjmc.Ed 518df930be7Sderaadt.Sh LISTS 519df930be7SderaadtA list is headed by a structure defined by the 520f33e0097Saaron.Fn LIST_HEAD 521df930be7Sderaadtmacro. 522431305c8SaaronThis structure contains a single pointer to the first element on the list. 523df930be7SderaadtThe elements are doubly linked so that an arbitrary element can be 524df930be7Sderaadtremoved without traversing the list. 525df930be7SderaadtNew elements can be added to the list after an existing element, 526df930be7Sderaadtbefore an existing element, or at the head of the list. 527df930be7SderaadtA 528df930be7Sderaadt.Fa LIST_HEAD 529df930be7Sderaadtstructure is declared as follows: 530df930be7Sderaadt.Bd -literal -offset indent 531df930be7SderaadtLIST_HEAD(HEADNAME, TYPE) head; 532df930be7Sderaadt.Ed 533431305c8Saaron.Pp 534df930be7Sderaadtwhere 535df930be7Sderaadt.Fa HEADNAME 5360868d64cSespieis the name of the structure to be defined, and struct 537df930be7Sderaadt.Fa TYPE 538df930be7Sderaadtis the type of the elements to be linked into the list. 539df930be7SderaadtA pointer to the head of the list can later be declared as: 540df930be7Sderaadt.Bd -literal -offset indent 541df930be7Sderaadtstruct HEADNAME *headp; 542df930be7Sderaadt.Ed 543431305c8Saaron.Pp 544df930be7Sderaadt(The names 545df930be7Sderaadt.Li head 546df930be7Sderaadtand 547df930be7Sderaadt.Li headp 548df930be7Sderaadtare user selectable.) 549431305c8Saaron.Pp 5500868d64cSespieThe 5510868d64cSespie.Fa HEADNAME 5520868d64cSespiefacility is often not used, leading to the following bizarre code: 5530868d64cSespie.Bd -literal -offset indent 5540868d64cSespieLIST_HEAD(, TYPE) head, *headp; 5550868d64cSespie.Ed 556df930be7Sderaadt.Pp 557f33e0097SaaronThe 558f33e0097Saaron.Fn LIST_ENTRY 559431305c8Saaronmacro declares a structure that connects the elements in the list. 560df930be7Sderaadt.Pp 561f33e0097SaaronThe 562f33e0097Saaron.Fn LIST_INIT 563f33e0097Saaronmacro initializes the list referenced by 564df930be7Sderaadt.Fa head . 565df930be7Sderaadt.Pp 5660868d64cSespieThe list can also be initialized statically by using the 5670868d64cSespie.Fn LIST_HEAD_INITIALIZER 5680868d64cSespiemacro like this: 5690868d64cSespie.Bd -literal -offset indent 5700868d64cSespieLIST_HEAD(HEADNAME, TYPE) head = LIST_HEAD_INITIALIZER(head); 5710868d64cSespie.Ed 5720868d64cSespie.Pp 573f33e0097SaaronThe 574f33e0097Saaron.Fn LIST_INSERT_HEAD 575f33e0097Saaronmacro inserts the new element 576df930be7Sderaadt.Fa elm 577df930be7Sderaadtat the head of the list. 578df930be7Sderaadt.Pp 579f33e0097SaaronThe 580f33e0097Saaron.Fn LIST_INSERT_AFTER 581f33e0097Saaronmacro inserts the new element 582df930be7Sderaadt.Fa elm 583df930be7Sderaadtafter the element 584df930be7Sderaadt.Fa listelm . 585df930be7Sderaadt.Pp 586f33e0097SaaronThe 587f33e0097Saaron.Fn LIST_INSERT_BEFORE 588f33e0097Saaronmacro inserts the new element 589df930be7Sderaadt.Fa elm 590df930be7Sderaadtbefore the element 591df930be7Sderaadt.Fa listelm . 592df930be7Sderaadt.Pp 593f33e0097SaaronThe 594f33e0097Saaron.Fn LIST_REMOVE 595f33e0097Saaronmacro removes the element 596df930be7Sderaadt.Fa elm 597df930be7Sderaadtfrom the list. 5980868d64cSespie.Pp 5990868d64cSespieThe 600df7c2479Sangelos.Fn LIST_REPLACE 601df7c2479Sangelosmacro replaces the list element 602df7c2479Sangelos.Fa elm 603df7c2479Sangeloswith the new element 604df7c2479Sangelos.Fa elm2 . 605df7c2479Sangelos.Pp 606df7c2479SangelosThe 607cc405d09Sjmc.Fn LIST_FIRST 6080868d64cSespieand 6090868d64cSespie.Fn LIST_NEXT 6100868d64cSespiemacros can be used to traverse the list: 6110868d64cSespie.Bd -literal -offset indent 6125479c038Sguentherfor (np = LIST_FIRST(&head); np != NULL; np = LIST_NEXT(np, FIELDNAME)) 6130868d64cSespie.Ed 6141f53fde1Saaron.Pp 6159237eaaaSespieOr, for simplicity, one can use the 6169237eaaaSespie.Fn LIST_FOREACH 6179237eaaaSespiemacro: 6189237eaaaSespie.Bd -literal -offset indent 6195479c038SguentherLIST_FOREACH(np, head, FIELDNAME) 6209237eaaaSespie.Ed 6219237eaaaSespie.Pp 622658b0e47SbluhmThe macro 623658b0e47Sbluhm.Fn LIST_FOREACH_SAFE 624658b0e47Sbluhmtraverses the list referenced by head in a 625d2ad55b1Sjmcforward direction, assigning each element in turn to var. 626d2ad55b1SjmcHowever, unlike 627d2ad55b1Sjmc.Fn LIST_FOREACH 628d2ad55b1Sjmcit is permitted to remove var as well 6292acff70eSpiroftias free it from within the loop safely without interfering with the traversal. 6302acff70eSpirofti.Pp 6319237eaaaSespieThe 6329237eaaaSespie.Fn LIST_EMPTY 6339237eaaaSespiemacro should be used to check whether a list is empty. 634df930be7Sderaadt.Sh LIST EXAMPLE 635df930be7Sderaadt.Bd -literal 636df930be7SderaadtLIST_HEAD(listhead, entry) head; 637df930be7Sderaadtstruct entry { 638df930be7Sderaadt ... 639df930be7Sderaadt LIST_ENTRY(entry) entries; /* List. */ 640df930be7Sderaadt ... 641df930be7Sderaadt} *n1, *n2, *np; 642df930be7Sderaadt 6430b0b405fSaaronLIST_INIT(&head); /* Initialize list. */ 644df930be7Sderaadt 645df930be7Sderaadtn1 = malloc(sizeof(struct entry)); /* Insert at the head. */ 646df930be7SderaadtLIST_INSERT_HEAD(&head, n1, entries); 647df930be7Sderaadt 648df930be7Sderaadtn2 = malloc(sizeof(struct entry)); /* Insert after. */ 649df930be7SderaadtLIST_INSERT_AFTER(n1, n2, entries); 650df930be7Sderaadt 651df930be7Sderaadtn2 = malloc(sizeof(struct entry)); /* Insert before. */ 652df930be7SderaadtLIST_INSERT_BEFORE(n1, n2, entries); 653df930be7Sderaadt /* Forward traversal. */ 6541d29e077SottoLIST_FOREACH(np, &head, entries) 655df930be7Sderaadt np-> ... 656df930be7Sderaadt 657c0c67761Stobiaswhile (!LIST_EMPTY(&head)) { /* Delete. */ 65875fe3d80Sbeck n1 = LIST_FIRST(&head); 65975fe3d80Sbeck LIST_REMOVE(n1, entries); 66075fe3d80Sbeck free(n1); 66175fe3d80Sbeck} 662df930be7Sderaadt.Ed 6630868d64cSespie.Sh SIMPLE QUEUES 6640868d64cSespieA simple queue is headed by a structure defined by the 6659237eaaaSespie.Fn SIMPLEQ_HEAD 6660868d64cSespiemacro. 667431305c8SaaronThis structure contains a pair of pointers, one to the first element in the 668431305c8Saaronsimple queue and the other to the last element in the simple queue. 6699237eaaaSespieThe elements are singly linked. 6700868d64cSespieNew elements can be added to the queue after an existing element, 6710868d64cSespieat the head of the queue or at the tail of the queue. 6720868d64cSespieA 6730868d64cSespie.Fa SIMPLEQ_HEAD 6740868d64cSespiestructure is declared as follows: 6750868d64cSespie.Bd -literal -offset indent 6760868d64cSespieSIMPLEQ_HEAD(HEADNAME, TYPE) head; 6770868d64cSespie.Ed 678431305c8Saaron.Pp 6790868d64cSespiewhere 6800868d64cSespie.Fa HEADNAME 6810868d64cSespieis the name of the structure to be defined, and struct 6820868d64cSespie.Fa TYPE 6830868d64cSespieis the type of the elements to be linked into the queue. 6840868d64cSespieA pointer to the head of the queue can later be declared as: 6850868d64cSespie.Bd -literal -offset indent 6860868d64cSespiestruct HEADNAME *headp; 6870868d64cSespie.Ed 688431305c8Saaron.Pp 6890868d64cSespie(The names 6900868d64cSespie.Li head 6910868d64cSespieand 6920868d64cSespie.Li headp 6930868d64cSespieare user selectable.) 6940868d64cSespie.Pp 6950868d64cSespieThe 6960868d64cSespie.Fn SIMPLEQ_ENTRY 6970868d64cSespiemacro declares a structure that connects the elements in 6980868d64cSespiethe queue. 6990868d64cSespie.Pp 7000868d64cSespieThe 7010868d64cSespie.Fn SIMPLEQ_INIT 7020868d64cSespiemacro initializes the queue referenced by 7030868d64cSespie.Fa head . 7040868d64cSespie.Pp 7050868d64cSespieThe queue can also be initialized statically by using the 7060868d64cSespie.Fn SIMPLEQ_HEAD_INITIALIZER 7070868d64cSespiemacro like this: 7080868d64cSespie.Bd -literal -offset indent 7090868d64cSespieSIMPLEQ_HEAD(HEADNAME, TYPE) head = SIMPLEQ_HEAD_INITIALIZER(head); 7100868d64cSespie.Ed 7110868d64cSespie.Pp 7120868d64cSespieThe 71361f9916fSnaddy.Fn SIMPLEQ_INSERT_AFTER 71461f9916fSnaddymacro inserts the new element 71561f9916fSnaddy.Fa elm 71661f9916fSnaddyafter the element 71761f9916fSnaddy.Fa listelm . 71861f9916fSnaddy.Pp 71961f9916fSnaddyThe 7200868d64cSespie.Fn SIMPLEQ_INSERT_HEAD 7210868d64cSespiemacro inserts the new element 7220868d64cSespie.Fa elm 7230868d64cSespieat the head of the queue. 7240868d64cSespie.Pp 7250868d64cSespieThe 7260868d64cSespie.Fn SIMPLEQ_INSERT_TAIL 7270868d64cSespiemacro inserts the new element 7280868d64cSespie.Fa elm 7290868d64cSespieat the end of the queue. 7300868d64cSespie.Pp 7310868d64cSespieThe 73261f9916fSnaddy.Fn SIMPLEQ_REMOVE_AFTER 73361f9916fSnaddymacro removes the queue element immediately following 73461f9916fSnaddy.Fa elm . 7350868d64cSespie.Pp 7360868d64cSespieThe 7370868d64cSespie.Fn SIMPLEQ_REMOVE_HEAD 7380868d64cSespiemacro removes the first element 7390868d64cSespiefrom the queue. 7400868d64cSespie.Pp 7410868d64cSespieThe 74244ab62a3Smillert.Fn SIMPLEQ_CONCAT 74344ab62a3Smillertmacro concatenates all the elements of the queue referenced by 74444ab62a3Smillert.Fa head2 74544ab62a3Smillertto the end of the queue referenced by 74644ab62a3Smillert.Fa head1 , 74744ab62a3Smillertemptying 74844ab62a3Smillert.Fa head2 74944ab62a3Smillertin the process. 75044ab62a3SmillertThis is more efficient than removing and inserting the individual elements 75144ab62a3Smillertas it does not actually traverse 75244ab62a3Smillert.Fa head2 . 75344ab62a3Smillert.Pp 75444ab62a3SmillertThe 755cc405d09Sjmc.Fn SIMPLEQ_FIRST 7560868d64cSespieand 7570868d64cSespie.Fn SIMPLEQ_NEXT 7580868d64cSespiemacros can be used to traverse the queue. 7599237eaaaSespieThe 7609237eaaaSespie.Fn SIMPLEQ_FOREACH 761*4bc2832dSnaddymacro is used for queue traversal: 7629237eaaaSespie.Bd -literal -offset indent 7635479c038SguentherSIMPLEQ_FOREACH(np, head, FIELDNAME) 7649237eaaaSespie.Ed 7659237eaaaSespie.Pp 766658b0e47SbluhmThe macro 767658b0e47Sbluhm.Fn SIMPLEQ_FOREACH_SAFE 768658b0e47Sbluhmtraverses the queue referenced by head in a 769d2ad55b1Sjmcforward direction, assigning each element in turn to var. 770d2ad55b1SjmcHowever, unlike 771d2ad55b1Sjmc.Fn SIMPLEQ_FOREACH 772d2ad55b1Sjmcit is permitted to remove var as well 7732acff70eSpiroftias free it from within the loop safely without interfering with the traversal. 7742acff70eSpirofti.Pp 7759237eaaaSespieThe 7769237eaaaSespie.Fn SIMPLEQ_EMPTY 7779237eaaaSespiemacro should be used to check whether a list is empty. 7780868d64cSespie.Sh SIMPLE QUEUE EXAMPLE 7790868d64cSespie.Bd -literal 7800868d64cSespieSIMPLEQ_HEAD(listhead, entry) head = SIMPLEQ_HEAD_INITIALIZER(head); 7810868d64cSespiestruct entry { 7820868d64cSespie ... 78335ebeca3Sjmc SIMPLEQ_ENTRY(entry) entries; /* Simple queue. */ 7840868d64cSespie ... 7850868d64cSespie} *n1, *n2, *np; 7860868d64cSespie 7870868d64cSespien1 = malloc(sizeof(struct entry)); /* Insert at the head. */ 7880868d64cSespieSIMPLEQ_INSERT_HEAD(&head, n1, entries); 7890868d64cSespie 7900868d64cSespien2 = malloc(sizeof(struct entry)); /* Insert after. */ 791ef699885SjfbSIMPLEQ_INSERT_AFTER(&head, n1, n2, entries); 7920868d64cSespie 7930868d64cSespien2 = malloc(sizeof(struct entry)); /* Insert at the tail. */ 7943c2c9ac9SjmcSIMPLEQ_INSERT_TAIL(&head, n2, entries); 7950868d64cSespie /* Forward traversal. */ 7961d29e077SottoSIMPLEQ_FOREACH(np, &head, entries) 7970868d64cSespie np-> ... 7980868d64cSespie /* Delete. */ 79975fe3d80Sbeckwhile (!SIMPLEQ_EMPTY(&head)) { 80075fe3d80Sbeck n1 = SIMPLEQ_FIRST(&head); 801ef699885Sjfb SIMPLEQ_REMOVE_HEAD(&head, entries); 80275fe3d80Sbeck free(n1); 80375fe3d80Sbeck} 8040868d64cSespie.Ed 8059322932cSmillert.Sh SINGLY-LINKED TAIL QUEUES 8069322932cSmillertA singly-linked tail queue is headed by a structure defined by the 8079322932cSmillert.Fn STAILQ_HEAD 8089322932cSmillertmacro. 8099322932cSmillertThis structure contains a pair of pointers, one to the first element in 8109322932cSmillertthe tail queue and the other to the last element in the tail queue. 8119322932cSmillertThe elements are singly linked for minimum space and pointer manipulation 8129322932cSmillertoverhead at the expense of O(n) removal for arbitrary elements. 8139322932cSmillertNew elements can be added to the tail queue after an existing element, 8149322932cSmillertat the head of the tail queue or at the end of the tail queue. 8159322932cSmillertA 8169322932cSmillert.Fa STAILQ_HEAD 8179322932cSmillertstructure is declared as follows: 8189322932cSmillert.Bd -literal -offset indent 8199322932cSmillertSTAILQ_HEAD(HEADNAME, TYPE) head; 8209322932cSmillert.Ed 8219322932cSmillert.Pp 8229322932cSmillertwhere 8239322932cSmillert.Fa HEADNAME 8249322932cSmillertis the name of the structure to be defined, and struct 8259322932cSmillert.Fa TYPE 8269322932cSmillertis the type of the elements to be linked into the tail queue. 8279322932cSmillertA pointer to the head of the tail queue can later be declared as: 8289322932cSmillert.Bd -literal -offset indent 8299322932cSmillertstruct HEADNAME *headp; 8309322932cSmillert.Ed 8319322932cSmillert.Pp 8329322932cSmillert(The names 8339322932cSmillert.Li head 8349322932cSmillertand 8359322932cSmillert.Li headp 8369322932cSmillertare user selectable.) 8379322932cSmillert.Pp 8389322932cSmillertThe 8399322932cSmillert.Fn STAILQ_ENTRY 8409322932cSmillertmacro declares a structure that connects the elements in 8419322932cSmillertthe tail queue. 8429322932cSmillert.Pp 8439322932cSmillertThe 8449322932cSmillert.Fn STAILQ_INIT 8459322932cSmillertmacro initializes the tail queue referenced by 8469322932cSmillert.Fa head . 8479322932cSmillert.Pp 8489322932cSmillertThe tail queue can also be initialized statically by using the 8499322932cSmillert.Fn STAILQ_HEAD_INITIALIZER 8509322932cSmillertmacro like this: 8519322932cSmillert.Bd -literal -offset indent 8529322932cSmillertSTAILQ_HEAD(HEADNAME, TYPE) head = STAILQ_HEAD_INITIALIZER(head); 8539322932cSmillert.Ed 8549322932cSmillert.Pp 8559322932cSmillertThe 8569322932cSmillert.Fn STAILQ_INSERT_AFTER 8579322932cSmillertmacro inserts the new element 8589322932cSmillert.Fa elm 8599322932cSmillertafter the element 8609322932cSmillert.Fa listelm . 8619322932cSmillert.Pp 8629322932cSmillertThe 8639322932cSmillert.Fn STAILQ_INSERT_HEAD 8649322932cSmillertmacro inserts the new element 8659322932cSmillert.Fa elm 8669322932cSmillertat the head of the tail queue. 8679322932cSmillert.Pp 8689322932cSmillertThe 8699322932cSmillert.Fn STAILQ_INSERT_TAIL 8709322932cSmillertmacro inserts the new element 8719322932cSmillert.Fa elm 8729322932cSmillertat the end of the tail queue. 8739322932cSmillert.Pp 8749322932cSmillertThe 8759322932cSmillert.Fn STAILQ_REMOVE_AFTER 8769322932cSmillertmacro removes the queue element immediately following 8779322932cSmillert.Fa elm . 8789322932cSmillertUnlike 8799322932cSmillert.Fa STAILQ_REMOVE , 8809322932cSmillertthis macro does not traverse the entire tail queue. 8819322932cSmillert.Pp 8829322932cSmillertThe 8839322932cSmillert.Fn STAILQ_REMOVE_HEAD 8849322932cSmillertmacro removes the first element 8859322932cSmillertfrom the tail queue. 8869322932cSmillertFor optimum efficiency, 8879322932cSmillertelements being removed from the head of the tail queue should 8889322932cSmillertuse this macro explicitly rather than the generic 8899322932cSmillert.Fa STAILQ_REMOVE 8909322932cSmillertmacro. 8919322932cSmillert.Pp 8929322932cSmillertThe 8939322932cSmillert.Fn STAILQ_REMOVE 8949322932cSmillertmacro removes the element 8959322932cSmillert.Fa elm 8969322932cSmillertfrom the tail queue. 8979322932cSmillertUse of this macro should be avoided as it traverses the entire list. 8989322932cSmillertA doubly-linked tail queue should be used if this macro is needed in 8999322932cSmillerthigh-usage code paths or to operate on long tail queues. 9009322932cSmillert.Pp 9019322932cSmillertThe 9029322932cSmillert.Fn STAILQ_CONCAT 9039322932cSmillertmacro concatenates all the elements of the tail queue referenced by 9049322932cSmillert.Fa head2 9059322932cSmillertto the end of the tail queue referenced by 9069322932cSmillert.Fa head1 , 9079322932cSmillertemptying 9089322932cSmillert.Fa head2 9099322932cSmillertin the process. 9109322932cSmillertThis is more efficient than removing and inserting the individual elements 9119322932cSmillertas it does not actually traverse 9129322932cSmillert.Fa head2 . 9139322932cSmillert.Pp 9149322932cSmillertThe 9159322932cSmillert.Fn STAILQ_FOREACH 916*4bc2832dSnaddymacro is used for queue traversal: 9179322932cSmillert.Bd -literal -offset indent 9189322932cSmillertSTAILQ_FOREACH(np, head, FIELDNAME) 9199322932cSmillert.Ed 9209322932cSmillert.Pp 9219322932cSmillertThe macro 9229322932cSmillert.Fn STAILQ_FOREACH_SAFE 9239322932cSmillerttraverses the queue referenced by head in a 9249322932cSmillertforward direction, assigning each element in turn to var. 9259322932cSmillertHowever, unlike 9269322932cSmillert.Fn STAILQ_FOREACH 9279322932cSmillertit is permitted to remove var as well 9289322932cSmillertas free it from within the loop safely without interfering with the traversal. 9299322932cSmillert.Pp 9309322932cSmillertThe 9313fd951e6Snaddy.Fn STAILQ_FIRST , 9329322932cSmillert.Fn STAILQ_NEXT , 9339322932cSmillertand 9349322932cSmillert.Fn STAILQ_LAST 9359322932cSmillertmacros can be used to manually traverse a tail queue or an arbitrary part of 9369322932cSmillertone. 9379322932cSmillertThe 9389322932cSmillert.Fn STAILQ_EMPTY 9399322932cSmillertmacro should be used to check whether a tail queue is empty. 9409322932cSmillert.Sh SINGLY-LINKED TAIL QUEUE EXAMPLE 9419322932cSmillert.Bd -literal 9429322932cSmillertSTAILQ_HEAD(listhead, entry) head = STAILQ_HEAD_INITIALIZER(head); 9439322932cSmillertstruct entry { 9449322932cSmillert ... 9459322932cSmillert STAILQ_ENTRY(entry) entries; /* Singly-linked tail queue. */ 9469322932cSmillert ... 9479322932cSmillert} *n1, *n2, *np; 9489322932cSmillert 9499322932cSmillertn1 = malloc(sizeof(struct entry)); /* Insert at the head. */ 9509322932cSmillertSTAILQ_INSERT_HEAD(&head, n1, entries); 9519322932cSmillert 9529322932cSmillertn2 = malloc(sizeof(struct entry)); /* Insert at the tail. */ 9539322932cSmillertSTAILQ_INSERT_TAIL(&head, n2, entries); 9549322932cSmillert 9559322932cSmillertn2 = malloc(sizeof(struct entry)); /* Insert after. */ 9569322932cSmillertSTAILQ_INSERT_AFTER(&head, n1, n2, entries); 9579322932cSmillert 9589322932cSmillert /* Deletion. */ 9599322932cSmillertSTAILQ_REMOVE(&head, n2, entry, entries); 9609322932cSmillertfree(n2); 9619322932cSmillert /* Deletion from the head. */ 9629322932cSmillertn3 = STAILQ_FIRST(&head); 9639322932cSmillertSTAILQ_REMOVE_HEAD(&head, entries); 9649322932cSmillertfree(n3); 9659322932cSmillert /* Forward traversal. */ 9669322932cSmillertSTAILQ_FOREACH(np, &head, entries) 9679322932cSmillert np-> ... 9689322932cSmillert /* Safe forward traversal. */ 9699322932cSmillertSTAILQ_FOREACH_SAFE(np, &head, entries, np_temp) { 9709322932cSmillert np-> ... 9719322932cSmillert STAILQ_REMOVE(&head, np, entry, entries); 9729322932cSmillert free(np); 9739322932cSmillert} 9749322932cSmillert /* Delete. */ 9759322932cSmillertwhile (!STAILQ_EMPTY(&head)) { 9769322932cSmillert n1 = STAILQ_FIRST(&head); 9779322932cSmillert STAILQ_REMOVE_HEAD(&head, entries); 9789322932cSmillert free(n1); 9799322932cSmillert} 9809322932cSmillert.Ed 981df930be7Sderaadt.Sh TAIL QUEUES 982df930be7SderaadtA tail queue is headed by a structure defined by the 983f33e0097Saaron.Fn TAILQ_HEAD 984df930be7Sderaadtmacro. 985df930be7SderaadtThis structure contains a pair of pointers, 986df930be7Sderaadtone to the first element in the tail queue and the other to 987df930be7Sderaadtthe last element in the tail queue. 988df930be7SderaadtThe elements are doubly linked so that an arbitrary element can be 989df930be7Sderaadtremoved without traversing the tail queue. 990df930be7SderaadtNew elements can be added to the queue after an existing element, 991df930be7Sderaadtbefore an existing element, at the head of the queue, or at the end 992b9d2958cSaaronof the queue. 993df930be7SderaadtA 994df930be7Sderaadt.Fa TAILQ_HEAD 995df930be7Sderaadtstructure is declared as follows: 996df930be7Sderaadt.Bd -literal -offset indent 997df930be7SderaadtTAILQ_HEAD(HEADNAME, TYPE) head; 998df930be7Sderaadt.Ed 999431305c8Saaron.Pp 1000df930be7Sderaadtwhere 1001f33e0097Saaron.Fa HEADNAME 10020868d64cSespieis the name of the structure to be defined, and struct 1003f33e0097Saaron.Fa TYPE 1004df930be7Sderaadtis the type of the elements to be linked into the tail queue. 1005df930be7SderaadtA pointer to the head of the tail queue can later be declared as: 1006df930be7Sderaadt.Bd -literal -offset indent 1007df930be7Sderaadtstruct HEADNAME *headp; 1008df930be7Sderaadt.Ed 1009431305c8Saaron.Pp 1010df930be7Sderaadt(The names 1011df930be7Sderaadt.Li head 1012df930be7Sderaadtand 1013df930be7Sderaadt.Li headp 1014df930be7Sderaadtare user selectable.) 1015df930be7Sderaadt.Pp 1016f33e0097SaaronThe 1017f33e0097Saaron.Fn TAILQ_ENTRY 1018f33e0097Saaronmacro declares a structure that connects the elements in 1019df930be7Sderaadtthe tail queue. 1020df930be7Sderaadt.Pp 1021f33e0097SaaronThe 1022f33e0097Saaron.Fn TAILQ_INIT 1023f33e0097Saaronmacro initializes the tail queue referenced by 1024df930be7Sderaadt.Fa head . 1025df930be7Sderaadt.Pp 10260868d64cSespieThe tail queue can also be initialized statically by using the 10270868d64cSespie.Fn TAILQ_HEAD_INITIALIZER 10280868d64cSespiemacro. 10290868d64cSespie.Pp 1030f33e0097SaaronThe 1031f33e0097Saaron.Fn TAILQ_INSERT_HEAD 1032f33e0097Saaronmacro inserts the new element 1033df930be7Sderaadt.Fa elm 1034df930be7Sderaadtat the head of the tail queue. 1035df930be7Sderaadt.Pp 1036f33e0097SaaronThe 1037f33e0097Saaron.Fn TAILQ_INSERT_TAIL 1038f33e0097Saaronmacro inserts the new element 1039df930be7Sderaadt.Fa elm 1040df930be7Sderaadtat the end of the tail queue. 1041df930be7Sderaadt.Pp 1042f33e0097SaaronThe 1043f33e0097Saaron.Fn TAILQ_INSERT_AFTER 1044f33e0097Saaronmacro inserts the new element 1045df930be7Sderaadt.Fa elm 1046df930be7Sderaadtafter the element 1047df930be7Sderaadt.Fa listelm . 1048df930be7Sderaadt.Pp 1049f33e0097SaaronThe 1050f33e0097Saaron.Fn TAILQ_INSERT_BEFORE 1051f33e0097Saaronmacro inserts the new element 1052df930be7Sderaadt.Fa elm 1053df930be7Sderaadtbefore the element 1054df930be7Sderaadt.Fa listelm . 1055df930be7Sderaadt.Pp 1056f33e0097SaaronThe 1057f33e0097Saaron.Fn TAILQ_REMOVE 1058f33e0097Saaronmacro removes the element 1059df930be7Sderaadt.Fa elm 1060df930be7Sderaadtfrom the tail queue. 10610868d64cSespie.Pp 106228601b65SjmcThe 106328601b65Sjmc.Fn TAILQ_REPLACE 106428601b65Sjmcmacro replaces the list element 106528601b65Sjmc.Fa elm 106628601b65Sjmcwith the new element 106728601b65Sjmc.Fa elm2 . 106828601b65Sjmc.Pp 106944ab62a3SmillertThe 107044ab62a3Smillert.Fn TAILQ_CONCAT 107144ab62a3Smillertmacro concatenates all the elements of the tail queue referenced by 107244ab62a3Smillert.Fa head2 107344ab62a3Smillertto the end of the tail queue referenced by 107444ab62a3Smillert.Fa head1 , 107544ab62a3Smillertemptying 107644ab62a3Smillert.Fa head2 107744ab62a3Smillertin the process. 107844ab62a3SmillertThis is more efficient than removing and inserting the individual elements 107944ab62a3Smillertas it does not actually traverse 108044ab62a3Smillert.Fa head2 . 108144ab62a3Smillert.Pp 1082c79a4dd8Skrw.Fn TAILQ_FOREACH 1083c79a4dd8Skrwand 1084c79a4dd8Skrw.Fn TAILQ_FOREACH_REVERSE 1085c79a4dd8Skrware used for traversing a tail queue. 1086c79a4dd8Skrw.Fn TAILQ_FOREACH 1087c79a4dd8Skrwstarts at the first element and proceeds towards the last. 1088c79a4dd8Skrw.Fn TAILQ_FOREACH_REVERSE 1089c79a4dd8Skrwstarts at the last element and proceeds towards the first. 1090c79a4dd8Skrw.Bd -literal -offset indent 10915479c038SguentherTAILQ_FOREACH(np, &head, FIELDNAME) 10925479c038SguentherTAILQ_FOREACH_REVERSE(np, &head, HEADNAME, FIELDNAME) 1093c79a4dd8Skrw.Ed 1094c79a4dd8Skrw.Pp 1095d2ad55b1SjmcThe macros 1096d2ad55b1Sjmc.Fn TAILQ_FOREACH_SAFE 1097d2ad55b1Sjmcand 1098d2ad55b1Sjmc.Fn TAILQ_FOREACH_REVERSE_SAFE 1099d2ad55b1Sjmctraverse the list referenced by head 1100d2ad55b1Sjmcin a forward or reverse direction respectively, 1101d2ad55b1Sjmcassigning each element in turn to var. 1102d2ad55b1SjmcHowever, unlike their unsafe counterparts, 1103d2ad55b1Sjmcthey permit both the removal of var 1104d2ad55b1Sjmcas well as freeing it from within the loop safely 1105d2ad55b1Sjmcwithout interfering with the traversal. 11062acff70eSpirofti.Pp 11070868d64cSespieThe 11088a784db4Smillert.Fn TAILQ_FIRST , 11090868d64cSespie.Fn TAILQ_NEXT , 11100868d64cSespie.Fn TAILQ_LAST 11110868d64cSespieand 11120868d64cSespie.Fn TAILQ_PREV 1113c79a4dd8Skrwmacros can be used to manually traverse a tail queue or an arbitrary part of 1114c79a4dd8Skrwone. 1115c9cbb67dSderaadt.Pp 1116c9cbb67dSderaadtThe 11179237eaaaSespie.Fn TAILQ_EMPTY 11189237eaaaSespiemacro should be used to check whether a tail queue is empty. 1119df930be7Sderaadt.Sh TAIL QUEUE EXAMPLE 1120df930be7Sderaadt.Bd -literal 1121df930be7SderaadtTAILQ_HEAD(tailhead, entry) head; 1122df930be7Sderaadtstruct entry { 1123df930be7Sderaadt ... 1124df930be7Sderaadt TAILQ_ENTRY(entry) entries; /* Tail queue. */ 1125df930be7Sderaadt ... 1126df930be7Sderaadt} *n1, *n2, *np; 1127df930be7Sderaadt 11280b0b405fSaaronTAILQ_INIT(&head); /* Initialize queue. */ 1129df930be7Sderaadt 1130df930be7Sderaadtn1 = malloc(sizeof(struct entry)); /* Insert at the head. */ 1131df930be7SderaadtTAILQ_INSERT_HEAD(&head, n1, entries); 1132df930be7Sderaadt 1133df930be7Sderaadtn1 = malloc(sizeof(struct entry)); /* Insert at the tail. */ 1134df930be7SderaadtTAILQ_INSERT_TAIL(&head, n1, entries); 1135df930be7Sderaadt 1136df930be7Sderaadtn2 = malloc(sizeof(struct entry)); /* Insert after. */ 1137df930be7SderaadtTAILQ_INSERT_AFTER(&head, n1, n2, entries); 1138df930be7Sderaadt 1139df930be7Sderaadtn2 = malloc(sizeof(struct entry)); /* Insert before. */ 1140df930be7SderaadtTAILQ_INSERT_BEFORE(n1, n2, entries); 1141df930be7Sderaadt /* Forward traversal. */ 1142c79a4dd8SkrwTAILQ_FOREACH(np, &head, entries) 1143c79a4dd8Skrw np-> ... 1144c6072168Sjmc /* Manual forward traversal. */ 1145c79a4dd8Skrwfor (np = n2; np != NULL; np = TAILQ_NEXT(np, entries)) 1146df930be7Sderaadt np-> ... 1147df930be7Sderaadt /* Delete. */ 1148b1475358Shaesbaertwhile ((np = TAILQ_FIRST(&head))) { 11499ed04d0aSprovos TAILQ_REMOVE(&head, np, entries); 115075fe3d80Sbeck free(np); 115175fe3d80Sbeck} 115275fe3d80Sbeck 1153df930be7Sderaadt.Ed 1154b9af1e79Sjmc.Sh SEE ALSO 1155b9af1e79Sjmc.Xr tree 3 11560868d64cSespie.Sh NOTES 11571d29e077SottoIt is an error to assume the next and previous fields are preserved 11581d29e077Sottoafter an element has been removed from a list or queue. 11591d29e077SottoUsing any macro (except the various forms of insertion) on an element 11601d29e077Sottoremoved from a list or queue is incorrect. 11611d29e077SottoAn example of erroneous usage is removing the same element twice. 11621d29e077Sotto.Pp 11630868d64cSespieThe 11649237eaaaSespie.Fn SLIST_END , 11650868d64cSespie.Fn LIST_END , 11669322932cSmillert.Fn SIMPLEQ_END , 11679322932cSmillert.Fn STAILQ_END 11680868d64cSespieand 11690868d64cSespie.Fn TAILQ_END 1170b9b58a6dSguenthermacros are deprecated; they provided symmetry with the historical 1171b9b58a6dSguenther.Fn CIRCLEQ_END 1172b9b58a6dSguentherand just expand to 1173b9b58a6dSguenther.Dv NULL . 11749237eaaaSespie.Pp 11759237eaaaSespieTrying to free a list in the following way is a common error: 11769237eaaaSespie.Bd -literal -offset indent 11779237eaaaSespieLIST_FOREACH(var, head, entry) 11789237eaaaSespie free(var); 11799237eaaaSespiefree(head); 11809237eaaaSespie.Ed 11815d436663Sderaadt.Pp 11829237eaaaSespieSince 11839237eaaaSespie.Va var 1184658b0e47Sbluhmis free'd, the FOREACH macros refer to a pointer that may have been 1185658b0e47Sbluhmreallocated already. 11861d29e077SottoA similar situation occurs when the current element is deleted 11871d29e077Sottofrom the list. 11882acff70eSpiroftiIn cases like these the data structure's FOREACH_SAFE macros should be used 11892acff70eSpiroftiinstead. 1190df930be7Sderaadt.Sh HISTORY 1191df930be7SderaadtThe 1192df930be7Sderaadt.Nm queue 1193a873166dSmickeyfunctions first appeared in 1194a873166dSmickey.Bx 4.4 . 1195b9b58a6dSguentherThe historical circle queue macros were deprecated in 1196b9b58a6dSguenther.Ox 5.5 . 1197