1afe61c15SRodney W. Grimes.\" Copyright (c) 1993 2afe61c15SRodney W. Grimes.\" The Regents of the University of California. All rights reserved. 3afe61c15SRodney W. Grimes.\" 4afe61c15SRodney W. Grimes.\" Redistribution and use in source and binary forms, with or without 5afe61c15SRodney W. Grimes.\" modification, are permitted provided that the following conditions 6afe61c15SRodney W. Grimes.\" are met: 7afe61c15SRodney W. Grimes.\" 1. Redistributions of source code must retain the above copyright 8afe61c15SRodney W. Grimes.\" notice, this list of conditions and the following disclaimer. 9afe61c15SRodney W. Grimes.\" 2. Redistributions in binary form must reproduce the above copyright 10afe61c15SRodney W. Grimes.\" notice, this list of conditions and the following disclaimer in the 11afe61c15SRodney W. Grimes.\" documentation and/or other materials provided with the distribution. 12afe61c15SRodney W. Grimes.\" 3. All advertising materials mentioning features or use of this software 13afe61c15SRodney W. Grimes.\" must display the following acknowledgement: 14afe61c15SRodney W. Grimes.\" This product includes software developed by the University of 15afe61c15SRodney W. Grimes.\" California, Berkeley and its contributors. 16afe61c15SRodney W. Grimes.\" 4. Neither the name of the University nor the names of its contributors 17afe61c15SRodney W. Grimes.\" may be used to endorse or promote products derived from this software 18afe61c15SRodney W. Grimes.\" without specific prior written permission. 19afe61c15SRodney W. Grimes.\" 20afe61c15SRodney W. Grimes.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21afe61c15SRodney W. Grimes.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22afe61c15SRodney W. Grimes.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23afe61c15SRodney W. Grimes.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24afe61c15SRodney W. Grimes.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25afe61c15SRodney W. Grimes.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26afe61c15SRodney W. Grimes.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27afe61c15SRodney W. Grimes.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28afe61c15SRodney W. Grimes.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29afe61c15SRodney W. Grimes.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30afe61c15SRodney W. Grimes.\" SUCH DAMAGE. 31afe61c15SRodney W. Grimes.\" 32afe61c15SRodney W. Grimes.\" @(#)queue.3 8.2 (Berkeley) 1/24/94 33afe61c15SRodney W. Grimes.\" 34afe61c15SRodney W. Grimes.Dd "January 24, 1994" 35afe61c15SRodney W. Grimes.Dt QUEUE 3 36afe61c15SRodney W. Grimes.Os BSD 4 37afe61c15SRodney W. Grimes.Sh NAME 38afe61c15SRodney W. Grimes.Nm LIST_ENTRY , 39afe61c15SRodney W. Grimes.Nm LIST_HEAD , 40afe61c15SRodney W. Grimes.Nm LIST_INIT , 41afe61c15SRodney W. Grimes.Nm LIST_INSERT_AFTER , 427658b0a2SJustin T. Gibbs.Nm LIST_INSERT_BEFORE , 43afe61c15SRodney W. Grimes.Nm LIST_INSERT_HEAD , 44afe61c15SRodney W. Grimes.Nm LIST_REMOVE , 45afe61c15SRodney W. Grimes.Nm TAILQ_ENTRY , 46afe61c15SRodney W. Grimes.Nm TAILQ_HEAD , 47afe61c15SRodney W. Grimes.Nm TAILQ_INIT , 48afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_AFTER , 497658b0a2SJustin T. Gibbs.Nm TAILQ_INSERT_BEFORE , 50afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_HEAD , 51afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_TAIL , 52afe61c15SRodney W. Grimes.Nm TAILQ_REMOVE , 53afe61c15SRodney W. Grimes.Nm CIRCLEQ_ENTRY , 54afe61c15SRodney W. Grimes.Nm CIRCLEQ_HEAD , 55afe61c15SRodney W. Grimes.Nm CIRCLEQ_INIT , 56afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_AFTER , 57afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_BEFORE , 58afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_HEAD , 59afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_TAIL , 60afe61c15SRodney W. Grimes.Nm CIRCLEQ_REMOVE 61afe61c15SRodney W. Grimes.Nd implementations of lists, tail queues, and circular queues 62afe61c15SRodney W. Grimes.Sh SYNOPSIS 63afe61c15SRodney W. Grimes.Fd #include <sys/queue.h> 64afe61c15SRodney W. Grimes.sp 65afe61c15SRodney W. Grimes.Fn LIST_ENTRY "TYPE" 66afe61c15SRodney W. Grimes.Fn LIST_HEAD "HEADNAME" "TYPE" 67afe61c15SRodney W. Grimes.Fn LIST_INIT "LIST_HEAD *head" 68afe61c15SRodney W. Grimes.Fn LIST_INSERT_AFTER "LIST_ENTRY *listelm" "TYPE *elm" "LIST_ENTRY NAME" 697658b0a2SJustin T. Gibbs.Fn LIST_INSERT_BEFORE "LIST_ENTRY *listelm" "TYPE *elm" "LIST_ENTRY NAME" 70afe61c15SRodney W. Grimes.Fn LIST_INSERT_HEAD "LIST_HEAD *head" "TYPE *elm" "LIST_ENTRY NAME" 71afe61c15SRodney W. Grimes.Fn LIST_REMOVE "TYPE *elm" "LIST_ENTRY NAME" 72afe61c15SRodney W. Grimes.sp 73afe61c15SRodney W. Grimes.Fn TAILQ_ENTRY "TYPE" 74afe61c15SRodney W. Grimes.Fn TAILQ_HEAD "HEADNAME" "TYPE" 75afe61c15SRodney W. Grimes.Fn TAILQ_INIT "TAILQ_HEAD *head" 76afe61c15SRodney W. Grimes.Fn TAILQ_INSERT_AFTER "TAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME" 773652ff55SJustin T. Gibbs.Fn TAILQ_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME" 78afe61c15SRodney W. Grimes.Fn TAILQ_INSERT_HEAD "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME" 79afe61c15SRodney W. Grimes.Fn TAILQ_INSERT_TAIL "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME" 80afe61c15SRodney W. Grimes.Fn TAILQ_REMOVE "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME" 81afe61c15SRodney W. Grimes.sp 82afe61c15SRodney W. Grimes.Fn CIRCLEQ_ENTRY "TYPE" 83afe61c15SRodney W. Grimes.Fn CIRCLEQ_HEAD "HEADNAME" "TYPE" 84afe61c15SRodney W. Grimes.Fn CIRCLEQ_INIT "CIRCLEQ_HEAD *head" 85afe61c15SRodney W. Grimes.Fn CIRCLEQ_INSERT_AFTER "CIRCLEQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "CIRCLEQ_ENTRY NAME" 86afe61c15SRodney W. Grimes.Fn CIRCLEQ_INSERT_BEFORE "CIRCLEQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "CIRCLEQ_ENTRY NAME" 87afe61c15SRodney W. Grimes.Fn CIRCLEQ_INSERT_HEAD "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME" 88afe61c15SRodney W. Grimes.Fn CIRCLEQ_INSERT_TAIL "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME" 89afe61c15SRodney W. Grimes.Fn CIRCLEQ_REMOVE "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME" 90afe61c15SRodney W. Grimes.Sh DESCRIPTION 91afe61c15SRodney W. GrimesThese macros define and operate on three types of data structures: 92afe61c15SRodney W. Grimeslists, tail queues, and circular queues. 93afe61c15SRodney W. GrimesAll three structures support the following functionality: 94afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent 95afe61c15SRodney W. Grimes.It 96afe61c15SRodney W. GrimesInsertion of a new entry at the head of the list. 97afe61c15SRodney W. Grimes.It 98afe61c15SRodney W. GrimesInsertion of a new entry after any element in the list. 99afe61c15SRodney W. Grimes.It 1007658b0a2SJustin T. GibbsInsertion of a new entry before any element in the list. 1017658b0a2SJustin T. Gibbs.It 102afe61c15SRodney W. GrimesRemoval of any entry in the list. 103afe61c15SRodney W. Grimes.It 104afe61c15SRodney W. GrimesForward traversal through the list. 105afe61c15SRodney W. Grimes.El 106afe61c15SRodney W. Grimes.Pp 107afe61c15SRodney W. GrimesLists are the simplest of the three data structures and support 108afe61c15SRodney W. Grimesonly the above functionality. 109afe61c15SRodney W. Grimes.Pp 110afe61c15SRodney W. GrimesTail queues add the following functionality: 111afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent 112afe61c15SRodney W. Grimes.It 113afe61c15SRodney W. GrimesEntries can be added at the end of a list. 114afe61c15SRodney W. Grimes.El 115afe61c15SRodney W. GrimesHowever: 116afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent 117afe61c15SRodney W. Grimes.It 118afe61c15SRodney W. GrimesAll list insertions and removals must specify the head of the list. 119afe61c15SRodney W. Grimes.It 120afe61c15SRodney W. GrimesEach head entry requires two pointers rather than one. 121afe61c15SRodney W. Grimes.It 122afe61c15SRodney W. GrimesCode size is about 15% greater and operations run about 20% slower 123afe61c15SRodney W. Grimesthan lists. 124afe61c15SRodney W. Grimes.El 125afe61c15SRodney W. Grimes.Pp 126afe61c15SRodney W. GrimesCircular queues add the following functionality: 127afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent 128afe61c15SRodney W. Grimes.It 129afe61c15SRodney W. GrimesEntries can be added at the end of a list. 130afe61c15SRodney W. Grimes.It 131afe61c15SRodney W. GrimesThey may be traversed backwards, from tail to head. 132afe61c15SRodney W. Grimes.El 133afe61c15SRodney W. GrimesHowever: 134afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent 135afe61c15SRodney W. Grimes.It 136afe61c15SRodney W. GrimesAll list insertions and removals must specify the head of the list. 137afe61c15SRodney W. Grimes.It 138afe61c15SRodney W. GrimesEach head entry requires two pointers rather than one. 139afe61c15SRodney W. Grimes.It 140afe61c15SRodney W. GrimesThe termination condition for traversal is more complex. 141afe61c15SRodney W. Grimes.It 142afe61c15SRodney W. GrimesCode size is about 40% greater and operations run about 45% slower 143afe61c15SRodney W. Grimesthan lists. 144afe61c15SRodney W. Grimes.El 145afe61c15SRodney W. Grimes.Pp 146afe61c15SRodney W. GrimesIn the macro definitions, 147afe61c15SRodney W. Grimes.Fa TYPE 148afe61c15SRodney W. Grimesis the name of a user defined structure, 149afe61c15SRodney W. Grimesthat must contain a field of type 150afe61c15SRodney W. Grimes.Li LIST_ENTRY , 151afe61c15SRodney W. Grimes.Li TAILQ_ENTRY , 152afe61c15SRodney W. Grimesor 153afe61c15SRodney W. Grimes.Li CIRCLEQ_ENTRY , 154afe61c15SRodney W. Grimesnamed 155afe61c15SRodney W. Grimes.Fa NAME . 156afe61c15SRodney W. GrimesThe argument 157afe61c15SRodney W. Grimes.Fa HEADNAME 158afe61c15SRodney W. Grimesis the name of a user defined structure that must be declared 159afe61c15SRodney W. Grimesusing the macros 160afe61c15SRodney W. Grimes.Li LIST_HEAD , 161afe61c15SRodney W. Grimes.Li TAILQ_HEAD , 162afe61c15SRodney W. Grimesor 163afe61c15SRodney W. Grimes.Li CIRCLEQ_HEAD . 164afe61c15SRodney W. GrimesSee the examples below for further explanation of how these 165afe61c15SRodney W. Grimesmacros are used. 166afe61c15SRodney W. Grimes.Sh LISTS 167afe61c15SRodney W. GrimesA list is headed by a structure defined by the 168afe61c15SRodney W. Grimes.Nm LIST_HEAD 169afe61c15SRodney W. Grimesmacro. 170afe61c15SRodney W. GrimesThis structure contains a single pointer to the first element 171afe61c15SRodney W. Grimeson the list. 172afe61c15SRodney W. GrimesThe elements are doubly linked so that an arbitrary element can be 173afe61c15SRodney W. Grimesremoved without traversing the list. 174afe61c15SRodney W. GrimesNew elements can be added to the list after an existing element or 175afe61c15SRodney W. Grimesat the head of the list. 176afe61c15SRodney W. GrimesA 177afe61c15SRodney W. Grimes.Fa LIST_HEAD 178afe61c15SRodney W. Grimesstructure is declared as follows: 179afe61c15SRodney W. Grimes.Bd -literal -offset indent 180afe61c15SRodney W. GrimesLIST_HEAD(HEADNAME, TYPE) head; 181afe61c15SRodney W. Grimes.Ed 182afe61c15SRodney W. Grimes.sp 183afe61c15SRodney W. Grimeswhere 184afe61c15SRodney W. Grimes.Fa HEADNAME 185afe61c15SRodney W. Grimesis the name of the structure to be defined, and 186afe61c15SRodney W. Grimes.Fa TYPE 187afe61c15SRodney W. Grimesis the type of the elements to be linked into the list. 188afe61c15SRodney W. GrimesA pointer to the head of the list can later be declared as: 189afe61c15SRodney W. Grimes.Bd -literal -offset indent 190afe61c15SRodney W. Grimesstruct HEADNAME *headp; 191afe61c15SRodney W. Grimes.Ed 192afe61c15SRodney W. Grimes.sp 193afe61c15SRodney W. Grimes(The names 194afe61c15SRodney W. Grimes.Li head 195afe61c15SRodney W. Grimesand 196afe61c15SRodney W. Grimes.Li headp 197afe61c15SRodney W. Grimesare user selectable.) 198afe61c15SRodney W. Grimes.Pp 199afe61c15SRodney W. GrimesThe macro 200afe61c15SRodney W. Grimes.Nm LIST_ENTRY 201afe61c15SRodney W. Grimesdeclares a structure that connects the elements in 202afe61c15SRodney W. Grimesthe list. 203afe61c15SRodney W. Grimes.Pp 204afe61c15SRodney W. GrimesThe macro 205afe61c15SRodney W. Grimes.Nm LIST_INIT 206afe61c15SRodney W. Grimesinitializes the list referenced by 207afe61c15SRodney W. Grimes.Fa head . 208afe61c15SRodney W. Grimes.Pp 209afe61c15SRodney W. GrimesThe macro 210afe61c15SRodney W. Grimes.Nm LIST_INSERT_HEAD 211afe61c15SRodney W. Grimesinserts the new element 212afe61c15SRodney W. Grimes.Fa elm 213afe61c15SRodney W. Grimesat the head of the list. 214afe61c15SRodney W. Grimes.Pp 215afe61c15SRodney W. GrimesThe macro 216afe61c15SRodney W. Grimes.Nm LIST_INSERT_AFTER 217afe61c15SRodney W. Grimesinserts the new element 218afe61c15SRodney W. Grimes.Fa elm 219afe61c15SRodney W. Grimesafter the element 220afe61c15SRodney W. Grimes.Fa listelm . 221afe61c15SRodney W. Grimes.Pp 222afe61c15SRodney W. GrimesThe macro 2237658b0a2SJustin T. Gibbs.Nm LIST_INSERT_BEFORE 2247658b0a2SJustin T. Gibbsinserts the new element 2257658b0a2SJustin T. Gibbs.Fa elm 2267658b0a2SJustin T. Gibbsbefore the element 2277658b0a2SJustin T. Gibbs.Fa listelm . 2287658b0a2SJustin T. Gibbs.Pp 2297658b0a2SJustin T. GibbsThe macro 230afe61c15SRodney W. Grimes.Nm LIST_REMOVE 231afe61c15SRodney W. Grimesremoves the element 232afe61c15SRodney W. Grimes.Fa elm 233afe61c15SRodney W. Grimesfrom the list. 234afe61c15SRodney W. Grimes.Sh LIST EXAMPLE 235afe61c15SRodney W. Grimes.Bd -literal 236afe61c15SRodney W. GrimesLIST_HEAD(listhead, entry) head; 237afe61c15SRodney W. Grimesstruct listhead *headp; /* List head. */ 238afe61c15SRodney W. Grimesstruct entry { 239afe61c15SRodney W. Grimes ... 240afe61c15SRodney W. Grimes LIST_ENTRY(entry) entries; /* List. */ 241afe61c15SRodney W. Grimes ... 2427658b0a2SJustin T. Gibbs} *n1, *n2, *n3, *np; 243afe61c15SRodney W. Grimes 244afe61c15SRodney W. GrimesLIST_INIT(&head); /* Initialize the list. */ 245afe61c15SRodney W. Grimes 246afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry)); /* Insert at the head. */ 247afe61c15SRodney W. GrimesLIST_INSERT_HEAD(&head, n1, entries); 248afe61c15SRodney W. Grimes 249afe61c15SRodney W. Grimesn2 = malloc(sizeof(struct entry)); /* Insert after. */ 250afe61c15SRodney W. GrimesLIST_INSERT_AFTER(n1, n2, entries); 2517658b0a2SJustin T. Gibbs 2527658b0a2SJustin T. Gibbsn3 = malloc(sizeof(struct entry)); /* Insert before. */ 2537658b0a2SJustin T. GibbsLIST_INSERT_BEFORE(n2, n3, entries); 2547658b0a2SJustin T. Gibbs 2557658b0a2SJustin T. GibbsLIST_REMOVE(n2, entries); /* Deletion. */ 2567658b0a2SJustin T. Gibbsfree(n2); 2577658b0a2SJustin T. Gibbs 258afe61c15SRodney W. Grimes /* Forward traversal. */ 259afe61c15SRodney W. Grimesfor (np = head.lh_first; np != NULL; np = np->entries.le_next) 260afe61c15SRodney W. Grimes np-> ... 261afe61c15SRodney W. Grimes 2627658b0a2SJustin T. Gibbswhile (head.lh_first != NULL) { /* List Deletion. */ 2637658b0a2SJustin T. Gibbs n1 = head.lh_first; 2647658b0a2SJustin T. Gibbs LIST_REMOVE(n1, entries); 2657658b0a2SJustin T. Gibbs free(n1); 2667658b0a2SJustin T. Gibbs} 2677658b0a2SJustin T. Gibbs 2687658b0a2SJustin T. Gibbsn1 = head.lh_first; /* Faster List Delete. */ 2697658b0a2SJustin T. Gibbswhile (n1 != NULL) { 2707658b0a2SJustin T. Gibbs n2 = n1->entires.le_next; 2717658b0a2SJustin T. Gibbs free(n1); 2727658b0a2SJustin T. Gibbs n1 = n2; 2737658b0a2SJustin T. Gibbs} 2747658b0a2SJustin T. GibbsLIST_INIT(&head); 2757658b0a2SJustin T. Gibbs 276afe61c15SRodney W. Grimes.Ed 277afe61c15SRodney W. Grimes.Sh TAIL QUEUES 278afe61c15SRodney W. GrimesA tail queue is headed by a structure defined by the 279afe61c15SRodney W. Grimes.Nm TAILQ_HEAD 280afe61c15SRodney W. Grimesmacro. 281afe61c15SRodney W. GrimesThis structure contains a pair of pointers, 282afe61c15SRodney W. Grimesone to the first element in the tail queue and the other to 283afe61c15SRodney W. Grimesthe last element in the tail queue. 284afe61c15SRodney W. GrimesThe elements are doubly linked so that an arbitrary element can be 285afe61c15SRodney W. Grimesremoved without traversing the tail queue. 286afe61c15SRodney W. GrimesNew elements can be added to the tail queue after an existing element, 287afe61c15SRodney W. Grimesat the head of the tail queue, or at the end of the tail queue. 288afe61c15SRodney W. GrimesA 289afe61c15SRodney W. Grimes.Fa TAILQ_HEAD 290afe61c15SRodney W. Grimesstructure is declared as follows: 291afe61c15SRodney W. Grimes.Bd -literal -offset indent 292afe61c15SRodney W. GrimesTAILQ_HEAD(HEADNAME, TYPE) head; 293afe61c15SRodney W. Grimes.Ed 294afe61c15SRodney W. Grimes.sp 295afe61c15SRodney W. Grimeswhere 296afe61c15SRodney W. Grimes.Li HEADNAME 297afe61c15SRodney W. Grimesis the name of the structure to be defined, and 298afe61c15SRodney W. Grimes.Li TYPE 299afe61c15SRodney W. Grimesis the type of the elements to be linked into the tail queue. 300afe61c15SRodney W. GrimesA pointer to the head of the tail queue can later be declared as: 301afe61c15SRodney W. Grimes.Bd -literal -offset indent 302afe61c15SRodney W. Grimesstruct HEADNAME *headp; 303afe61c15SRodney W. Grimes.Ed 304afe61c15SRodney W. Grimes.sp 305afe61c15SRodney W. Grimes(The names 306afe61c15SRodney W. Grimes.Li head 307afe61c15SRodney W. Grimesand 308afe61c15SRodney W. Grimes.Li headp 309afe61c15SRodney W. Grimesare user selectable.) 310afe61c15SRodney W. Grimes.Pp 311afe61c15SRodney W. GrimesThe macro 312afe61c15SRodney W. Grimes.Nm TAILQ_ENTRY 313afe61c15SRodney W. Grimesdeclares a structure that connects the elements in 314afe61c15SRodney W. Grimesthe tail queue. 315afe61c15SRodney W. Grimes.Pp 316afe61c15SRodney W. GrimesThe macro 317afe61c15SRodney W. Grimes.Nm TAILQ_INIT 318afe61c15SRodney W. Grimesinitializes the tail queue referenced by 319afe61c15SRodney W. Grimes.Fa head . 320afe61c15SRodney W. Grimes.Pp 321afe61c15SRodney W. GrimesThe macro 322afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_HEAD 323afe61c15SRodney W. Grimesinserts the new element 324afe61c15SRodney W. Grimes.Fa elm 325afe61c15SRodney W. Grimesat the head of the tail queue. 326afe61c15SRodney W. Grimes.Pp 327afe61c15SRodney W. GrimesThe macro 328afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_TAIL 329afe61c15SRodney W. Grimesinserts the new element 330afe61c15SRodney W. Grimes.Fa elm 331afe61c15SRodney W. Grimesat the end of the tail queue. 332afe61c15SRodney W. Grimes.Pp 333afe61c15SRodney W. GrimesThe macro 334afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_AFTER 335afe61c15SRodney W. Grimesinserts the new element 336afe61c15SRodney W. Grimes.Fa elm 337afe61c15SRodney W. Grimesafter the element 338afe61c15SRodney W. Grimes.Fa listelm . 339afe61c15SRodney W. Grimes.Pp 340afe61c15SRodney W. GrimesThe macro 3417658b0a2SJustin T. Gibbs.Nm TAILQ_INSERT_BEFORE 3427658b0a2SJustin T. Gibbsinserts the new element 3437658b0a2SJustin T. Gibbs.Fa elm 3447658b0a2SJustin T. Gibbsbefore the element 3457658b0a2SJustin T. Gibbs.Fa listelm . 3467658b0a2SJustin T. Gibbs.Pp 3477658b0a2SJustin T. GibbsThe macro 348afe61c15SRodney W. Grimes.Nm TAILQ_REMOVE 349afe61c15SRodney W. Grimesremoves the element 350afe61c15SRodney W. Grimes.Fa elm 351afe61c15SRodney W. Grimesfrom the tail queue. 352afe61c15SRodney W. Grimes.Sh TAIL QUEUE EXAMPLE 353afe61c15SRodney W. Grimes.Bd -literal 354afe61c15SRodney W. GrimesTAILQ_HEAD(tailhead, entry) head; 355afe61c15SRodney W. Grimesstruct tailhead *headp; /* Tail queue head. */ 356afe61c15SRodney W. Grimesstruct entry { 357afe61c15SRodney W. Grimes ... 358afe61c15SRodney W. Grimes TAILQ_ENTRY(entry) entries; /* Tail queue. */ 359afe61c15SRodney W. Grimes ... 3607658b0a2SJustin T. Gibbs} *n1, *n2, *n3, *np; 361afe61c15SRodney W. Grimes 362afe61c15SRodney W. GrimesTAILQ_INIT(&head); /* Initialize the queue. */ 363afe61c15SRodney W. Grimes 364afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry)); /* Insert at the head. */ 365afe61c15SRodney W. GrimesTAILQ_INSERT_HEAD(&head, n1, entries); 366afe61c15SRodney W. Grimes 367afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry)); /* Insert at the tail. */ 368afe61c15SRodney W. GrimesTAILQ_INSERT_TAIL(&head, n1, entries); 369afe61c15SRodney W. Grimes 370afe61c15SRodney W. Grimesn2 = malloc(sizeof(struct entry)); /* Insert after. */ 371afe61c15SRodney W. GrimesTAILQ_INSERT_AFTER(&head, n1, n2, entries); 3727658b0a2SJustin T. Gibbs 3737658b0a2SJustin T. Gibbsn3 = malloc(sizeof(struct entry)); /* Insert before. */ 3743652ff55SJustin T. GibbsTAILQ_INSERT_BEFORE(n2, n3, entries); 3757658b0a2SJustin T. Gibbs 3767658b0a2SJustin T. GibbsTAILQ_REMOVE(&head, n2, entries); /* Deletion. */ 3777658b0a2SJustin T. Gibbsfree(n2); 378afe61c15SRodney W. Grimes /* Forward traversal. */ 379afe61c15SRodney W. Grimesfor (np = head.tqh_first; np != NULL; np = np->entries.tqe_next) 380afe61c15SRodney W. Grimes np-> ... 3817658b0a2SJustin T. Gibbs /* TailQ Deletion. */ 3827658b0a2SJustin T. Gibbswhile (head.tqh_first != NULL) { 3837658b0a2SJustin T. Gibbs n1 = head.tqh_first; 384afe61c15SRodney W. Grimes TAILQ_REMOVE(&head, head.tqh_first, entries); 3857658b0a2SJustin T. Gibbs free(n1); 3867658b0a2SJustin T. Gibbs} 3877658b0a2SJustin T. Gibbs /* Faster TailQ Deletion. */ 3887658b0a2SJustin T. Gibbsn1 = head.tqh_first; 3897658b0a2SJustin T. Gibbswhile (n1 != NULL) { 3907658b0a2SJustin T. Gibbs n2 = n1->entries.tqe_next; 3917658b0a2SJustin T. Gibbs free(n1); 3927658b0a2SJustin T. Gibbs n1 = n2; 3937658b0a2SJustin T. Gibbs} 3947658b0a2SJustin T. GibbsTAILQ_INIT(&head); 395afe61c15SRodney W. Grimes.Ed 396afe61c15SRodney W. Grimes.Sh CIRCULAR QUEUES 397afe61c15SRodney W. GrimesA circular queue is headed by a structure defined by the 398afe61c15SRodney W. Grimes.Nm CIRCLEQ_HEAD 399afe61c15SRodney W. Grimesmacro. 400afe61c15SRodney W. GrimesThis structure contains a pair of pointers, 401afe61c15SRodney W. Grimesone to the first element in the circular queue and the other to the 402afe61c15SRodney W. Grimeslast element in the circular queue. 403afe61c15SRodney W. GrimesThe elements are doubly linked so that an arbitrary element can be 404afe61c15SRodney W. Grimesremoved without traversing the queue. 405afe61c15SRodney W. GrimesNew elements can be added to the queue after an existing element, 406afe61c15SRodney W. Grimesbefore an existing element, at the head of the queue, or at the end 407afe61c15SRodney W. Grimesof the queue. 408afe61c15SRodney W. GrimesA 409afe61c15SRodney W. Grimes.Fa CIRCLEQ_HEAD 410afe61c15SRodney W. Grimesstructure is declared as follows: 411afe61c15SRodney W. Grimes.Bd -literal -offset indent 412afe61c15SRodney W. GrimesCIRCLEQ_HEAD(HEADNAME, TYPE) head; 413afe61c15SRodney W. Grimes.Ed 414afe61c15SRodney W. Grimes.sp 415afe61c15SRodney W. Grimeswhere 416afe61c15SRodney W. Grimes.Li HEADNAME 417afe61c15SRodney W. Grimesis the name of the structure to be defined, and 418afe61c15SRodney W. Grimes.Li TYPE 419afe61c15SRodney W. Grimesis the type of the elements to be linked into the circular queue. 420afe61c15SRodney W. GrimesA pointer to the head of the circular queue can later be declared as: 421afe61c15SRodney W. Grimes.Bd -literal -offset indent 422afe61c15SRodney W. Grimesstruct HEADNAME *headp; 423afe61c15SRodney W. Grimes.Ed 424afe61c15SRodney W. Grimes.sp 425afe61c15SRodney W. Grimes(The names 426afe61c15SRodney W. Grimes.Li head 427afe61c15SRodney W. Grimesand 428afe61c15SRodney W. Grimes.Li headp 429afe61c15SRodney W. Grimesare user selectable.) 430afe61c15SRodney W. Grimes.Pp 431afe61c15SRodney W. GrimesThe macro 432afe61c15SRodney W. Grimes.Nm CIRCLEQ_ENTRY 433afe61c15SRodney W. Grimesdeclares a structure that connects the elements in 434afe61c15SRodney W. Grimesthe circular queue. 435afe61c15SRodney W. Grimes.Pp 436afe61c15SRodney W. GrimesThe macro 437afe61c15SRodney W. Grimes.Nm CIRCLEQ_INIT 438afe61c15SRodney W. Grimesinitializes the circular queue referenced by 439afe61c15SRodney W. Grimes.Fa head . 440afe61c15SRodney W. Grimes.Pp 441afe61c15SRodney W. GrimesThe macro 442afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_HEAD 443afe61c15SRodney W. Grimesinserts the new element 444afe61c15SRodney W. Grimes.Fa elm 445afe61c15SRodney W. Grimesat the head of the circular queue. 446afe61c15SRodney W. Grimes.Pp 447afe61c15SRodney W. GrimesThe macro 448afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_TAIL 449afe61c15SRodney W. Grimesinserts the new element 450afe61c15SRodney W. Grimes.Fa elm 451afe61c15SRodney W. Grimesat the end of the circular queue. 452afe61c15SRodney W. Grimes.Pp 453afe61c15SRodney W. GrimesThe macro 454afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_AFTER 455afe61c15SRodney W. Grimesinserts the new element 456afe61c15SRodney W. Grimes.Fa elm 457afe61c15SRodney W. Grimesafter the element 458afe61c15SRodney W. Grimes.Fa listelm . 459afe61c15SRodney W. Grimes.Pp 460afe61c15SRodney W. GrimesThe macro 461afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_BEFORE 462afe61c15SRodney W. Grimesinserts the new element 463afe61c15SRodney W. Grimes.Fa elm 464afe61c15SRodney W. Grimesbefore the element 465afe61c15SRodney W. Grimes.Fa listelm . 466afe61c15SRodney W. Grimes.Pp 467afe61c15SRodney W. GrimesThe macro 468afe61c15SRodney W. Grimes.Nm CIRCLEQ_REMOVE 469afe61c15SRodney W. Grimesremoves the element 470afe61c15SRodney W. Grimes.Fa elm 471afe61c15SRodney W. Grimesfrom the circular queue. 472afe61c15SRodney W. Grimes.Sh CIRCULAR QUEUE EXAMPLE 473afe61c15SRodney W. Grimes.Bd -literal 474afe61c15SRodney W. GrimesCIRCLEQ_HEAD(circleq, entry) head; 475afe61c15SRodney W. Grimesstruct circleq *headp; /* Circular queue head. */ 476afe61c15SRodney W. Grimesstruct entry { 477afe61c15SRodney W. Grimes ... 478afe61c15SRodney W. Grimes CIRCLEQ_ENTRY entries; /* Circular queue. */ 479afe61c15SRodney W. Grimes ... 480afe61c15SRodney W. Grimes} *n1, *n2, *np; 481afe61c15SRodney W. Grimes 482afe61c15SRodney W. GrimesCIRCLEQ_INIT(&head); /* Initialize the circular queue. */ 483afe61c15SRodney W. Grimes 484afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry)); /* Insert at the head. */ 485afe61c15SRodney W. GrimesCIRCLEQ_INSERT_HEAD(&head, n1, entries); 486afe61c15SRodney W. Grimes 487afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry)); /* Insert at the tail. */ 488afe61c15SRodney W. GrimesCIRCLEQ_INSERT_TAIL(&head, n1, entries); 489afe61c15SRodney W. Grimes 490afe61c15SRodney W. Grimesn2 = malloc(sizeof(struct entry)); /* Insert after. */ 491afe61c15SRodney W. GrimesCIRCLEQ_INSERT_AFTER(&head, n1, n2, entries); 492afe61c15SRodney W. Grimes 493afe61c15SRodney W. Grimesn2 = malloc(sizeof(struct entry)); /* Insert before. */ 494afe61c15SRodney W. GrimesCIRCLEQ_INSERT_BEFORE(&head, n1, n2, entries); 4957658b0a2SJustin T. Gibbs 4967658b0a2SJustin T. GibbsCIRCLEQ_REMOVE(&head, n1, entries); /* Deletion. */ 4977658b0a2SJustin T. Gibbsfree(n1); 498afe61c15SRodney W. Grimes /* Forward traversal. */ 499afe61c15SRodney W. Grimesfor (np = head.cqh_first; np != (void *)&head; np = np->entries.cqe_next) 500afe61c15SRodney W. Grimes np-> ... 501afe61c15SRodney W. Grimes /* Reverse traversal. */ 502afe61c15SRodney W. Grimesfor (np = head.cqh_last; np != (void *)&head; np = np->entries.cqe_prev) 503afe61c15SRodney W. Grimes np-> ... 5047658b0a2SJustin T. Gibbs /* CircleQ Deletion. */ 5057658b0a2SJustin T. Gibbswhile (head.cqh_first != (void *)&head) { 5067658b0a2SJustin T. Gibbs n1 = head.cqh_first; 507afe61c15SRodney W. Grimes CIRCLEQ_REMOVE(&head, head.cqh_first, entries); 5087658b0a2SJustin T. Gibbs free(n1); 5097658b0a2SJustin T. Gibbs} 5107658b0a2SJustin T. Gibbs /* Faster CircleQ Deletion. */ 5117658b0a2SJustin T. Gibbsn1 = head.cqh_first; 5127658b0a2SJustin T. Gibbswhile (n1 != (void *)&head) { 5137658b0a2SJustin T. Gibbs n2 = n1->entries.cqh_next; 5147658b0a2SJustin T. Gibbs free(n1); 5157658b0a2SJustin T. Gibbs n1 = n2; 5167658b0a2SJustin T. Gibbs} 5177658b0a2SJustin T. GibbsCIRCLEQ_INIT(&head); 518afe61c15SRodney W. Grimes.Ed 519afe61c15SRodney W. Grimes.Sh HISTORY 520afe61c15SRodney W. GrimesThe 521afe61c15SRodney W. Grimes.Nm queue 522afe61c15SRodney W. Grimesfunctions first appeared in 4.4BSD. 523