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