xref: /csrg-svn/share/man/man3/queue.3 (revision 65881)
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