165881Sbostic.\" Copyright (c) 1993 265881Sbostic.\" The Regents of the University of California. All rights reserved. 365120Smckusick.\" 465120Smckusick.\" %sccs.include.redist.roff% 565120Smckusick.\" 6*67714Smckusick.\" @(#)queue.3 8.3 (Berkeley) 08/20/94 765120Smckusick.\" 865120Smckusick.Dd "" 965120Smckusick.Dt QUEUE 3 1065120Smckusick.Os BSD 4 1165120Smckusick.Sh NAME 1265120Smckusick.Nm LIST_ENTRY , 1365120Smckusick.Nm LIST_HEAD , 1465120Smckusick.Nm LIST_INIT , 1565120Smckusick.Nm LIST_INSERT_AFTER , 16*67714Smckusick.Nm LIST_INSERT_BEFORE , 1765120Smckusick.Nm LIST_INSERT_HEAD , 1865120Smckusick.Nm LIST_REMOVE , 1965120Smckusick.Nm TAILQ_ENTRY , 2065120Smckusick.Nm TAILQ_HEAD , 2165120Smckusick.Nm TAILQ_INIT , 2265120Smckusick.Nm TAILQ_INSERT_AFTER , 23*67714Smckusick.Nm TAILQ_INSERT_BEFORE , 2465120Smckusick.Nm TAILQ_INSERT_HEAD , 2565120Smckusick.Nm TAILQ_INSERT_TAIL , 2665120Smckusick.Nm TAILQ_REMOVE , 2765120Smckusick.Nm CIRCLEQ_ENTRY , 2865120Smckusick.Nm CIRCLEQ_HEAD , 2965120Smckusick.Nm CIRCLEQ_INIT , 3065120Smckusick.Nm CIRCLEQ_INSERT_AFTER , 3165120Smckusick.Nm CIRCLEQ_INSERT_BEFORE , 3265120Smckusick.Nm CIRCLEQ_INSERT_HEAD , 3365120Smckusick.Nm CIRCLEQ_INSERT_TAIL , 3465120Smckusick.Nm CIRCLEQ_REMOVE 3565120Smckusick.Nd implementations of lists, tail queues, and circular queues 3665120Smckusick.Sh SYNOPSIS 3765120Smckusick.Fd #include <sys/queue.h> 3865120Smckusick.sp 3965120Smckusick.Fn LIST_ENTRY "TYPE" 4065120Smckusick.Fn LIST_HEAD "HEADNAME" "TYPE" 4165120Smckusick.Fn LIST_INIT "LIST_HEAD *head" 4265120Smckusick.Fn LIST_INSERT_AFTER "LIST_ENTRY *listelm" "TYPE *elm" "LIST_ENTRY NAME" 43*67714Smckusick.Fn LIST_INSERT_BEFORE "LIST_ENTRY *listelm" "TYPE *elm" "LIST_ENTRY NAME" 4465120Smckusick.Fn LIST_INSERT_HEAD "LIST_HEAD *head" "TYPE *elm" "LIST_ENTRY NAME" 4565120Smckusick.Fn LIST_REMOVE "TYPE *elm" "LIST_ENTRY NAME" 4665120Smckusick.sp 4765120Smckusick.Fn TAILQ_ENTRY "TYPE" 4865120Smckusick.Fn TAILQ_HEAD "HEADNAME" "TYPE" 4965120Smckusick.Fn TAILQ_INIT "TAILQ_HEAD *head" 5065120Smckusick.Fn TAILQ_INSERT_AFTER "TAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME" 51*67714Smckusick.Fn TAILQ_INSERT_BEFORE "TAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME" 5265120Smckusick.Fn TAILQ_INSERT_HEAD "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME" 5365120Smckusick.Fn TAILQ_INSERT_TAIL "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME" 5465120Smckusick.Fn TAILQ_REMOVE "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME" 5565120Smckusick.sp 5665120Smckusick.Fn CIRCLEQ_ENTRY "TYPE" 5765120Smckusick.Fn CIRCLEQ_HEAD "HEADNAME" "TYPE" 5865120Smckusick.Fn CIRCLEQ_INIT "CIRCLEQ_HEAD *head" 5965120Smckusick.Fn CIRCLEQ_INSERT_AFTER "CIRCLEQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "CIRCLEQ_ENTRY NAME" 6065120Smckusick.Fn CIRCLEQ_INSERT_BEFORE "CIRCLEQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "CIRCLEQ_ENTRY NAME" 6165120Smckusick.Fn CIRCLEQ_INSERT_HEAD "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME" 6265120Smckusick.Fn CIRCLEQ_INSERT_TAIL "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME" 6365120Smckusick.Fn CIRCLEQ_REMOVE "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME" 6465120Smckusick.Sh DESCRIPTION 6565120SmckusickThese macros define and operate on three types of data structures: 6665120Smckusicklists, tail queues, and circular queues. 6765120SmckusickAll three structures support the following functionality: 6865120Smckusick.Bl -enum -compact -offset indent 6965120Smckusick.It 7065120SmckusickInsertion of a new entry at the head of the list. 7165120Smckusick.It 7265120SmckusickInsertion of a new entry after any element in the list. 7365120Smckusick.It 74*67714SmckusickInsertion of a new entry before any element in the list. 75*67714Smckusick.It 7665120SmckusickRemoval of any entry in the list. 7765120Smckusick.It 7865120SmckusickForward traversal through the list. 7965120Smckusick.El 8065120Smckusick.Pp 8165120SmckusickLists are the simplest of the three data structures and support 8265120Smckusickonly the above functionality. 8365120Smckusick.Pp 8465120SmckusickTail queues add the following functionality: 8565120Smckusick.Bl -enum -compact -offset indent 8665120Smckusick.It 8765120SmckusickEntries can be added at the end of a list. 8865120Smckusick.El 8965120SmckusickHowever: 9065120Smckusick.Bl -enum -compact -offset indent 9165120Smckusick.It 9265120SmckusickAll list insertions and removals must specify the head of the list. 9365120Smckusick.It 9465120SmckusickEach head entry requires two pointers rather than one. 9565120Smckusick.It 9665120SmckusickCode size is about 15% greater and operations run about 20% slower 9765120Smckusickthan lists. 9865120Smckusick.El 9965120Smckusick.Pp 10065120SmckusickCircular queues add the following functionality: 10165120Smckusick.Bl -enum -compact -offset indent 10265120Smckusick.It 10365120SmckusickEntries can be added at the end of a list. 10465120Smckusick.It 10565120SmckusickThey may be traversed backwards, from tail to head. 10665120Smckusick.El 10765120SmckusickHowever: 10865120Smckusick.Bl -enum -compact -offset indent 10965120Smckusick.It 11065120SmckusickAll list insertions and removals must specify the head of the list. 11165120Smckusick.It 11265120SmckusickEach head entry requires two pointers rather than one. 11365120Smckusick.It 11465120SmckusickThe termination condition for traversal is more complex. 11565120Smckusick.It 11665120SmckusickCode size is about 40% greater and operations run about 45% slower 11765120Smckusickthan lists. 11865120Smckusick.El 11965120Smckusick.Pp 12065120SmckusickIn the macro definitions, 12165120Smckusick.Fa TYPE 12265120Smckusickis the name of a user defined structure, 12365120Smckusickthat must contain a field of type 12465120Smckusick.Li LIST_ENTRY , 12565120Smckusick.Li TAILQ_ENTRY , 12665120Smckusickor 12765120Smckusick.Li CIRCLEQ_ENTRY , 12865120Smckusicknamed 12965120Smckusick.Fa NAME . 13065120SmckusickThe argument 13165120Smckusick.Fa HEADNAME 13265120Smckusickis the name of a user defined structure that must be declared 13365120Smckusickusing the macros 13465120Smckusick.Li LIST_HEAD , 13565120Smckusick.Li TAILQ_HEAD , 13665120Smckusickor 13765120Smckusick.Li CIRCLEQ_HEAD . 13865120SmckusickSee the examples below for further explanation of how these 13965120Smckusickmacros are used. 14065120Smckusick.Sh LISTS 14165120SmckusickA list is headed by a structure defined by the 14265120Smckusick.Nm LIST_HEAD 14365120Smckusickmacro. 14465120SmckusickThis structure contains a single pointer to the first element 14565120Smckusickon the list. 14665120SmckusickThe elements are doubly linked so that an arbitrary element can be 14765120Smckusickremoved without traversing the list. 148*67714SmckusickNew elements can be added to the list before or after an existing element or 14965120Smckusickat the head of the list. 15065120SmckusickA 15165120Smckusick.Fa LIST_HEAD 15265120Smckusickstructure is declared as follows: 15365120Smckusick.Bd -literal -offset indent 15465120SmckusickLIST_HEAD(HEADNAME, TYPE) head; 15565120Smckusick.Ed 15665120Smckusick.sp 15765120Smckusickwhere 15865120Smckusick.Fa HEADNAME 15965120Smckusickis the name of the structure to be defined, and 16065120Smckusick.Fa TYPE 16165120Smckusickis the type of the elements to be linked into the list. 16265120SmckusickA pointer to the head of the list can later be declared as: 16365120Smckusick.Bd -literal -offset indent 16465120Smckusickstruct HEADNAME *headp; 16565120Smckusick.Ed 16665120Smckusick.sp 16765120Smckusick(The names 16865120Smckusick.Li head 16965120Smckusickand 17065120Smckusick.Li headp 17165120Smckusickare user selectable.) 17265120Smckusick.Pp 17365120SmckusickThe macro 17465120Smckusick.Nm LIST_ENTRY 17565120Smckusickdeclares a structure that connects the elements in 17665120Smckusickthe list. 17765120Smckusick.Pp 17865120SmckusickThe macro 17965120Smckusick.Nm LIST_INIT 18065120Smckusickinitializes the list referenced by 18165120Smckusick.Fa head . 18265120Smckusick.Pp 18365120SmckusickThe macro 18465120Smckusick.Nm LIST_INSERT_HEAD 18565120Smckusickinserts the new element 18665120Smckusick.Fa elm 18765120Smckusickat the head of the list. 18865120Smckusick.Pp 18965120SmckusickThe macro 19065120Smckusick.Nm LIST_INSERT_AFTER 19165120Smckusickinserts the new element 19265120Smckusick.Fa elm 19365120Smckusickafter the element 19465120Smckusick.Fa listelm . 19565120Smckusick.Pp 19665120SmckusickThe macro 197*67714Smckusick.Nm LIST_INSERT_BEFORE 198*67714Smckusickinserts the new element 199*67714Smckusick.Fa elm 200*67714Smckusickbefore the element 201*67714Smckusick.Fa listelm . 202*67714Smckusick.Pp 203*67714SmckusickThe macro 20465120Smckusick.Nm LIST_REMOVE 20565120Smckusickremoves the element 20665120Smckusick.Fa elm 20765120Smckusickfrom the list. 20865120Smckusick.Sh LIST EXAMPLE 20965120Smckusick.Bd -literal 21065120SmckusickLIST_HEAD(listhead, entry) head; 21165120Smckusickstruct listhead *headp; /* List head. */ 21265120Smckusickstruct entry { 21365120Smckusick ... 21465120Smckusick LIST_ENTRY(entry) entries; /* List. */ 21565120Smckusick ... 21665120Smckusick} *n1, *n2, *np; 21765120Smckusick 21865120SmckusickLIST_INIT(&head); /* Initialize the list. */ 21965120Smckusick 22065120Smckusickn1 = malloc(sizeof(struct entry)); /* Insert at the head. */ 22165120SmckusickLIST_INSERT_HEAD(&head, n1, entries); 22265120Smckusick 22365120Smckusickn2 = malloc(sizeof(struct entry)); /* Insert after. */ 22465120SmckusickLIST_INSERT_AFTER(n1, n2, entries); 225*67714Smckusick 226*67714Smckusickn2 = malloc(sizeof(struct entry)); /* Insert before. */ 227*67714SmckusickLIST_INSERT_BEFORE(n1, n2, entries); 22865120Smckusick /* Forward traversal. */ 22965120Smckusickfor (np = head.lh_first; np != NULL; np = np->entries.le_next) 23065120Smckusick np-> ... 23165120Smckusick 23265120Smckusickwhile (head.lh_first != NULL) /* Delete. */ 23365120Smckusick LIST_REMOVE(head.lh_first, entries); 23465120Smckusick.Ed 23565120Smckusick.Sh TAIL QUEUES 23665120SmckusickA tail queue is headed by a structure defined by the 23765120Smckusick.Nm TAILQ_HEAD 23865120Smckusickmacro. 23965120SmckusickThis structure contains a pair of pointers, 24065120Smckusickone to the first element in the tail queue and the other to 24165120Smckusickthe last element in the tail queue. 24265120SmckusickThe elements are doubly linked so that an arbitrary element can be 24365120Smckusickremoved without traversing the tail queue. 24465120SmckusickNew elements can be added to the tail queue after an existing element, 24565120Smckusickat the head of the tail queue, or at the end of the tail queue. 24665120SmckusickA 24765120Smckusick.Fa TAILQ_HEAD 24865120Smckusickstructure is declared as follows: 24965120Smckusick.Bd -literal -offset indent 25065120SmckusickTAILQ_HEAD(HEADNAME, TYPE) head; 25165120Smckusick.Ed 25265120Smckusick.sp 25365120Smckusickwhere 25465120Smckusick.Li HEADNAME 25565120Smckusickis the name of the structure to be defined, and 25665120Smckusick.Li TYPE 25765120Smckusickis the type of the elements to be linked into the tail queue. 25865120SmckusickA pointer to the head of the tail queue can later be declared as: 25965120Smckusick.Bd -literal -offset indent 26065120Smckusickstruct HEADNAME *headp; 26165120Smckusick.Ed 26265120Smckusick.sp 26365120Smckusick(The names 26465120Smckusick.Li head 26565120Smckusickand 26665120Smckusick.Li headp 26765120Smckusickare user selectable.) 26865120Smckusick.Pp 26965120SmckusickThe macro 27065120Smckusick.Nm TAILQ_ENTRY 27165120Smckusickdeclares a structure that connects the elements in 27265120Smckusickthe tail queue. 27365120Smckusick.Pp 27465120SmckusickThe macro 27565120Smckusick.Nm TAILQ_INIT 27665120Smckusickinitializes the tail queue referenced by 27765120Smckusick.Fa head . 27865120Smckusick.Pp 27965120SmckusickThe macro 28065120Smckusick.Nm TAILQ_INSERT_HEAD 28165120Smckusickinserts the new element 28265120Smckusick.Fa elm 28365120Smckusickat the head of the tail queue. 28465120Smckusick.Pp 28565120SmckusickThe macro 28665120Smckusick.Nm TAILQ_INSERT_TAIL 28765120Smckusickinserts the new element 28865120Smckusick.Fa elm 28965120Smckusickat the end of the tail queue. 29065120Smckusick.Pp 29165120SmckusickThe macro 29265120Smckusick.Nm TAILQ_INSERT_AFTER 29365120Smckusickinserts the new element 29465120Smckusick.Fa elm 29565120Smckusickafter the element 29665120Smckusick.Fa listelm . 29765120Smckusick.Pp 29865120SmckusickThe macro 299*67714Smckusick.Nm TAILQ_INSERT_BEFORE 300*67714Smckusickinserts the new element 301*67714Smckusick.Fa elm 302*67714Smckusickbefore the element 303*67714Smckusick.Fa listelm . 304*67714Smckusick.Pp 305*67714SmckusickThe macro 30665120Smckusick.Nm TAILQ_REMOVE 30765120Smckusickremoves the element 30865120Smckusick.Fa elm 30965120Smckusickfrom the tail queue. 31065120Smckusick.Sh TAIL QUEUE EXAMPLE 31165120Smckusick.Bd -literal 31265120SmckusickTAILQ_HEAD(tailhead, entry) head; 31365120Smckusickstruct tailhead *headp; /* Tail queue head. */ 31465120Smckusickstruct entry { 31565120Smckusick ... 31665120Smckusick TAILQ_ENTRY(entry) entries; /* Tail queue. */ 31765120Smckusick ... 31865120Smckusick} *n1, *n2, *np; 31965120Smckusick 32065120SmckusickTAILQ_INIT(&head); /* Initialize the queue. */ 32165120Smckusick 32265120Smckusickn1 = malloc(sizeof(struct entry)); /* Insert at the head. */ 32365120SmckusickTAILQ_INSERT_HEAD(&head, n1, entries); 32465120Smckusick 32565120Smckusickn1 = malloc(sizeof(struct entry)); /* Insert at the tail. */ 32665120SmckusickTAILQ_INSERT_TAIL(&head, n1, entries); 32765120Smckusick 32865120Smckusickn2 = malloc(sizeof(struct entry)); /* Insert after. */ 32965120SmckusickTAILQ_INSERT_AFTER(&head, n1, n2, entries); 330*67714Smckusick 331*67714Smckusickn2 = malloc(sizeof(struct entry)); /* Insert before. */ 332*67714SmckusickTAILQ_INSERT_BEFORE(&head, n1, n2, entries); 33365120Smckusick /* Forward traversal. */ 33465120Smckusickfor (np = head.tqh_first; np != NULL; np = np->entries.tqe_next) 33565120Smckusick np-> ... 33665120Smckusick /* Delete. */ 33765120Smckusickwhile (head.tqh_first != NULL) 33865120Smckusick TAILQ_REMOVE(&head, head.tqh_first, entries); 33965120Smckusick.Ed 34065120Smckusick.Sh CIRCULAR QUEUES 34165120SmckusickA circular queue is headed by a structure defined by the 34265120Smckusick.Nm CIRCLEQ_HEAD 34365120Smckusickmacro. 34465120SmckusickThis structure contains a pair of pointers, 34565120Smckusickone to the first element in the circular queue and the other to the 34665120Smckusicklast element in the circular queue. 34765120SmckusickThe elements are doubly linked so that an arbitrary element can be 34865120Smckusickremoved without traversing the queue. 34965120SmckusickNew elements can be added to the queue after an existing element, 35065120Smckusickbefore an existing element, at the head of the queue, or at the end 35165120Smckusickof the queue. 35265120SmckusickA 35365120Smckusick.Fa CIRCLEQ_HEAD 35465120Smckusickstructure is declared as follows: 35565120Smckusick.Bd -literal -offset indent 35665120SmckusickCIRCLEQ_HEAD(HEADNAME, TYPE) head; 35765120Smckusick.Ed 35865120Smckusick.sp 35965120Smckusickwhere 36065120Smckusick.Li HEADNAME 36165120Smckusickis the name of the structure to be defined, and 36265120Smckusick.Li TYPE 36365120Smckusickis the type of the elements to be linked into the circular queue. 36465120SmckusickA pointer to the head of the circular queue can later be declared as: 36565120Smckusick.Bd -literal -offset indent 36665120Smckusickstruct HEADNAME *headp; 36765120Smckusick.Ed 36865120Smckusick.sp 36965120Smckusick(The names 37065120Smckusick.Li head 37165120Smckusickand 37265120Smckusick.Li headp 37365120Smckusickare user selectable.) 37465120Smckusick.Pp 37565120SmckusickThe macro 37665120Smckusick.Nm CIRCLEQ_ENTRY 37765120Smckusickdeclares a structure that connects the elements in 37865120Smckusickthe circular queue. 37965120Smckusick.Pp 38065120SmckusickThe macro 38165120Smckusick.Nm CIRCLEQ_INIT 38265120Smckusickinitializes the circular queue referenced by 38365120Smckusick.Fa head . 38465120Smckusick.Pp 38565120SmckusickThe macro 38665120Smckusick.Nm CIRCLEQ_INSERT_HEAD 38765120Smckusickinserts the new element 38865120Smckusick.Fa elm 38965120Smckusickat the head of the circular queue. 39065120Smckusick.Pp 39165120SmckusickThe macro 39265120Smckusick.Nm CIRCLEQ_INSERT_TAIL 39365120Smckusickinserts the new element 39465120Smckusick.Fa elm 39565120Smckusickat the end of the circular queue. 39665120Smckusick.Pp 39765120SmckusickThe macro 39865120Smckusick.Nm CIRCLEQ_INSERT_AFTER 39965120Smckusickinserts the new element 40065120Smckusick.Fa elm 40165120Smckusickafter the element 40265120Smckusick.Fa listelm . 40365120Smckusick.Pp 40465120SmckusickThe macro 40565120Smckusick.Nm CIRCLEQ_INSERT_BEFORE 40665120Smckusickinserts the new element 40765120Smckusick.Fa elm 40865120Smckusickbefore the element 40965120Smckusick.Fa listelm . 41065120Smckusick.Pp 41165120SmckusickThe macro 41265120Smckusick.Nm CIRCLEQ_REMOVE 41365120Smckusickremoves the element 41465120Smckusick.Fa elm 41565120Smckusickfrom the circular queue. 41665120Smckusick.Sh CIRCULAR QUEUE EXAMPLE 41765120Smckusick.Bd -literal 41865120SmckusickCIRCLEQ_HEAD(circleq, entry) head; 41965120Smckusickstruct circleq *headp; /* Circular queue head. */ 42065120Smckusickstruct entry { 42165120Smckusick ... 42265120Smckusick CIRCLEQ_ENTRY entries; /* Circular queue. */ 42365120Smckusick ... 42465120Smckusick} *n1, *n2, *np; 42565120Smckusick 42665120SmckusickCIRCLEQ_INIT(&head); /* Initialize the circular queue. */ 42765120Smckusick 42865120Smckusickn1 = malloc(sizeof(struct entry)); /* Insert at the head. */ 42965120SmckusickCIRCLEQ_INSERT_HEAD(&head, n1, entries); 43065120Smckusick 43165120Smckusickn1 = malloc(sizeof(struct entry)); /* Insert at the tail. */ 43265120SmckusickCIRCLEQ_INSERT_TAIL(&head, n1, entries); 43365120Smckusick 43465120Smckusickn2 = malloc(sizeof(struct entry)); /* Insert after. */ 43565120SmckusickCIRCLEQ_INSERT_AFTER(&head, n1, n2, entries); 43665120Smckusick 43765120Smckusickn2 = malloc(sizeof(struct entry)); /* Insert before. */ 43865120SmckusickCIRCLEQ_INSERT_BEFORE(&head, n1, n2, entries); 43965120Smckusick /* Forward traversal. */ 44065120Smckusickfor (np = head.cqh_first; np != (void *)&head; np = np->entries.cqe_next) 44165120Smckusick np-> ... 44265120Smckusick /* Reverse traversal. */ 44365120Smckusickfor (np = head.cqh_last; np != (void *)&head; np = np->entries.cqe_prev) 44465120Smckusick np-> ... 44565120Smckusick /* Delete. */ 44665120Smckusickwhile (head.cqh_first != (void *)&head) 44765120Smckusick CIRCLEQ_REMOVE(&head, head.cqh_first, entries); 44865120Smckusick.Ed 44965120Smckusick.Sh HISTORY 45065120SmckusickThe 45165120Smckusick.Nm queue 45265120Smckusickfunctions first appeared in 4.4BSD. 453