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