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