1*7ba76359Skamil.\" $NetBSD: queue.3,v 1.61 2020/10/20 23:27:57 kamil Exp $ 2a05c7063Smycroft.\" 306de4264Slukem.\" Copyright (c) 2000, 2002 The NetBSD Foundation, Inc. 4a05c7063Smycroft.\" All rights reserved. 5a05c7063Smycroft.\" 6a05c7063Smycroft.\" Redistribution and use in source and binary forms, with or without 7a05c7063Smycroft.\" modification, are permitted provided that the following conditions 8a05c7063Smycroft.\" are met: 9a05c7063Smycroft.\" 1. Redistributions of source code must retain the above copyright 10a05c7063Smycroft.\" notice, this list of conditions and the following disclaimer. 11a05c7063Smycroft.\" 2. Redistributions in binary form must reproduce the above copyright 12a05c7063Smycroft.\" notice, this list of conditions and the following disclaimer in the 13a05c7063Smycroft.\" documentation and/or other materials provided with the distribution. 14a05c7063Smycroft.\" 15a05c7063Smycroft.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16a05c7063Smycroft.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17a05c7063Smycroft.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18a05c7063Smycroft.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19a05c7063Smycroft.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20a05c7063Smycroft.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21a05c7063Smycroft.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22a05c7063Smycroft.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23a05c7063Smycroft.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24a05c7063Smycroft.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25a05c7063Smycroft.\" POSSIBILITY OF SUCH DAMAGE. 26ee52468aSjtc.\" 27ee52468aSjtc.\" Copyright (c) 1993 The Regents of the University of California. 28ee52468aSjtc.\" All rights reserved. 29630651b7Scgd.\" 30630651b7Scgd.\" Redistribution and use in source and binary forms, with or without 31630651b7Scgd.\" modification, are permitted provided that the following conditions 32630651b7Scgd.\" are met: 33630651b7Scgd.\" 1. Redistributions of source code must retain the above copyright 34630651b7Scgd.\" notice, this list of conditions and the following disclaimer. 35630651b7Scgd.\" 2. Redistributions in binary form must reproduce the above copyright 36630651b7Scgd.\" notice, this list of conditions and the following disclaimer in the 37630651b7Scgd.\" documentation and/or other materials provided with the distribution. 38075022b3Sagc.\" 3. Neither the name of the University nor the names of its contributors 39630651b7Scgd.\" may be used to endorse or promote products derived from this software 40630651b7Scgd.\" without specific prior written permission. 41630651b7Scgd.\" 42630651b7Scgd.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 43630651b7Scgd.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 44630651b7Scgd.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 45630651b7Scgd.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 46630651b7Scgd.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 47630651b7Scgd.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 48630651b7Scgd.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 49630651b7Scgd.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 50630651b7Scgd.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 51630651b7Scgd.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 52630651b7Scgd.\" SUCH DAMAGE. 53630651b7Scgd.\" 54ee52468aSjtc.\" @(#)queue.3 8.1 (Berkeley) 12/13/93 55630651b7Scgd.\" 5637871fa6Spgoyette.Dd October 1, 2017 57630651b7Scgd.Dt QUEUE 3 585b40cb57Sgarbled.Os 59630651b7Scgd.Sh NAME 604c51b74bSdeberg.Nm SLIST_HEAD , 614c51b74bSdeberg.Nm SLIST_HEAD_INITIALIZER , 622f6ed1a8Slukem.Nm SLIST_ENTRY , 6382164e46Schristos.Nm SLIST_FIRST , 6482164e46Schristos.Nm SLIST_EMPTY , 6582164e46Schristos.Nm SLIST_NEXT , 664c51b74bSdeberg.Nm SLIST_FOREACH , 670d53a16dSmschuett.Nm SLIST_FOREACH_SAFE , 6882164e46Schristos.Nm SLIST_INIT , 6982164e46Schristos.Nm SLIST_INSERT_AFTER , 700246bab0Swiz.Nm SLIST_INSERT_HEAD , 7182164e46Schristos.Nm SLIST_REMOVE_AFTER , 7282164e46Schristos.Nm SLIST_REMOVE_HEAD , 7382164e46Schristos.Nm SLIST_REMOVE , 7406de4264Slukem.Nm LIST_HEAD , 7506de4264Slukem.Nm LIST_HEAD_INITIALIZER , 762f6ed1a8Slukem.Nm LIST_ENTRY , 7782164e46Schristos.Nm LIST_FIRST , 7882164e46Schristos.Nm LIST_EMPTY , 7982164e46Schristos.Nm LIST_NEXT , 8082164e46Schristos.Nm LIST_FOREACH , 8182164e46Schristos.Nm LIST_FOREACH_SAFE , 8206de4264Slukem.Nm LIST_INIT , 8306de4264Slukem.Nm LIST_INSERT_AFTER , 8406de4264Slukem.Nm LIST_INSERT_BEFORE , 8506de4264Slukem.Nm LIST_INSERT_HEAD , 8606de4264Slukem.Nm LIST_REMOVE , 8782164e46Schristos.Nm LIST_REPLACE , 88169afaf5Srmind.Nm LIST_MOVE , 8982164e46Schristos.Nm SIMPLEQ_HEAD , 9082164e46Schristos.Nm SIMPLEQ_HEAD_INITIALIZER , 9182164e46Schristos.Nm SIMPLEQ_ENTRY , 9282164e46Schristos.Nm SIMPLEQ_FIRST , 9382164e46Schristos.Nm SIMPLEQ_EMPTY , 9482164e46Schristos.Nm SIMPLEQ_NEXT , 9582164e46Schristos.Nm SIMPLEQ_LAST , 9682164e46Schristos.Nm SIMPLEQ_FOREACH , 9782164e46Schristos.Nm SIMPLEQ_FOREACH_SAFE , 9882164e46Schristos.Nm SIMPLEQ_INIT , 990246bab0Swiz.Nm SIMPLEQ_INSERT_AFTER , 10082164e46Schristos.Nm SIMPLEQ_INSERT_HEAD , 10182164e46Schristos.Nm SIMPLEQ_INSERT_TAIL , 10282164e46Schristos.Nm SIMPLEQ_REMOVE_AFTER , 1030246bab0Swiz.Nm SIMPLEQ_REMOVE_HEAD , 10482164e46Schristos.Nm SIMPLEQ_REMOVE , 10582164e46Schristos.Nm SIMPLEQ_CONCAT , 106630651b7Scgd.Nm TAILQ_HEAD , 107ed72b850Scgd.Nm TAILQ_HEAD_INITIALIZER , 1082f6ed1a8Slukem.Nm TAILQ_ENTRY , 10982164e46Schristos.Nm TAILQ_FIRST , 11082164e46Schristos.Nm TAILQ_NEXT , 11182164e46Schristos.Nm TAILQ_LAST , 11282164e46Schristos.Nm TAILQ_PREV , 11382164e46Schristos.Nm TAILQ_EMPTY , 11482164e46Schristos.Nm TAILQ_FOREACH , 11582164e46Schristos.Nm TAILQ_FOREACH_SAFE , 11682164e46Schristos.Nm TAILQ_FOREACH_REVERSE , 11782164e46Schristos.Nm TAILQ_FOREACH_REVERSE_SAFE , 118630651b7Scgd.Nm TAILQ_INIT , 1192f6ed1a8Slukem.Nm TAILQ_INSERT_AFTER , 1202f6ed1a8Slukem.Nm TAILQ_INSERT_BEFORE , 1210246bab0Swiz.Nm TAILQ_INSERT_HEAD , 1220246bab0Swiz.Nm TAILQ_INSERT_TAIL , 123630651b7Scgd.Nm TAILQ_REMOVE , 12482164e46Schristos.Nm TAILQ_REPLACE , 12598c50c91Selad.Nm TAILQ_CONCAT , 12682164e46Schristos.Nm STAILQ_HEAD , 12782164e46Schristos.Nm STAILQ_HEAD_INITIALIZER , 12882164e46Schristos.Nm STAILQ_ENTRY , 12982164e46Schristos.Nm STAILQ_FIRST , 13082164e46Schristos.Nm STAILQ_EMPTY , 13182164e46Schristos.Nm STAILQ_NEXT , 13282164e46Schristos.Nm STAILQ_LAST , 13382164e46Schristos.Nm STAILQ_FOREACH , 13482164e46Schristos.Nm STAILQ_FOREACH_SAFE , 13582164e46Schristos.Nm STAILQ_INIT , 1360246bab0Swiz.Nm STAILQ_INSERT_AFTER , 13782164e46Schristos.Nm STAILQ_INSERT_HEAD , 13882164e46Schristos.Nm STAILQ_INSERT_TAIL , 13982164e46Schristos.Nm STAILQ_REMOVE_HEAD , 14082164e46Schristos.Nm STAILQ_REMOVE , 1411582bbd5Sabhinav.Nm STAILQ_CONCAT 142f2155026Swiz.Nd implementations of singly-linked lists, lists, simple queues, tail queues, and singly-linked tail queues 143630651b7Scgd.Sh SYNOPSIS 144472351e1Swiz.In sys/queue.h 145ba856526Snjoly.Pp 1464c51b74bSdeberg.Fn SLIST_HEAD "HEADNAME" "TYPE" 1474c51b74bSdeberg.Fn SLIST_HEAD_INITIALIZER "head" 1482f6ed1a8Slukem.Fn SLIST_ENTRY "TYPE" 14982164e46Schristos.Ft TYPE * 15082164e46Schristos.Fn SLIST_FIRST "SLIST_HEAD *head" 1514c51b74bSdeberg.Ft int 1524c51b74bSdeberg.Fn SLIST_EMPTY "SLIST_HEAD *head" 1534c51b74bSdeberg.Ft TYPE * 1544c51b74bSdeberg.Fn SLIST_NEXT "TYPE *elm" "SLIST_ENTRY NAME" 15582164e46Schristos.Fn SLIST_FOREACH "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME" 15682164e46Schristos.Fn SLIST_FOREACH_SAFE "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME" "TYPE *tmp" 15782164e46Schristos.Fn SLIST_INIT "SLIST_HEAD *head" 15882164e46Schristos.Fn SLIST_INSERT_HEAD "SLIST_HEAD *head" "TYPE *elm" "SLIST_ENTRY NAME" 15982164e46Schristos.Fn SLIST_INSERT_AFTER "TYPE *listelm" "TYPE *elm" "SLIST_ENTRY NAME" 16082164e46Schristos.Fn SLIST_REMOVE "SLIST_HEAD *head" "TYPE *elm" "TYPE" "SLIST_ENTRY NAME" 16182164e46Schristos.Fn SLIST_REMOVE_HEAD "SLIST_HEAD *head" "SLIST_ENTRY NAME" 162ba856526Snjoly.Pp 16306de4264Slukem.Fn LIST_HEAD "HEADNAME" "TYPE" 16406de4264Slukem.Fn LIST_HEAD_INITIALIZER "head" 1652f6ed1a8Slukem.Fn LIST_ENTRY "TYPE" 16682164e46Schristos.Ft TYPE * 16782164e46Schristos.Fn LIST_FIRST "LIST_HEAD *head" 16882164e46Schristos.Ft TYPE * 16982164e46Schristos.Fn LIST_NEXT "TYPE *elm" "LIST_ENTRY NAME" 17082164e46Schristos.Ft int 17182164e46Schristos.Fn LIST_EMPTY "LIST_HEAD *head" 17282164e46Schristos.Fn LIST_FOREACH "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME" 17382164e46Schristos.Fn LIST_FOREACH_SAFE "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME" "TYPE *tmp" 17406de4264Slukem.Fn LIST_INIT "LIST_HEAD *head" 17506de4264Slukem.Fn LIST_INSERT_AFTER "TYPE *listelm" "TYPE *elm" "LIST_ENTRY NAME" 17606de4264Slukem.Fn LIST_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "LIST_ENTRY NAME" 17706de4264Slukem.Fn LIST_INSERT_HEAD "LIST_HEAD *head" "TYPE *elm" "LIST_ENTRY NAME" 17806de4264Slukem.Fn LIST_REMOVE "TYPE *elm" "LIST_ENTRY NAME" 17982164e46Schristos.Fn LIST_REPLACE "TYPE *elm" "TYPE *new" "LIST_ENTRY NAME" 18037871fa6Spgoyette.Fn LIST_MOVE "LIST_HEAD *head1" "LIST_HEAD *head2" "LIST_ENTRY NAME" 18182164e46Schristos.Pp 18282164e46Schristos.Fn SIMPLEQ_HEAD "HEADNAME" "TYPE" 18382164e46Schristos.Fn SIMPLEQ_HEAD_INITIALIZER "head" 18482164e46Schristos.Fn SIMPLEQ_ENTRY "TYPE" 18582164e46Schristos.Ft TYPE * 18682164e46Schristos.Fn SIMPLEQ_FIRST "SIMPLEQ_HEAD *head" 18706de4264Slukem.Ft int 18882164e46Schristos.Fn SIMPLEQ_EMPTY "SIMPLEQ_HEAD *head" 18906de4264Slukem.Ft TYPE * 19082164e46Schristos.Fn SIMPLEQ_NEXT "TYPE *elm" "SIMPLEQ_ENTRY NAME" 19106de4264Slukem.Ft TYPE * 19282164e46Schristos.Fn SIMPLEQ_LAST "SIMPLEQ_HEAD *head" "TYPE *elm" "SIMPLEQ_ENTRY NAME" 19382164e46Schristos.Fn SIMPLEQ_FOREACH "TYPE *var" "SIMPLEQ_HEAD *head" "SIMPLEQ_ENTRY NAME" 19482164e46Schristos.Fn SIMPLEQ_FOREACH_SAFE "TYPE *var" "SIMPLEQ_HEAD *head" "SIMPLEQ_ENTRY NAME" "TYPE *tmp" 19582164e46Schristos.Fn SIMPLEQ_INIT "SIMPLEQ_HEAD *head" 19682164e46Schristos.Fn SIMPLEQ_INSERT_HEAD "SIMPLEQ_HEAD *head" "TYPE *elm" "SIMPLEQ_ENTRY NAME" 19782164e46Schristos.Fn SIMPLEQ_INSERT_TAIL "SIMPLEQ_HEAD *head" "TYPE *elm" "SIMPLEQ_ENTRY NAME" 19882164e46Schristos.Fn SIMPLEQ_INSERT_AFTER "SIMPLEQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "SIMPLEQ_ENTRY NAME" 19982164e46Schristos.Fn SIMPLEQ_REMOVE_HEAD "SIMPLEQ_HEAD *head" "SIMPLEQ_ENTRY NAME" 20082164e46Schristos.Fn SIMPLEQ_REMOVE_AFTER "SIMPLEQ_HEAD *head" "TYPE *elm" "SIMPLEQ_ENTRY NAME" 20182164e46Schristos.Fn SIMPLEQ_REMOVE "SIMPLEQ_HEAD *head" "TYPE *elm" "TYPE" "SIMPLEQ_ENTRY NAME" 20282164e46Schristos.Fn SIMPLEQ_CONCAT "SIMPLEQ_HEAD *head1" "SIMPLEQ_HEAD *head2" 203ba856526Snjoly.Pp 204630651b7Scgd.Fn TAILQ_HEAD "HEADNAME" "TYPE" 205ed72b850Scgd.Fn TAILQ_HEAD_INITIALIZER "head" 2062f6ed1a8Slukem.Fn TAILQ_ENTRY "TYPE" 207dcbd40b7Sthorpej.Ft TYPE * 208dcbd40b7Sthorpej.Fn TAILQ_FIRST "TAILQ_HEAD *head" 209dcbd40b7Sthorpej.Ft TYPE * 210dcbd40b7Sthorpej.Fn TAILQ_NEXT "TYPE *elm" "TAILQ_ENTRY NAME" 2112f6ed1a8Slukem.Ft TYPE * 2122f6ed1a8Slukem.Fn TAILQ_LAST "TAILQ_HEAD *head" "HEADNAME" 2132f6ed1a8Slukem.Ft TYPE * 2142f6ed1a8Slukem.Fn TAILQ_PREV "TYPE *elm" "HEADNAME" "TAILQ_ENTRY NAME" 21582164e46Schristos.Ft int 21682164e46Schristos.Fn TAILQ_EMPTY "TAILQ_HEAD *head" 21782164e46Schristos.Fn TAILQ_FOREACH "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME" 21882164e46Schristos.Fn TAILQ_FOREACH_SAFE "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME" "TYPE *tmp" 21982164e46Schristos.Fn TAILQ_FOREACH_REVERSE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME" 22082164e46Schristos.Fn TAILQ_FOREACH_REVERSE_SAFE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME" "TYPE *tmp" 22182164e46Schristos.Fn TAILQ_INIT "TAILQ_HEAD *head" 22282164e46Schristos.Fn TAILQ_INSERT_HEAD "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME" 22382164e46Schristos.Fn TAILQ_INSERT_TAIL "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME" 22482164e46Schristos.Fn TAILQ_INSERT_AFTER "TAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME" 22582164e46Schristos.Fn TAILQ_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME" 22682164e46Schristos.Fn TAILQ_REMOVE "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME" 22782164e46Schristos.Fn TAILQ_REPLACE "TAILQ_HEAD *head" "TYPE *elm" "TYPE *new" "TAILQ_ENTRY NAME" 22898c50c91Selad.Fn TAILQ_CONCAT "TAILQ_HEAD *head1" "TAILQ_HEAD *head2" "TAILQ_ENTRY NAME" 22982164e46Schristos.Pp 23082164e46Schristos.Fn STAILQ_HEAD "HEADNAME" "TYPE" 23182164e46Schristos.Fn STAILQ_HEAD_INITIALIZER "head" 23282164e46Schristos.Fn STAILQ_ENTRY "TYPE" 23382164e46Schristos.Ft TYPE * 23482164e46Schristos.Fn STAILQ_FIRST "STAILQ_HEAD *head" 23582164e46Schristos.Ft int 23682164e46Schristos.Fn STAILQ_EMPTY "STAILQ_HEAD *head" 23782164e46Schristos.Ft TYPE * 23882164e46Schristos.Fn STAILQ_NEXT "TYPE *elm" "STAILQ_ENTRY NAME" 23982164e46Schristos.Ft TYPE * 24082164e46Schristos.Fn STAILQ_LAST "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME" 24182164e46Schristos.Fn STAILQ_FOREACH "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" 24282164e46Schristos.Fn STAILQ_FOREACH_SAFE "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" "TYPE *tmp" 24382164e46Schristos.Fn STAILQ_INIT "STAILQ_HEAD *head" 24482164e46Schristos.Fn STAILQ_INSERT_HEAD "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME" 24582164e46Schristos.Fn STAILQ_INSERT_TAIL "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME" 24682164e46Schristos.Fn STAILQ_INSERT_AFTER "STAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "STAILQ_ENTRY NAME" 24782164e46Schristos.Fn STAILQ_REMOVE_HEAD "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" 24882164e46Schristos.Fn STAILQ_REMOVE "STAILQ_HEAD *head" "TYPE *elm" "TYPE" "STAILQ_ENTRY NAME" 24982164e46Schristos.Fn STAILQ_CONCAT "STAILQ_HEAD *head1" "STAILQ_HEAD *head2" 250630651b7Scgd.Sh DESCRIPTION 25182164e46SchristosThese macros define and operate on five types of data structures: 2520246bab0Swizsingly-linked lists, simple queues, lists, tail queues, and singly-linked 25382164e46Schristostail queues. 25482164e46SchristosAll five structures support the following functionality: 255630651b7Scgd.Bl -enum -compact -offset indent 256630651b7Scgd.It 257630651b7ScgdInsertion of a new entry at the head of the list. 258630651b7Scgd.It 2597554718dSpgoyetteInsertion of a new entry after any element in the list. 260630651b7Scgd.It 261630651b7ScgdRemoval of any entry in the list. 262630651b7Scgd.It 263630651b7ScgdForward traversal through the list. 264630651b7Scgd.El 265630651b7Scgd.Pp 2669e7349a5SchristosSingly-linked lists are the simplest of the four data structures and 2674c51b74bSdebergsupport only the above functionality. 2684c51b74bSdebergSingly-linked lists are ideal for applications with large datasets and 2694c51b74bSdebergfew or no removals, 2704c51b74bSdebergor for implementing a LIFO queue. 271630651b7Scgd.Pp 27268727e36SchristosSimple queues add the following functionality: 27368727e36Schristos.Bl -enum -compact -offset indent 27468727e36Schristos.It 27568727e36SchristosEntries can be added at the end of a list. 27698c50c91Selad.It 27798c50c91SeladThey may be concatenated. 27868727e36Schristos.El 27968727e36SchristosHowever: 28068727e36Schristos.Bl -enum -compact -offset indent 28168727e36Schristos.It 28268727e36SchristosEntries may not be added before any element in the list. 28368727e36Schristos.It 28468727e36SchristosAll list insertions and removals must specify the head of the list. 28568727e36Schristos.It 28668727e36SchristosEach head entry requires two pointers rather than one. 28768727e36Schristos.El 28868727e36Schristos.Pp 2894c51b74bSdebergSimple queues are ideal for applications with large datasets and few or 2904c51b74bSdebergno removals, or for implementing a FIFO queue. 2914c51b74bSdeberg.Pp 29206dfe20dSwizAll doubly linked types of data structures (lists and tail queues) 2939e7349a5Schristosadditionally allow: 2944c51b74bSdeberg.Bl -enum -compact -offset indent 2954c51b74bSdeberg.It 2964c51b74bSdebergInsertion of a new entry before any element in the list. 2974c51b74bSdeberg.It 2984c51b74bSdebergO(1) removal of any entry in the list. 2994c51b74bSdeberg.El 3004c51b74bSdebergHowever: 3014c51b74bSdeberg.Bl -enum -compact -offset indent 3024c51b74bSdeberg.It 3034e4095f1SwizEach element requires two pointers rather than one. 3044c51b74bSdeberg.It 3054c51b74bSdebergCode size and execution time of operations (except for removal) is about 3064c51b74bSdebergtwice that of the singly-linked data-structures. 3074c51b74bSdeberg.El 3084c51b74bSdeberg.Pp 3094c51b74bSdebergLinked lists are the simplest of the doubly linked data structures and 3104c51b74bSdebergsupport only the above functionality over singly-linked lists. 3114c51b74bSdeberg.Pp 312630651b7ScgdTail queues add the following functionality: 313630651b7Scgd.Bl -enum -compact -offset indent 314630651b7Scgd.It 315630651b7ScgdEntries can be added at the end of a list. 31698c50c91Selad.It 31798c50c91SeladThey may be concatenated. 318630651b7Scgd.El 319630651b7ScgdHowever: 320630651b7Scgd.Bl -enum -compact -offset indent 321630651b7Scgd.It 32273a1524aSmycroftAll list insertions and removals, except insertion before another element, must 32373a1524aSmycroftspecify the head of the list. 324630651b7Scgd.It 325630651b7ScgdEach head entry requires two pointers rather than one. 326630651b7Scgd.It 327630651b7ScgdCode size is about 15% greater and operations run about 20% slower 328630651b7Scgdthan lists. 329630651b7Scgd.El 330630651b7Scgd.Pp 331630651b7ScgdCircular queues add the following functionality: 332630651b7Scgd.Bl -enum -compact -offset indent 333630651b7Scgd.It 334630651b7ScgdEntries can be added at the end of a list. 335630651b7Scgd.It 336630651b7ScgdThey may be traversed backwards, from tail to head. 337630651b7Scgd.El 338630651b7ScgdHowever: 339630651b7Scgd.Bl -enum -compact -offset indent 340630651b7Scgd.It 341630651b7ScgdAll list insertions and removals must specify the head of the list. 342630651b7Scgd.It 343630651b7ScgdEach head entry requires two pointers rather than one. 344630651b7Scgd.It 345630651b7ScgdThe termination condition for traversal is more complex. 346630651b7Scgd.It 347630651b7ScgdCode size is about 40% greater and operations run about 45% slower 348630651b7Scgdthan lists. 349630651b7Scgd.El 350630651b7Scgd.Pp 351630651b7ScgdIn the macro definitions, 352630651b7Scgd.Fa TYPE 353630651b7Scgdis the name of a user defined structure, 354630651b7Scgdthat must contain a field of type 35582164e46Schristos.Li SLIST_ENTRY , 356630651b7Scgd.Li LIST_ENTRY , 35768727e36Schristos.Li SIMPLEQ_ENTRY , 3589e7349a5Schristos.Li TAILQ_ENTRY , 35982164e46Schristosor 36082164e46Schristos.Li STAILQ_ENTRY , 361630651b7Scgdnamed 362630651b7Scgd.Fa NAME . 363630651b7ScgdThe argument 364630651b7Scgd.Fa HEADNAME 365630651b7Scgdis the name of a user defined structure that must be declared 366630651b7Scgdusing the macros 367630651b7Scgd.Li LIST_HEAD , 36868727e36Schristos.Li SIMPLEQ_HEAD , 3694c51b74bSdeberg.Li SLIST_HEAD , 370630651b7Scgdor 37162d7bff7Ssnj.Li TAILQ_HEAD . 372630651b7ScgdSee the examples below for further explanation of how these 373630651b7Scgdmacros are used. 37494e818b2Spooka.Ss Summary of Operations 37594e818b2SpookaThe following table summarizes the supported macros for each type 37694e818b2Spookaof data structure. 37794e818b2Spooka.Pp 37894e818b2Spooka.TS 37994e818b2Spookabox tab(:); 3809e7349a5Schristosl | c | c | c | c | c 3819e7349a5Schristosl | c | c | c | c | c 3829e7349a5Schristosl | c | c | c | c | c 3839e7349a5Schristosl | c | c | c | c | c 3849e7349a5Schristosl | c | c | c | c | c 3859e7349a5Schristosl | c | c | c | c | c. 38682164e46Schristos:SLIST:LIST:SIMPLEQ:TAILQ:STAILQ 38794e818b2Spooka_ 3889e7349a5Schristos_FIRST:+:+:+:+:+ 38982164e46Schristos_EMPTY:+:+:+:+:+ 3909e7349a5Schristos_NEXT:+:+:+:+:+ 39182164e46Schristos_PREV:-:-:-:+:- 39282164e46Schristos_LAST:-:-:+:+:+ 39382164e46Schristos_FOREACH:+:+:+:+:+ 39482164e46Schristos_FOREACH_SAFE:+:+:+:+:+ 39582164e46Schristos_FOREACH_REVERSE:-:-:-:+:- 39682164e46Schristos_FOREACH_REVERSE_SAFE:-:-:-:+:- 39782164e46Schristos_INSERT_HEAD:+:+:+:+:+ 39882164e46Schristos_INSERT_AFTER:+:+:+:+:+ 39982164e46Schristos_INSERT_BEFORE:-:+:-:+:- 40082164e46Schristos_INSERT_TAIL:-:-:+:+:+ 4019e7349a5Schristos_REMOVE:+:+:+:+:+ 40282164e46Schristos_REMOVE_HEAD:+:-:+:-:+ 40382164e46Schristos_REMOVE_AFTER:-:-:+:-:+ 40482164e46Schristos_REPLACE:-:+:-:+:- 4059e7349a5Schristos_CONCAT:-:-:+:+:+ 40694e818b2Spooka.TE 4074c51b74bSdeberg.Sh SINGLY-LINKED LISTS 4084c51b74bSdebergA singly-linked list is headed by a structure defined by the 4090604df8aSabhinav.Fn SLIST_HEAD 4104c51b74bSdebergmacro. 4114c51b74bSdebergThis structure contains a single pointer to the first element 4124c51b74bSdebergon the list. 4134c51b74bSdebergThe elements are singly linked for minimum space and pointer manipulation 4144c51b74bSdebergoverhead at the expense of O(n) removal for arbitrary elements. 4154c51b74bSdebergNew elements can be added to the list after an existing element or 4164c51b74bSdebergat the head of the list. 4174c51b74bSdebergAn 4184c51b74bSdeberg.Fa SLIST_HEAD 4194c51b74bSdebergstructure is declared as follows: 4204c51b74bSdeberg.Bd -literal -offset indent 4214c51b74bSdebergSLIST_HEAD(HEADNAME, TYPE) head; 4224c51b74bSdeberg.Ed 4234c51b74bSdeberg.Pp 4244c51b74bSdebergwhere 4254c51b74bSdeberg.Fa HEADNAME 4264c51b74bSdebergis the name of the structure to be defined, and 4274c51b74bSdeberg.Fa TYPE 4284c51b74bSdebergis the type of the elements to be linked into the list. 4294c51b74bSdebergA pointer to the head of the list can later be declared as: 4304c51b74bSdeberg.Bd -literal -offset indent 4314c51b74bSdebergstruct HEADNAME *headp; 4324c51b74bSdeberg.Ed 4334c51b74bSdeberg.Pp 4344c51b74bSdeberg(The names 4354c51b74bSdeberg.Li head 4364c51b74bSdebergand 4374c51b74bSdeberg.Li headp 4384c51b74bSdebergare user selectable.) 4394c51b74bSdeberg.Pp 4404c51b74bSdebergThe macro 4410604df8aSabhinav.Fn SLIST_HEAD_INITIALIZER 4424c51b74bSdebergevaluates to an initializer for the list 4434c51b74bSdeberg.Fa head . 4444c51b74bSdeberg.Pp 4454c51b74bSdebergThe macro 4460604df8aSabhinav.Fn SLIST_ENTRY 4474c51b74bSdebergdeclares a structure that connects the elements in 4484c51b74bSdebergthe list. 4494c51b74bSdeberg.Pp 4504c51b74bSdebergThe macro 4510604df8aSabhinav.Fn SLIST_FIRST 4524c51b74bSdebergreturns the first element in the list or NULL if the list is empty. 4534c51b74bSdeberg.Pp 4544c51b74bSdebergThe macro 4550604df8aSabhinav.Fn SLIST_EMPTY 45682164e46Schristosevaluates to true if there are no elements in the list. 45782164e46Schristos.Pp 45882164e46SchristosThe macro 4590604df8aSabhinav.Fn SLIST_NEXT 46082164e46Schristosreturns the next element in the list. 46182164e46Schristos.Pp 4620604df8aSabhinav.Fn SLIST_FOREACH 4634c51b74bSdebergtraverses the list referenced by 4644c51b74bSdeberg.Fa head 4654c51b74bSdebergin the forward direction, assigning each element in 4664c51b74bSdebergturn to 4674c51b74bSdeberg.Fa var . 4684c51b74bSdeberg.Pp 46982164e46SchristosThe SAFE version uses 4700d53a16dSmschuett.Fa tmp 4710d53a16dSmschuettto hold the next element, so 4720d53a16dSmschuett.Fa var 4730d53a16dSmschuettmay be freed or removed from the list. 4740d53a16dSmschuett.Pp 4754c51b74bSdebergThe macro 4760604df8aSabhinav.Fn SLIST_INIT 4774c51b74bSdeberginitializes the list referenced by 4784c51b74bSdeberg.Fa head . 4794c51b74bSdeberg.Pp 4804c51b74bSdebergThe macro 4810604df8aSabhinav.Fn SLIST_INSERT_HEAD 4824c51b74bSdeberginserts the new element 4834c51b74bSdeberg.Fa elm 4844c51b74bSdebergat the head of the list. 4854c51b74bSdeberg.Pp 4864c51b74bSdebergThe macro 4870604df8aSabhinav.Fn SLIST_INSERT_AFTER 4884c51b74bSdeberginserts the new element 4894c51b74bSdeberg.Fa elm 4904c51b74bSdebergafter the element 4914c51b74bSdeberg.Fa listelm . 4924c51b74bSdeberg.Pp 4934c51b74bSdebergThe macro 4940604df8aSabhinav.Fn SLIST_REMOVE 49506de4264Slukemremoves the element 49606de4264Slukem.Fa elm 49706de4264Slukemfrom the list. 49806de4264Slukem.Pp 49906de4264SlukemThe macro 5000604df8aSabhinav.Fn SLIST_REMOVE_HEAD 501874c812dSlukemremoves the first element from the head of the list. 5024c51b74bSdebergFor optimum efficiency, 5034c51b74bSdebergelements being removed from the head of the list should explicitly use 5044c51b74bSdebergthis macro instead of the generic 5050604df8aSabhinav.Fn SLIST_REMOVE 50606de4264Slukemmacro. 50782164e46Schristos.Pp 50862d7bff7SsnjThe macro 5090604df8aSabhinav.Fn SLIST_REMOVE_AFTER 51082164e46Schristosremoves the element after the one specified. 51182164e46SchristosFor optimum efficiency, 51282164e46Schristoselements being removed after a specified one should explicitly use 51382164e46Schristosthis macro instead of the generic 5140604df8aSabhinav.Fn SLIST_REMOVE 5154c51b74bSdeberg.Sh SINGLY-LINKED LIST EXAMPLE 5164c51b74bSdeberg.Bd -literal 5174c51b74bSdebergSLIST_HEAD(slisthead, entry) head = 5184c51b74bSdeberg SLIST_HEAD_INITIALIZER(head); 5194c51b74bSdebergstruct slisthead *headp; /* Singly-linked List head. */ 5204c51b74bSdebergstruct entry { 5214c51b74bSdeberg ... 5224c51b74bSdeberg SLIST_ENTRY(entry) entries; /* Singly-linked List. */ 5234c51b74bSdeberg ... 5244c51b74bSdeberg} *n1, *n2, *n3, *np; 5254c51b74bSdeberg 52601869ca4SwizSLIST_INIT(&head); /* Initialize the list. */ 5274c51b74bSdeberg 5284c51b74bSdebergn1 = malloc(sizeof(struct entry)); /* Insert at the head. */ 52901869ca4SwizSLIST_INSERT_HEAD(&head, n1, entries); 5304c51b74bSdeberg 5314c51b74bSdebergn2 = malloc(sizeof(struct entry)); /* Insert after. */ 5324c51b74bSdebergSLIST_INSERT_AFTER(n1, n2, entries); 5334c51b74bSdeberg 53401869ca4SwizSLIST_REMOVE(&head, n2, entry, entries);/* Deletion. */ 5354c51b74bSdebergfree(n2); 5364c51b74bSdeberg 53701869ca4Swizn3 = SLIST_FIRST(&head); 53801869ca4SwizSLIST_REMOVE_HEAD(&head, entries); /* Deletion from the head. */ 5394c51b74bSdebergfree(n3); 540318922f0Sryoon 54101869ca4SwizSLIST_FOREACH(np, &head, entries) /* Forward traversal. */ 54201869ca4Swiz np-> ... 5434c51b74bSdeberg 54401869ca4Swizwhile (!SLIST_EMPTY(&head)) { /* List Deletion. */ 54501869ca4Swiz n1 = SLIST_FIRST(&head); 54601869ca4Swiz SLIST_REMOVE_HEAD(&head, entries); 5474c51b74bSdeberg free(n1); 5484c51b74bSdeberg} 5494c51b74bSdeberg.Ed 55082164e46Schristos.Sh LISTS 55182164e46SchristosA list is headed by a structure defined by the 5520604df8aSabhinav.Fn LIST_HEAD 55382164e46Schristosmacro. 55482164e46SchristosThis structure contains a single pointer to the first element 55582164e46Schristoson the list. 55682164e46SchristosThe elements are doubly linked so that an arbitrary element can be 55782164e46Schristosremoved without traversing the list. 55882164e46SchristosNew elements can be added to the list after an existing element, 55982164e46Schristosbefore an existing element, or at the head of the list. 56082164e46SchristosA 56182164e46Schristos.Fa LIST_HEAD 56282164e46Schristosstructure is declared as follows: 56382164e46Schristos.Bd -literal -offset indent 56482164e46SchristosLIST_HEAD(HEADNAME, TYPE) head; 56582164e46Schristos.Ed 56682164e46Schristos.Pp 56782164e46Schristoswhere 56882164e46Schristos.Fa HEADNAME 56982164e46Schristosis the name of the structure to be defined, and 57082164e46Schristos.Fa TYPE 57182164e46Schristosis the type of the elements to be linked into the list. 57282164e46SchristosA pointer to the head of the list can later be declared as: 57382164e46Schristos.Bd -literal -offset indent 57482164e46Schristosstruct HEADNAME *headp; 57582164e46Schristos.Ed 57682164e46Schristos.Pp 57782164e46Schristos(The names 57882164e46Schristos.Li head 57982164e46Schristosand 58082164e46Schristos.Li headp 58182164e46Schristosare user selectable.) 58282164e46Schristos.Pp 58382164e46SchristosThe macro 5840604df8aSabhinav.Fn LIST_ENTRY 58582164e46Schristosdeclares a structure that connects the elements in 58682164e46Schristosthe list. 58782164e46Schristos.Pp 58882164e46SchristosThe macro 5890604df8aSabhinav.Fn LIST_HEAD_INITIALIZER 59082164e46Schristosprovides a value which can be used to initialize a list head at 59182164e46Schristoscompile time, and is used at the point that the list head 59282164e46Schristosvariable is declared, like: 59382164e46Schristos.Bd -literal -offset indent 59482164e46Schristosstruct HEADNAME head = LIST_HEAD_INITIALIZER(head); 59582164e46Schristos.Ed 59682164e46Schristos.Pp 59782164e46SchristosThe macro 5980604df8aSabhinav.Fn LIST_FIRST 59982164e46Schristosreturns the first element of the list 60082164e46Schristos.Fa head . 60182164e46Schristos.Pp 60282164e46SchristosThe macro 6030604df8aSabhinav.Fn LIST_EMPTY 60462d7bff7Ssnjreturns true if the list 60582164e46Schristos.Fa head 60682164e46Schristoshas no elements. 60782164e46Schristos.Pp 60882164e46SchristosThe macro 6090604df8aSabhinav.Fn LIST_NEXT 61082164e46Schristosreturns the element after the element 61182164e46Schristos.Fa elm . 61282164e46Schristos.Pp 61382164e46SchristosThe macro 6140604df8aSabhinav.Fn LIST_FOREACH 61582164e46Schristostraverses the list referenced by 61682164e46Schristos.Fa head 61782164e46Schristosin the forward direction, assigning each element in turn to 61882164e46Schristos.Fa var . 61982164e46Schristos.Pp 62082164e46SchristosThe SAFE version uses 62182164e46Schristos.Fa tmp 62282164e46Schristosto hold the next element, so 62382164e46Schristos.Fa var 62482164e46Schristosmay be freed or removed from the list. 62582164e46Schristos.Pp 62682164e46SchristosThe macro 6270604df8aSabhinav.Fn LIST_INIT 62882164e46Schristosinitializes the list referenced by 62982164e46Schristos.Fa head . 63082164e46Schristos.Pp 63182164e46SchristosThe macro 6320604df8aSabhinav.Fn LIST_INSERT_AFTER 63382164e46Schristosinserts the new element 63482164e46Schristos.Fa elm 63582164e46Schristosafter the element 63682164e46Schristos.Fa listelm . 63782164e46Schristos.Pp 63882164e46SchristosThe macro 6390604df8aSabhinav.Fn LIST_INSERT_BEFORE 64082164e46Schristosinserts the new element 64182164e46Schristos.Fa elm 64282164e46Schristosbefore the element 64382164e46Schristos.Fa listelm . 64482164e46Schristos.Pp 64582164e46SchristosThe macro 6460604df8aSabhinav.Fn LIST_INSERT_HEAD 64782164e46Schristosinserts the new element 64882164e46Schristos.Fa elm 64982164e46Schristosat the head of the list. 65082164e46Schristos.Pp 65182164e46SchristosThe macro 6520604df8aSabhinav.Fn LIST_REMOVE 65382164e46Schristosremoves the element 65482164e46Schristos.Fa elm 65582164e46Schristosfrom the list. 65682164e46Schristos.Pp 65782164e46SchristosThe macro 6580604df8aSabhinav.Fn LIST_REPLACE 65982164e46Schristosreplaces the element 66082164e46Schristos.Fa elm 66182164e46Schristoswith 66282164e46Schristos.Fa new 66382164e46Schristosin the list. 664169afaf5Srmind.Pp 665169afaf5SrmindThe macro 6660604df8aSabhinav.Fn LIST_MOVE 667169afaf5Srmindmoves the list headed by 668169afaf5Srmind.Fa head1 669169afaf5Srmindonto the list headed by 670169afaf5Srmind.Fa head2 , 671169afaf5Srmindalways making the former empty. 67282164e46Schristos.Sh LIST EXAMPLE 67382164e46Schristos.Bd -literal 67482164e46SchristosLIST_HEAD(listhead, entry) head; 67582164e46Schristosstruct listhead *headp; /* List head. */ 67682164e46Schristosstruct entry { 67782164e46Schristos ... 67882164e46Schristos LIST_ENTRY(entry) entries; /* List. */ 67982164e46Schristos ... 68082164e46Schristos} *n1, *n2, *np; 68182164e46Schristos 68201869ca4SwizLIST_INIT(&head); /* Initialize the list. */ 68382164e46Schristos 68482164e46Schristosn1 = malloc(sizeof(struct entry)); /* Insert at the head. */ 68501869ca4SwizLIST_INSERT_HEAD(&head, n1, entries); 68682164e46Schristos 68782164e46Schristosn2 = malloc(sizeof(struct entry)); /* Insert after. */ 68882164e46SchristosLIST_INSERT_AFTER(n1, n2, entries); 68982164e46Schristos 69082164e46Schristosn2 = malloc(sizeof(struct entry)); /* Insert before. */ 69182164e46SchristosLIST_INSERT_BEFORE(n1, n2, entries); 692318922f0Sryoon 69301869ca4SwizLIST_FOREACH(np, &head, entries) /* Forward traversal. */ 69401869ca4Swiz np-> ... 695318922f0Sryoon 69601869ca4Swizwhile (LIST_FIRST(&head) != NULL) /* Delete. */ 69701869ca4Swiz LIST_REMOVE(LIST_FIRST(&head), entries); 69801869ca4Swizif (LIST_EMPTY(&head)) /* Test for emptiness. */ 69982164e46Schristos printf("nothing to do\\n"); 70082164e46Schristos.Ed 70106de4264Slukem.Sh SIMPLE QUEUES 70206de4264SlukemA simple queue is headed by a structure defined by the 7030604df8aSabhinav.Fn SIMPLEQ_HEAD 70406de4264Slukemmacro. 70506de4264SlukemThis structure contains a pair of pointers, 70606de4264Slukemone to the first element in the simple queue and the other to 70706de4264Slukemthe last element in the simple queue. 70806de4264SlukemThe elements are singly linked for minimum space and pointer manipulation 70906de4264Slukemoverhead at the expense of O(n) removal for arbitrary elements. 71006de4264SlukemNew elements can be added to the queue after an existing element, 71106de4264Slukemat the head of the queue, or at the end of the queue. 71206de4264SlukemA 71306de4264Slukem.Fa SIMPLEQ_HEAD 71406de4264Slukemstructure is declared as follows: 71506de4264Slukem.Bd -literal -offset indent 71606de4264SlukemSIMPLEQ_HEAD(HEADNAME, TYPE) head; 71706de4264Slukem.Ed 718ba856526Snjoly.Pp 71906de4264Slukemwhere 72006de4264Slukem.Li HEADNAME 72106de4264Slukemis the name of the structure to be defined, and 72206de4264Slukem.Li TYPE 72306de4264Slukemis the type of the elements to be linked into the simple queue. 72406de4264SlukemA pointer to the head of the simple queue can later be declared as: 72506de4264Slukem.Bd -literal -offset indent 72606de4264Slukemstruct HEADNAME *headp; 72706de4264Slukem.Ed 728ba856526Snjoly.Pp 72906de4264Slukem(The names 73006de4264Slukem.Li head 73106de4264Slukemand 73206de4264Slukem.Li headp 73306de4264Slukemare user selectable.) 73406de4264Slukem.Pp 73506de4264SlukemThe macro 7360604df8aSabhinav.Fn SIMPLEQ_ENTRY 73706de4264Slukemdeclares a structure that connects the elements in 73806de4264Slukemthe simple queue. 73906de4264Slukem.Pp 74006de4264SlukemThe macro 7410604df8aSabhinav.Fn SIMPLEQ_HEAD_INITIALIZER 74206de4264Slukemprovides a value which can be used to initialize a simple queue head at 74306de4264Slukemcompile time, and is used at the point that the simple queue head 74406de4264Slukemvariable is declared, like: 74506de4264Slukem.Bd -literal -offset indent 74606de4264Slukemstruct HEADNAME head = SIMPLEQ_HEAD_INITIALIZER(head); 74706de4264Slukem.Ed 74806de4264Slukem.Pp 74906de4264SlukemThe macro 7500604df8aSabhinav.Fn SIMPLEQ_FIRST 75182164e46Schristosreturns the first element of the simple queue 75282164e46Schristos.Fa head . 75382164e46Schristos.Pp 75482164e46SchristosThe macro 7550604df8aSabhinav.Fn SIMPLEQ_EMPTY 75662d7bff7Ssnjreturns true if the simple queue 75782164e46Schristos.Fa head 75882164e46Schristoshas no elements. 75982164e46Schristos.Pp 76082164e46SchristosThe macro 7610604df8aSabhinav.Fn SIMPLEQ_NEXT 76282164e46Schristosreturns the element after the element 76382164e46Schristos.Fa elm . 76482164e46Schristos.Pp 76582164e46SchristosThe macro 7660604df8aSabhinav.Fn SIMPLEQ_LAST 76708587dfcSisakireturns the last item on the simple queue. 76808587dfcSisakiIf the simple queue is empty the return value is 76982164e46Schristos.Dv NULL . 77082164e46Schristos.Pp 77182164e46SchristosThe macro 7720604df8aSabhinav.Fn SIMPLEQ_FOREACH 77308587dfcSisakitraverses the simple queue referenced by 77482164e46Schristos.Fa head 77582164e46Schristosin the forward direction, assigning each element 77682164e46Schristosin turn to 77782164e46Schristos.Fa var . 77882164e46Schristos.Pp 77982164e46SchristosThe SAFE version uses 78082164e46Schristos.Fa tmp 78182164e46Schristosto hold the next element, so 78282164e46Schristos.Fa var 78382164e46Schristosmay be freed or removed from the list. 78482164e46Schristos.Pp 78582164e46SchristosThe macro 7860604df8aSabhinav.Fn SIMPLEQ_INIT 78706de4264Slukeminitializes the simple queue referenced by 78806de4264Slukem.Fa head . 78906de4264Slukem.Pp 79006de4264SlukemThe macro 7910604df8aSabhinav.Fn SIMPLEQ_INSERT_HEAD 79206de4264Slukeminserts the new element 79306de4264Slukem.Fa elm 79406de4264Slukemat the head of the simple queue. 79506de4264Slukem.Pp 79606de4264SlukemThe macro 7970604df8aSabhinav.Fn SIMPLEQ_INSERT_TAIL 79806de4264Slukeminserts the new element 79906de4264Slukem.Fa elm 80006de4264Slukemat the end of the simple queue. 80106de4264Slukem.Pp 80206de4264SlukemThe macro 8030604df8aSabhinav.Fn SIMPLEQ_INSERT_AFTER 80406de4264Slukeminserts the new element 80506de4264Slukem.Fa elm 80606de4264Slukemafter the element 80706de4264Slukem.Fa listelm . 80806de4264Slukem.Pp 80906de4264SlukemThe macro 8100604df8aSabhinav.Fn SIMPLEQ_REMOVE_HEAD 81106de4264Slukemremoves the first element from the head of the simple queue. 81206de4264SlukemFor optimum efficiency, 81306de4264Slukemelements being removed from the head of the queue should explicitly use 81406de4264Slukemthis macro instead of the generic 8150604df8aSabhinav.Fn SIMPLEQ_REMOVE 81606de4264Slukemmacro. 81706de4264Slukem.Pp 81806de4264SlukemThe macro 8190604df8aSabhinav.Fn SIMPLEQ_REMOVE_AFTER 82082164e46Schristosremoves the element after the one specified from the simple queue. 82182164e46SchristosFor optimum efficiency, 82282164e46Schristoselements being removed after specified elements should explicitly use 82382164e46Schristosthis macro instead of the generic 8240604df8aSabhinav.Fn SIMPLEQ_REMOVE 82582164e46Schristosmacro. 82606de4264Slukem.Pp 82706de4264SlukemThe macro 8280604df8aSabhinav.Fn SIMPLEQ_REMOVE 82982164e46Schristosremoves 83082164e46Schristos.Fa elm 83182164e46Schristosfrom the simple queue. 8320d53a16dSmschuett.Pp 8330d53a16dSmschuettThe macro 8340604df8aSabhinav.Fn SIMPLEQ_CONCAT 83508587dfcSisakiconcatenates the simple queue headed by 8360d53a16dSmschuett.Fa head2 8370d53a16dSmschuettonto the end of the one headed by 83862d7bff7Ssnj.Fa head1 , 8390d53a16dSmschuettremoving all entries from the former. 84006de4264Slukem.Sh SIMPLE QUEUE EXAMPLE 84106de4264Slukem.Bd -literal 84206de4264SlukemSIMPLEQ_HEAD(simplehead, entry) head; 84306de4264Slukemstruct simplehead *headp; /* Simple queue head. */ 84406de4264Slukemstruct entry { 84506de4264Slukem ... 84606de4264Slukem SIMPLEQ_ENTRY(entry) entries; /* Simple queue. */ 84706de4264Slukem ... 84806de4264Slukem} *n1, *n2, *np; 84906de4264Slukem 85001869ca4SwizSIMPLEQ_INIT(&head); /* Initialize the queue. */ 85106de4264Slukem 85206de4264Slukemn1 = malloc(sizeof(struct entry)); /* Insert at the head. */ 85301869ca4SwizSIMPLEQ_INSERT_HEAD(&head, n1, entries); 85406de4264Slukem 85506de4264Slukemn1 = malloc(sizeof(struct entry)); /* Insert at the tail. */ 85601869ca4SwizSIMPLEQ_INSERT_TAIL(&head, n1, entries); 85706de4264Slukem 85806de4264Slukemn2 = malloc(sizeof(struct entry)); /* Insert after. */ 85901869ca4SwizSIMPLEQ_INSERT_AFTER(&head, n1, n2, entries); 860318922f0Sryoon 86101869ca4SwizSIMPLEQ_FOREACH(np, &head, entries) /* Forward traversal. */ 86201869ca4Swiz np-> ... 863318922f0Sryoon 86401869ca4Swizwhile (SIMPLEQ_FIRST(&head) != NULL) /* Delete. */ 86501869ca4Swiz SIMPLEQ_REMOVE_HEAD(&head, entries); 86601869ca4Swizif (SIMPLEQ_EMPTY(&head)) /* Test for emptiness. */ 86706de4264Slukem printf("nothing to do\\n"); 86806de4264Slukem.Ed 869630651b7Scgd.Sh TAIL QUEUES 870630651b7ScgdA tail queue is headed by a structure defined by the 8710604df8aSabhinav.Fn TAILQ_HEAD 872630651b7Scgdmacro. 873630651b7ScgdThis structure contains a pair of pointers, 874630651b7Scgdone to the first element in the tail queue and the other to 875630651b7Scgdthe last element in the tail queue. 876630651b7ScgdThe elements are doubly linked so that an arbitrary element can be 877630651b7Scgdremoved without traversing the tail queue. 878b545b9dbSmycroftNew elements can be added to the queue after an existing element, 879b545b9dbSmycroftbefore an existing element, at the head of the queue, or at the end 880b545b9dbSmycroftthe queue. 881630651b7ScgdA 882630651b7Scgd.Fa TAILQ_HEAD 883630651b7Scgdstructure is declared as follows: 884630651b7Scgd.Bd -literal -offset indent 885630651b7ScgdTAILQ_HEAD(HEADNAME, TYPE) head; 886630651b7Scgd.Ed 887ba856526Snjoly.Pp 888630651b7Scgdwhere 889630651b7Scgd.Li HEADNAME 890630651b7Scgdis the name of the structure to be defined, and 891630651b7Scgd.Li TYPE 892630651b7Scgdis the type of the elements to be linked into the tail queue. 893630651b7ScgdA pointer to the head of the tail queue can later be declared as: 894630651b7Scgd.Bd -literal -offset indent 895630651b7Scgdstruct HEADNAME *headp; 896630651b7Scgd.Ed 897ba856526Snjoly.Pp 898630651b7Scgd(The names 899630651b7Scgd.Li head 900630651b7Scgdand 901630651b7Scgd.Li headp 902630651b7Scgdare user selectable.) 903630651b7Scgd.Pp 904630651b7ScgdThe macro 9050604df8aSabhinav.Fn TAILQ_ENTRY 906630651b7Scgddeclares a structure that connects the elements in 907630651b7Scgdthe tail queue. 908630651b7Scgd.Pp 909630651b7ScgdThe macro 9100604df8aSabhinav.Fn TAILQ_HEAD_INITIALIZER 911ed72b850Scgdprovides a value which can be used to initialize a tail queue head at 912ed72b850Scgdcompile time, and is used at the point that the tail queue head 913ed72b850Scgdvariable is declared, like: 914ed72b850Scgd.Bd -literal -offset indent 915ed72b850Scgdstruct HEADNAME head = TAILQ_HEAD_INITIALIZER(head); 916ed72b850Scgd.Ed 917ed72b850Scgd.Pp 918ed72b850ScgdThe macro 9190604df8aSabhinav.Fn TAILQ_FIRST 92082164e46Schristosreturns the first element of the tail queue 92182164e46Schristos.Fa head . 92282164e46Schristos.Pp 92382164e46SchristosThe macro 9240604df8aSabhinav.Fn TAILQ_NEXT 92582164e46Schristosreturns the element after the element 92682164e46Schristos.Fa elm . 92782164e46Schristos.Pp 92882164e46SchristosThe macro 9290604df8aSabhinav.Fn TAILQ_LAST 93082164e46Schristosreturns the last item on the tail queue. 93182164e46SchristosIf the tail queue is empty the return value is 93282164e46Schristos.Dv NULL . 93382164e46Schristos.Pp 93482164e46SchristosThe macro 9350604df8aSabhinav.Fn TAILQ_PREV 93682164e46Schristosreturns the previous item on the tail queue, from the one specified. 93782164e46SchristosIf the tail queue is empty the return value is 93882164e46Schristos.Dv NULL . 93982164e46Schristos.Pp 94082164e46SchristosThe macro 9410604df8aSabhinav.Fn TAILQ_EMPTY 94262d7bff7Ssnjreturns true if the tail queue 94382164e46Schristos.Fa head 94482164e46Schristoshas no elements. 94582164e46Schristos.Pp 94682164e46SchristosThe macros 9470604df8aSabhinav.Fn TAILQ_FOREACH , 9480604df8aSabhinav.Fn TAILQ_FOREACH_REVERSE , 9490604df8aSabhinav.Fn TAILQ_FOREACH_SAFE , 95082164e46Schristosand 9510604df8aSabhinav.Fn TAILQ_FOREACH_REVERSE_SAFE 95282164e46Schristostraverse the tail queue referenced by 95382164e46Schristos.Fa head 9548b7a64b2Seadlerin the forward or reverse direction, assigning each element in turn to 95582164e46Schristos.Fa var . 95682164e46Schristos.Pp 95782164e46SchristosThe SAFE versions use 95882164e46Schristos.Fa tmp 95982164e46Schristosto hold the next element, so 96082164e46Schristos.Fa var 96182164e46Schristosmay be freed or removed from the list. 96282164e46Schristos.Pp 96382164e46SchristosThe macro 9640604df8aSabhinav.Fn TAILQ_INIT 965630651b7Scgdinitializes the tail queue referenced by 966630651b7Scgd.Fa head . 967630651b7Scgd.Pp 968630651b7ScgdThe macro 9690604df8aSabhinav.Fn TAILQ_INSERT_HEAD 970630651b7Scgdinserts the new element 971630651b7Scgd.Fa elm 972630651b7Scgdat the head of the tail queue. 973630651b7Scgd.Pp 974630651b7ScgdThe macro 9750604df8aSabhinav.Fn TAILQ_INSERT_TAIL 976630651b7Scgdinserts the new element 977630651b7Scgd.Fa elm 978630651b7Scgdat the end of the tail queue. 979630651b7Scgd.Pp 980630651b7ScgdThe macro 9810604df8aSabhinav.Fn TAILQ_INSERT_AFTER 982630651b7Scgdinserts the new element 983630651b7Scgd.Fa elm 984630651b7Scgdafter the element 985630651b7Scgd.Fa listelm . 986630651b7Scgd.Pp 987630651b7ScgdThe macro 9880604df8aSabhinav.Fn TAILQ_INSERT_BEFORE 98973a1524aSmycroftinserts the new element 99073a1524aSmycroft.Fa elm 99173a1524aSmycroftbefore the element 99273a1524aSmycroft.Fa listelm . 99373a1524aSmycroft.Pp 99473a1524aSmycroftThe macro 9950604df8aSabhinav.Fn TAILQ_REMOVE 996630651b7Scgdremoves the element 997630651b7Scgd.Fa elm 998630651b7Scgdfrom the tail queue. 999dcbd40b7Sthorpej.Pp 1000dcbd40b7SthorpejThe macro 10010604df8aSabhinav.Fn TAILQ_REPLACE 100262d7bff7Ssnjreplaces the element 100382164e46Schristos.Fa elm 100482164e46Schristoswith the 100582164e46Schristos.Fa new 100682164e46Schristosone specified in the tail queue. 100798c50c91Selad.Pp 100898c50c91SeladThe macro 10090604df8aSabhinav.Fn TAILQ_CONCAT 101098c50c91Seladconcatenates the tail queue headed by 101198c50c91Selad.Fa head2 101298c50c91Seladonto the end of the one headed by 101362d7bff7Ssnj.Fa head1 , 101498c50c91Seladremoving all entries from the former. 1015630651b7Scgd.Sh TAIL QUEUE EXAMPLE 1016630651b7Scgd.Bd -literal 1017630651b7ScgdTAILQ_HEAD(tailhead, entry) head; 1018630651b7Scgdstruct tailhead *headp; /* Tail queue head. */ 1019630651b7Scgdstruct entry { 1020630651b7Scgd ... 1021630651b7Scgd TAILQ_ENTRY(entry) entries; /* Tail queue. */ 1022630651b7Scgd ... 1023630651b7Scgd} *n1, *n2, *np; 1024630651b7Scgd 102501869ca4SwizTAILQ_INIT(&head); /* Initialize the queue. */ 1026630651b7Scgd 1027630651b7Scgdn1 = malloc(sizeof(struct entry)); /* Insert at the head. */ 102801869ca4SwizTAILQ_INSERT_HEAD(&head, n1, entries); 1029630651b7Scgd 1030630651b7Scgdn1 = malloc(sizeof(struct entry)); /* Insert at the tail. */ 103101869ca4SwizTAILQ_INSERT_TAIL(&head, n1, entries); 1032630651b7Scgd 1033630651b7Scgdn2 = malloc(sizeof(struct entry)); /* Insert after. */ 103401869ca4SwizTAILQ_INSERT_AFTER(&head, n1, n2, entries); 103573a1524aSmycroft 103673a1524aSmycroftn2 = malloc(sizeof(struct entry)); /* Insert before. */ 103773a1524aSmycroftTAILQ_INSERT_BEFORE(n1, n2, entries); 1038318922f0Sryoon 103901869ca4SwizTAILQ_FOREACH(np, &head, entries) /* Forward traversal. */ 104001869ca4Swiz np-> ... 10414c51b74bSdeberg /* Reverse traversal. */ 104201869ca4SwizTAILQ_FOREACH_REVERSE(np, &head, tailhead, entries) 104301869ca4Swiz np-> ... 1044318922f0Sryoon 104501869ca4Swizwhile (TAILQ_FIRST(&head) != NULL) /* Delete. */ 104601869ca4Swiz TAILQ_REMOVE(&head, TAILQ_FIRST(&head), entries); 104701869ca4Swizif (TAILQ_EMPTY(&head)) /* Test for emptiness. */ 104889e229d9Smycroft printf("nothing to do\\n"); 1049630651b7Scgd.Ed 105082164e46Schristos.Sh SINGLY LINKED TAIL QUEUES 105182164e46SchristosThe macros prefixed with 10520604df8aSabhinav.Do Nm STAILQ_ Dc ( 10530604df8aSabhinav.Fn STAILQ_HEAD , 10540604df8aSabhinav.Fn STAILQ_HEAD_INITIALIZER , 10550604df8aSabhinav.Fn STAILQ_ENTRY , 10560604df8aSabhinav.Fn STAILQ_FOREACH , 10570604df8aSabhinav.Fn STAILQ_FOREACH_SAFE , 10580604df8aSabhinav.Fn STAILQ_FIRST , 10590604df8aSabhinav.Fn STAILQ_EMPTY , 10600604df8aSabhinav.Fn STAILQ_NEXT , 10610604df8aSabhinav.Fn STAILQ_LAST , 10620604df8aSabhinav.Fn STAILQ_INIT , 10630604df8aSabhinav.Fn STAILQ_INSERT_HEAD , 10640604df8aSabhinav.Fn STAILQ_INSERT_TAIL , 10650604df8aSabhinav.Fn STAILQ_INSERT_AFTER , 10660604df8aSabhinav.Fn STAILQ_REMOVE_HEAD , 10670604df8aSabhinav.Fn STAILQ_REMOVE , 106882164e46Schristosand 10690604df8aSabhinav.Fn STAILQ_CONCAT ) 107082164e46Schristosare functionally identical to these simple queue functions, 107182164e46Schristosand are provided for compatibility with 107282164e46Schristos.Fx . 10733fa869bcSapb.Sh NOTES 10743fa869bcSapbSome of these macros or functions perform no error checking, 10753fa869bcSapband invalid usage leads to undefined behaviour. 10763fa869bcSapbIn the case of macros or functions that expect their arguments 10773fa869bcSapbto be elements that are present in the list or queue, passing an element 10783fa869bcSapbthat is not present is invalid. 1079630651b7Scgd.Sh HISTORY 1080630651b7ScgdThe 1081630651b7Scgd.Nm queue 108234a98169Sperryfunctions first appeared in 108334a98169Sperry.Bx 4.4 . 108468727e36SchristosThe 108568727e36Schristos.Nm SIMPLEQ 108668727e36Schristosfunctions first appeared in 108768727e36Schristos.Nx 1.2 . 1088d729cba0SpookaThe 1089d729cba0Spooka.Nm SLIST 10902f6ed1a8Slukemand 10912f6ed1a8Slukem.Nm STAILQ 1092d729cba0Spookafunctions first appeared in 1093d729cba0Spooka.Fx 2.1.5 . 1094*7ba76359Skamil.Pp 1095*7ba76359SkamilThe 1096*7ba76359Skamil.Nm CIRCLEQ 1097*7ba76359Skamilfunctions first appeared in 1098*7ba76359Skamil.Bx 4.4 1099*7ba76359Skamiland were deprecated in 1100*7ba76359Skamil.Nx 7 1101*7ba76359Skamiland removed in 1102*7ba76359Skamil.Nx 10 1103*7ba76359Skamildue to the pointer aliasing violations. 1104