1.\" $NetBSD: queue.3,v 1.6 1997/05/29 01:48:39 cgd Exp $ 2.\" 3.\" Copyright (c) 1993 The Regents of the University of California. 4.\" All rights reserved. 5.\" 6.\" Redistribution and use in source and binary forms, with or without 7.\" modification, are permitted provided that the following conditions 8.\" are met: 9.\" 1. Redistributions of source code must retain the above copyright 10.\" notice, this list of conditions and the following disclaimer. 11.\" 2. Redistributions in binary form must reproduce the above copyright 12.\" notice, this list of conditions and the following disclaimer in the 13.\" documentation and/or other materials provided with the distribution. 14.\" 3. All advertising materials mentioning features or use of this software 15.\" must display the following acknowledgement: 16.\" This product includes software developed by the University of 17.\" California, Berkeley and its contributors. 18.\" 4. Neither the name of the University nor the names of its contributors 19.\" may be used to endorse or promote products derived from this software 20.\" without specific prior written permission. 21.\" 22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32.\" SUCH DAMAGE. 33.\" 34.\" @(#)queue.3 8.1 (Berkeley) 12/13/93 35.\" 36.Dd December 13, 1993 37.Dt QUEUE 3 38.Os BSD 4 39.Sh NAME 40.Nm LIST_ENTRY , 41.Nm LIST_HEAD , 42.Nm LIST_HEAD_INITIALIZER , 43.Nm LIST_INIT , 44.Nm LIST_INSERT_AFTER , 45.Nm LIST_INSERT_BEFORE , 46.Nm LIST_INSERT_HEAD , 47.Nm LIST_REMOVE , 48.Nm TAILQ_ENTRY , 49.Nm TAILQ_HEAD , 50.Nm TAILQ_HEAD_INITIALIZER , 51.Nm TAILQ_INIT , 52.Nm TAILQ_INSERT_AFTER , 53.Nm TAILQ_INSERT_BEFORE , 54.Nm TAILQ_INSERT_HEAD , 55.Nm TAILQ_INSERT_TAIL , 56.Nm TAILQ_REMOVE , 57.Nm CIRCLEQ_ENTRY , 58.Nm CIRCLEQ_HEAD , 59.Nm CIRCLEQ_HEAD_INITIALIZER , 60.Nm CIRCLEQ_INIT , 61.Nm CIRCLEQ_INSERT_AFTER , 62.Nm CIRCLEQ_INSERT_BEFORE , 63.Nm CIRCLEQ_INSERT_HEAD , 64.Nm CIRCLEQ_INSERT_TAIL , 65.Nm CIRCLEQ_REMOVE 66.Nd implementations of lists, tail queues, and circular queues 67.Sh SYNOPSIS 68.Fd #include <sys/queue.h> 69.sp 70.Fn LIST_ENTRY "TYPE" 71.Fn LIST_HEAD "HEADNAME" "TYPE" 72.Fn LIST_HEAD_INITIALIZER "head" 73.Fn LIST_INIT "LIST_HEAD *head" 74.Fn LIST_INSERT_AFTER "TYPE *listelm" "TYPE *elm" "LIST_ENTRY NAME" 75.Fn LIST_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "LIST_ENTRY NAME" 76.Fn LIST_INSERT_HEAD "LIST_HEAD *head" "TYPE *elm" "LIST_ENTRY NAME" 77.Fn LIST_REMOVE "TYPE *elm" "LIST_ENTRY NAME" 78.sp 79.Fn TAILQ_ENTRY "TYPE" 80.Fn TAILQ_HEAD "HEADNAME" "TYPE" 81.Fn TAILQ_HEAD_INITIALIZER "head" 82.Fn TAILQ_INIT "TAILQ_HEAD *head" 83.Fn TAILQ_INSERT_AFTER "TAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME" 84.Fn TAILQ_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME" 85.Fn TAILQ_INSERT_HEAD "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME" 86.Fn TAILQ_INSERT_TAIL "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME" 87.Fn TAILQ_REMOVE "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME" 88.sp 89.Fn CIRCLEQ_ENTRY "TYPE" 90.Fn CIRCLEQ_HEAD "HEADNAME" "TYPE" 91.Fn CIRCLEQ_HEAD_INITIALIZER "head" 92.Fn CIRCLEQ_INIT "CIRCLEQ_HEAD *head" 93.Fn CIRCLEQ_INSERT_AFTER "CIRCLEQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "CIRCLEQ_ENTRY NAME" 94.Fn CIRCLEQ_INSERT_BEFORE "CIRCLEQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "CIRCLEQ_ENTRY NAME" 95.Fn CIRCLEQ_INSERT_HEAD "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME" 96.Fn CIRCLEQ_INSERT_TAIL "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME" 97.Fn CIRCLEQ_REMOVE "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME" 98.Sh DESCRIPTION 99These macros define and operate on three types of data structures: 100lists, tail queues, and circular queues. 101All three structures support the following functionality: 102.Bl -enum -compact -offset indent 103.It 104Insertion of a new entry at the head of the list. 105.It 106Insertion of a new entry before or after any element in the list. 107.It 108Removal of any entry in the list. 109.It 110Forward traversal through the list. 111.El 112.Pp 113Lists are the simplest of the three data structures and support 114only the above functionality. 115.Pp 116Tail queues add the following functionality: 117.Bl -enum -compact -offset indent 118.It 119Entries can be added at the end of a list. 120.El 121However: 122.Bl -enum -compact -offset indent 123.It 124All list insertions and removals, except insertion before another element, must 125specify the head of the list. 126.It 127Each head entry requires two pointers rather than one. 128.It 129Code size is about 15% greater and operations run about 20% slower 130than lists. 131.El 132.Pp 133Circular queues add the following functionality: 134.Bl -enum -compact -offset indent 135.It 136Entries can be added at the end of a list. 137.It 138They may be traversed backwards, from tail to head. 139.El 140However: 141.Bl -enum -compact -offset indent 142.It 143All list insertions and removals must specify the head of the list. 144.It 145Each head entry requires two pointers rather than one. 146.It 147The termination condition for traversal is more complex. 148.It 149Code size is about 40% greater and operations run about 45% slower 150than lists. 151.El 152.Pp 153In the macro definitions, 154.Fa TYPE 155is the name of a user defined structure, 156that must contain a field of type 157.Li LIST_ENTRY , 158.Li TAILQ_ENTRY , 159or 160.Li CIRCLEQ_ENTRY , 161named 162.Fa NAME . 163The argument 164.Fa HEADNAME 165is the name of a user defined structure that must be declared 166using the macros 167.Li LIST_HEAD , 168.Li TAILQ_HEAD , 169or 170.Li CIRCLEQ_HEAD . 171See the examples below for further explanation of how these 172macros are used. 173.Sh LISTS 174A list is headed by a structure defined by the 175.Nm LIST_HEAD 176macro. 177This structure contains a single pointer to the first element 178on the list. 179The elements are doubly linked so that an arbitrary element can be 180removed without traversing the list. 181New elements can be added to the list after an existing element, 182before an existing element, or at the head of the list. 183A 184.Fa LIST_HEAD 185structure is declared as follows: 186.Bd -literal -offset indent 187LIST_HEAD(HEADNAME, TYPE) head; 188.Ed 189.sp 190where 191.Fa HEADNAME 192is the name of the structure to be defined, and 193.Fa TYPE 194is the type of the elements to be linked into the list. 195A pointer to the head of the list can later be declared as: 196.Bd -literal -offset indent 197struct HEADNAME *headp; 198.Ed 199.sp 200(The names 201.Li head 202and 203.Li headp 204are user selectable.) 205.Pp 206The macro 207.Nm LIST_ENTRY 208declares a structure that connects the elements in 209the list. 210.Pp 211The macro 212.Nm LIST_HEAD_INITIALIZER 213provides a value which can be used to initialize a list head at 214compile time, and is used at the point that the list head 215variable is declared, like: 216.Bd -literal -offset indent 217struct HEADNAME head = LIST_HEAD_INITIALIZER(head); 218.Ed 219.Pp 220The macro 221.Nm LIST_INIT 222initializes the list referenced by 223.Fa head . 224.Pp 225The macro 226.Nm LIST_INSERT_HEAD 227inserts the new element 228.Fa elm 229at the head of the list. 230.Pp 231The macro 232.Nm LIST_INSERT_AFTER 233inserts the new element 234.Fa elm 235after the element 236.Fa listelm . 237.Pp 238The macro 239.Nm LIST_INSERT_BEFORE 240inserts the new element 241.Fa elm 242before the element 243.Fa listelm . 244.Pp 245The macro 246.Nm LIST_REMOVE 247removes the element 248.Fa elm 249from the list. 250.Sh LIST EXAMPLE 251.Bd -literal 252LIST_HEAD(listhead, entry) head; 253struct listhead *headp; /* List head. */ 254struct entry { 255 ... 256 LIST_ENTRY(entry) entries; /* List. */ 257 ... 258} *n1, *n2, *np; 259 260LIST_INIT(&head); /* Initialize the list. */ 261 262n1 = malloc(sizeof(struct entry)); /* Insert at the head. */ 263LIST_INSERT_HEAD(&head, n1, entries); 264 265n2 = malloc(sizeof(struct entry)); /* Insert after. */ 266LIST_INSERT_AFTER(n1, n2, entries); 267 268n2 = malloc(sizeof(struct entry)); /* Insert before. */ 269LIST_INSERT_BEFORE(n1, n2, entries); 270 /* Forward traversal. */ 271for (np = head.lh_first; np != NULL; np = np->entries.le_next) 272 np-> ... 273 274while (head.lh_first != NULL) /* Delete. */ 275 LIST_REMOVE(head.lh_first, entries); 276.Ed 277.Sh TAIL QUEUES 278A tail queue is headed by a structure defined by the 279.Nm TAILQ_HEAD 280macro. 281This structure contains a pair of pointers, 282one to the first element in the tail queue and the other to 283the last element in the tail queue. 284The elements are doubly linked so that an arbitrary element can be 285removed without traversing the tail queue. 286New elements can be added to the queue after an existing element, 287before an existing element, at the head of the queue, or at the end 288the queue. 289A 290.Fa TAILQ_HEAD 291structure is declared as follows: 292.Bd -literal -offset indent 293TAILQ_HEAD(HEADNAME, TYPE) head; 294.Ed 295.sp 296where 297.Li HEADNAME 298is the name of the structure to be defined, and 299.Li TYPE 300is the type of the elements to be linked into the tail queue. 301A pointer to the head of the tail queue can later be declared as: 302.Bd -literal -offset indent 303struct HEADNAME *headp; 304.Ed 305.sp 306(The names 307.Li head 308and 309.Li headp 310are user selectable.) 311.Pp 312The macro 313.Nm TAILQ_ENTRY 314declares a structure that connects the elements in 315the tail queue. 316.Pp 317The macro 318.Nm TAILQ_HEAD_INITIALIZER 319provides a value which can be used to initialize a tail queue head at 320compile time, and is used at the point that the tail queue head 321variable is declared, like: 322.Bd -literal -offset indent 323struct HEADNAME head = TAILQ_HEAD_INITIALIZER(head); 324.Ed 325.Pp 326The macro 327.Nm TAILQ_INIT 328initializes the tail queue referenced by 329.Fa head . 330.Pp 331The macro 332.Nm TAILQ_INSERT_HEAD 333inserts the new element 334.Fa elm 335at the head of the tail queue. 336.Pp 337The macro 338.Nm TAILQ_INSERT_TAIL 339inserts the new element 340.Fa elm 341at the end of the tail queue. 342.Pp 343The macro 344.Nm TAILQ_INSERT_AFTER 345inserts the new element 346.Fa elm 347after the element 348.Fa listelm . 349.Pp 350The macro 351.Nm TAILQ_INSERT_BEFORE 352inserts the new element 353.Fa elm 354before the element 355.Fa listelm . 356.Pp 357The macro 358.Nm TAILQ_REMOVE 359removes the element 360.Fa elm 361from the tail queue. 362.Sh TAIL QUEUE EXAMPLE 363.Bd -literal 364TAILQ_HEAD(tailhead, entry) head; 365struct tailhead *headp; /* Tail queue head. */ 366struct entry { 367 ... 368 TAILQ_ENTRY(entry) entries; /* Tail queue. */ 369 ... 370} *n1, *n2, *np; 371 372TAILQ_INIT(&head); /* Initialize the queue. */ 373 374n1 = malloc(sizeof(struct entry)); /* Insert at the head. */ 375TAILQ_INSERT_HEAD(&head, n1, entries); 376 377n1 = malloc(sizeof(struct entry)); /* Insert at the tail. */ 378TAILQ_INSERT_TAIL(&head, n1, entries); 379 380n2 = malloc(sizeof(struct entry)); /* Insert after. */ 381TAILQ_INSERT_AFTER(&head, n1, n2, entries); 382 383n2 = malloc(sizeof(struct entry)); /* Insert before. */ 384TAILQ_INSERT_BEFORE(n1, n2, entries); 385 /* Forward traversal. */ 386for (np = head.tqh_first; np != NULL; np = np->entries.tqe_next) 387 np-> ... 388 /* Delete. */ 389while (head.tqh_first != NULL) 390 TAILQ_REMOVE(&head, head.tqh_first, entries); 391.Ed 392.Sh CIRCULAR QUEUES 393A circular queue is headed by a structure defined by the 394.Nm CIRCLEQ_HEAD 395macro. 396This structure contains a pair of pointers, 397one to the first element in the circular queue and the other to the 398last element in the circular queue. 399The elements are doubly linked so that an arbitrary element can be 400removed without traversing the queue. 401New elements can be added to the queue after an existing element, 402before an existing element, at the head of the queue, or at the end 403of the queue. 404A 405.Fa CIRCLEQ_HEAD 406structure is declared as follows: 407.Bd -literal -offset indent 408CIRCLEQ_HEAD(HEADNAME, TYPE) head; 409.Ed 410.sp 411where 412.Li HEADNAME 413is the name of the structure to be defined, and 414.Li TYPE 415is the type of the elements to be linked into the circular queue. 416A pointer to the head of the circular queue can later be declared as: 417.Bd -literal -offset indent 418struct HEADNAME *headp; 419.Ed 420.sp 421(The names 422.Li head 423and 424.Li headp 425are user selectable.) 426.Pp 427The macro 428.Nm CIRCLEQ_ENTRY 429declares a structure that connects the elements in 430the circular queue. 431.Pp 432The macro 433.Nm CIRCLEQ_HEAD_INITIALIZER 434provides a value which can be used to initialize a circular queue head at 435compile time, and is used at the point that the circular queue head 436variable is declared, like: 437.Bd -literal -offset indent 438struct HEADNAME head = CIRCLEQ_HEAD_INITIALIZER(head); 439.Ed 440.Pp 441The macro 442.Nm CIRCLEQ_INIT 443initializes the circular queue referenced by 444.Fa head . 445.Pp 446The macro 447.Nm CIRCLEQ_INSERT_HEAD 448inserts the new element 449.Fa elm 450at the head of the circular queue. 451.Pp 452The macro 453.Nm CIRCLEQ_INSERT_TAIL 454inserts the new element 455.Fa elm 456at the end of the circular queue. 457.Pp 458The macro 459.Nm CIRCLEQ_INSERT_AFTER 460inserts the new element 461.Fa elm 462after the element 463.Fa listelm . 464.Pp 465The macro 466.Nm CIRCLEQ_INSERT_BEFORE 467inserts the new element 468.Fa elm 469before the element 470.Fa listelm . 471.Pp 472The macro 473.Nm CIRCLEQ_REMOVE 474removes the element 475.Fa elm 476from the circular queue. 477.Sh CIRCULAR QUEUE EXAMPLE 478.Bd -literal 479CIRCLEQ_HEAD(circleq, entry) head; 480struct circleq *headp; /* Circular queue head. */ 481struct entry { 482 ... 483 CIRCLEQ_ENTRY entries; /* Circular queue. */ 484 ... 485} *n1, *n2, *np; 486 487CIRCLEQ_INIT(&head); /* Initialize the circular queue. */ 488 489n1 = malloc(sizeof(struct entry)); /* Insert at the head. */ 490CIRCLEQ_INSERT_HEAD(&head, n1, entries); 491 492n1 = malloc(sizeof(struct entry)); /* Insert at the tail. */ 493CIRCLEQ_INSERT_TAIL(&head, n1, entries); 494 495n2 = malloc(sizeof(struct entry)); /* Insert after. */ 496CIRCLEQ_INSERT_AFTER(&head, n1, n2, entries); 497 498n2 = malloc(sizeof(struct entry)); /* Insert before. */ 499CIRCLEQ_INSERT_BEFORE(&head, n1, n2, entries); 500 /* Forward traversal. */ 501for (np = head.cqh_first; np != (void *)&head; np = np->entries.cqe_next) 502 np-> ... 503 /* Reverse traversal. */ 504for (np = head.cqh_last; np != (void *)&head; np = np->entries.cqe_prev) 505 np-> ... 506 /* Delete. */ 507while (head.cqh_first != (void *)&head) 508 CIRCLEQ_REMOVE(&head, head.cqh_first, entries); 509.Ed 510.Sh HISTORY 511The 512.Nm queue 513functions first appeared in 4.4BSD. 514