xref: /freebsd/share/man/man3/queue.3 (revision 3652ff557dc3f615cc2f6a777b046e2861b4dd48)
1afe61c15SRodney W. Grimes.\" Copyright (c) 1993
2afe61c15SRodney W. Grimes.\"	The Regents of the University of California.  All rights reserved.
3afe61c15SRodney W. Grimes.\"
4afe61c15SRodney W. Grimes.\" Redistribution and use in source and binary forms, with or without
5afe61c15SRodney W. Grimes.\" modification, are permitted provided that the following conditions
6afe61c15SRodney W. Grimes.\" are met:
7afe61c15SRodney W. Grimes.\" 1. Redistributions of source code must retain the above copyright
8afe61c15SRodney W. Grimes.\"    notice, this list of conditions and the following disclaimer.
9afe61c15SRodney W. Grimes.\" 2. Redistributions in binary form must reproduce the above copyright
10afe61c15SRodney W. Grimes.\"    notice, this list of conditions and the following disclaimer in the
11afe61c15SRodney W. Grimes.\"    documentation and/or other materials provided with the distribution.
12afe61c15SRodney W. Grimes.\" 3. All advertising materials mentioning features or use of this software
13afe61c15SRodney W. Grimes.\"    must display the following acknowledgement:
14afe61c15SRodney W. Grimes.\"	This product includes software developed by the University of
15afe61c15SRodney W. Grimes.\"	California, Berkeley and its contributors.
16afe61c15SRodney W. Grimes.\" 4. Neither the name of the University nor the names of its contributors
17afe61c15SRodney W. Grimes.\"    may be used to endorse or promote products derived from this software
18afe61c15SRodney W. Grimes.\"    without specific prior written permission.
19afe61c15SRodney W. Grimes.\"
20afe61c15SRodney W. Grimes.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21afe61c15SRodney W. Grimes.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22afe61c15SRodney W. Grimes.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23afe61c15SRodney W. Grimes.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24afe61c15SRodney W. Grimes.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25afe61c15SRodney W. Grimes.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26afe61c15SRodney W. Grimes.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27afe61c15SRodney W. Grimes.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28afe61c15SRodney W. Grimes.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29afe61c15SRodney W. Grimes.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30afe61c15SRodney W. Grimes.\" SUCH DAMAGE.
31afe61c15SRodney W. Grimes.\"
32afe61c15SRodney W. Grimes.\"	@(#)queue.3	8.2 (Berkeley) 1/24/94
33afe61c15SRodney W. Grimes.\"
34afe61c15SRodney W. Grimes.Dd "January 24, 1994"
35afe61c15SRodney W. Grimes.Dt QUEUE 3
36afe61c15SRodney W. Grimes.Os BSD 4
37afe61c15SRodney W. Grimes.Sh NAME
38afe61c15SRodney W. Grimes.Nm LIST_ENTRY ,
39afe61c15SRodney W. Grimes.Nm LIST_HEAD ,
40afe61c15SRodney W. Grimes.Nm LIST_INIT ,
41afe61c15SRodney W. Grimes.Nm LIST_INSERT_AFTER ,
427658b0a2SJustin T. Gibbs.Nm LIST_INSERT_BEFORE ,
43afe61c15SRodney W. Grimes.Nm LIST_INSERT_HEAD ,
44afe61c15SRodney W. Grimes.Nm LIST_REMOVE ,
45afe61c15SRodney W. Grimes.Nm TAILQ_ENTRY ,
46afe61c15SRodney W. Grimes.Nm TAILQ_HEAD ,
47afe61c15SRodney W. Grimes.Nm TAILQ_INIT ,
48afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_AFTER ,
497658b0a2SJustin T. Gibbs.Nm TAILQ_INSERT_BEFORE ,
50afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_HEAD ,
51afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_TAIL ,
52afe61c15SRodney W. Grimes.Nm TAILQ_REMOVE ,
53afe61c15SRodney W. Grimes.Nm CIRCLEQ_ENTRY ,
54afe61c15SRodney W. Grimes.Nm CIRCLEQ_HEAD ,
55afe61c15SRodney W. Grimes.Nm CIRCLEQ_INIT ,
56afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_AFTER ,
57afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_BEFORE ,
58afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_HEAD ,
59afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_TAIL ,
60afe61c15SRodney W. Grimes.Nm CIRCLEQ_REMOVE
61afe61c15SRodney W. Grimes.Nd implementations of lists, tail queues, and circular queues
62afe61c15SRodney W. Grimes.Sh SYNOPSIS
63afe61c15SRodney W. Grimes.Fd #include <sys/queue.h>
64afe61c15SRodney W. Grimes.sp
65afe61c15SRodney W. Grimes.Fn LIST_ENTRY "TYPE"
66afe61c15SRodney W. Grimes.Fn LIST_HEAD "HEADNAME" "TYPE"
67afe61c15SRodney W. Grimes.Fn LIST_INIT "LIST_HEAD *head"
68afe61c15SRodney W. Grimes.Fn LIST_INSERT_AFTER "LIST_ENTRY *listelm" "TYPE *elm" "LIST_ENTRY NAME"
697658b0a2SJustin T. Gibbs.Fn LIST_INSERT_BEFORE "LIST_ENTRY *listelm" "TYPE *elm" "LIST_ENTRY NAME"
70afe61c15SRodney W. Grimes.Fn LIST_INSERT_HEAD "LIST_HEAD *head" "TYPE *elm" "LIST_ENTRY NAME"
71afe61c15SRodney W. Grimes.Fn LIST_REMOVE "TYPE *elm" "LIST_ENTRY NAME"
72afe61c15SRodney W. Grimes.sp
73afe61c15SRodney W. Grimes.Fn TAILQ_ENTRY "TYPE"
74afe61c15SRodney W. Grimes.Fn TAILQ_HEAD "HEADNAME" "TYPE"
75afe61c15SRodney W. Grimes.Fn TAILQ_INIT "TAILQ_HEAD *head"
76afe61c15SRodney W. Grimes.Fn TAILQ_INSERT_AFTER "TAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME"
773652ff55SJustin T. Gibbs.Fn TAILQ_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME"
78afe61c15SRodney W. Grimes.Fn TAILQ_INSERT_HEAD "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
79afe61c15SRodney W. Grimes.Fn TAILQ_INSERT_TAIL "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
80afe61c15SRodney W. Grimes.Fn TAILQ_REMOVE "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
81afe61c15SRodney W. Grimes.sp
82afe61c15SRodney W. Grimes.Fn CIRCLEQ_ENTRY "TYPE"
83afe61c15SRodney W. Grimes.Fn CIRCLEQ_HEAD "HEADNAME" "TYPE"
84afe61c15SRodney W. Grimes.Fn CIRCLEQ_INIT "CIRCLEQ_HEAD *head"
85afe61c15SRodney W. Grimes.Fn CIRCLEQ_INSERT_AFTER "CIRCLEQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
86afe61c15SRodney W. Grimes.Fn CIRCLEQ_INSERT_BEFORE "CIRCLEQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
87afe61c15SRodney W. Grimes.Fn CIRCLEQ_INSERT_HEAD "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
88afe61c15SRodney W. Grimes.Fn CIRCLEQ_INSERT_TAIL "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
89afe61c15SRodney W. Grimes.Fn CIRCLEQ_REMOVE "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
90afe61c15SRodney W. Grimes.Sh DESCRIPTION
91afe61c15SRodney W. GrimesThese macros define and operate on three types of data structures:
92afe61c15SRodney W. Grimeslists, tail queues, and circular queues.
93afe61c15SRodney W. GrimesAll three structures support the following functionality:
94afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
95afe61c15SRodney W. Grimes.It
96afe61c15SRodney W. GrimesInsertion of a new entry at the head of the list.
97afe61c15SRodney W. Grimes.It
98afe61c15SRodney W. GrimesInsertion of a new entry after any element in the list.
99afe61c15SRodney W. Grimes.It
1007658b0a2SJustin T. GibbsInsertion of a new entry before any element in the list.
1017658b0a2SJustin T. Gibbs.It
102afe61c15SRodney W. GrimesRemoval of any entry in the list.
103afe61c15SRodney W. Grimes.It
104afe61c15SRodney W. GrimesForward traversal through the list.
105afe61c15SRodney W. Grimes.El
106afe61c15SRodney W. Grimes.Pp
107afe61c15SRodney W. GrimesLists are the simplest of the three data structures and support
108afe61c15SRodney W. Grimesonly the above functionality.
109afe61c15SRodney W. Grimes.Pp
110afe61c15SRodney W. GrimesTail queues add the following functionality:
111afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
112afe61c15SRodney W. Grimes.It
113afe61c15SRodney W. GrimesEntries can be added at the end of a list.
114afe61c15SRodney W. Grimes.El
115afe61c15SRodney W. GrimesHowever:
116afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
117afe61c15SRodney W. Grimes.It
118afe61c15SRodney W. GrimesAll list insertions and removals must specify the head of the list.
119afe61c15SRodney W. Grimes.It
120afe61c15SRodney W. GrimesEach head entry requires two pointers rather than one.
121afe61c15SRodney W. Grimes.It
122afe61c15SRodney W. GrimesCode size is about 15% greater and operations run about 20% slower
123afe61c15SRodney W. Grimesthan lists.
124afe61c15SRodney W. Grimes.El
125afe61c15SRodney W. Grimes.Pp
126afe61c15SRodney W. GrimesCircular queues add the following functionality:
127afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
128afe61c15SRodney W. Grimes.It
129afe61c15SRodney W. GrimesEntries can be added at the end of a list.
130afe61c15SRodney W. Grimes.It
131afe61c15SRodney W. GrimesThey may be traversed backwards, from tail to head.
132afe61c15SRodney W. Grimes.El
133afe61c15SRodney W. GrimesHowever:
134afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
135afe61c15SRodney W. Grimes.It
136afe61c15SRodney W. GrimesAll list insertions and removals must specify the head of the list.
137afe61c15SRodney W. Grimes.It
138afe61c15SRodney W. GrimesEach head entry requires two pointers rather than one.
139afe61c15SRodney W. Grimes.It
140afe61c15SRodney W. GrimesThe termination condition for traversal is more complex.
141afe61c15SRodney W. Grimes.It
142afe61c15SRodney W. GrimesCode size is about 40% greater and operations run about 45% slower
143afe61c15SRodney W. Grimesthan lists.
144afe61c15SRodney W. Grimes.El
145afe61c15SRodney W. Grimes.Pp
146afe61c15SRodney W. GrimesIn the macro definitions,
147afe61c15SRodney W. Grimes.Fa TYPE
148afe61c15SRodney W. Grimesis the name of a user defined structure,
149afe61c15SRodney W. Grimesthat must contain a field of type
150afe61c15SRodney W. Grimes.Li LIST_ENTRY ,
151afe61c15SRodney W. Grimes.Li TAILQ_ENTRY ,
152afe61c15SRodney W. Grimesor
153afe61c15SRodney W. Grimes.Li CIRCLEQ_ENTRY ,
154afe61c15SRodney W. Grimesnamed
155afe61c15SRodney W. Grimes.Fa NAME .
156afe61c15SRodney W. GrimesThe argument
157afe61c15SRodney W. Grimes.Fa HEADNAME
158afe61c15SRodney W. Grimesis the name of a user defined structure that must be declared
159afe61c15SRodney W. Grimesusing the macros
160afe61c15SRodney W. Grimes.Li LIST_HEAD ,
161afe61c15SRodney W. Grimes.Li TAILQ_HEAD ,
162afe61c15SRodney W. Grimesor
163afe61c15SRodney W. Grimes.Li CIRCLEQ_HEAD .
164afe61c15SRodney W. GrimesSee the examples below for further explanation of how these
165afe61c15SRodney W. Grimesmacros are used.
166afe61c15SRodney W. Grimes.Sh LISTS
167afe61c15SRodney W. GrimesA list is headed by a structure defined by the
168afe61c15SRodney W. Grimes.Nm LIST_HEAD
169afe61c15SRodney W. Grimesmacro.
170afe61c15SRodney W. GrimesThis structure contains a single pointer to the first element
171afe61c15SRodney W. Grimeson the list.
172afe61c15SRodney W. GrimesThe elements are doubly linked so that an arbitrary element can be
173afe61c15SRodney W. Grimesremoved without traversing the list.
174afe61c15SRodney W. GrimesNew elements can be added to the list after an existing element or
175afe61c15SRodney W. Grimesat the head of the list.
176afe61c15SRodney W. GrimesA
177afe61c15SRodney W. Grimes.Fa LIST_HEAD
178afe61c15SRodney W. Grimesstructure is declared as follows:
179afe61c15SRodney W. Grimes.Bd -literal -offset indent
180afe61c15SRodney W. GrimesLIST_HEAD(HEADNAME, TYPE) head;
181afe61c15SRodney W. Grimes.Ed
182afe61c15SRodney W. Grimes.sp
183afe61c15SRodney W. Grimeswhere
184afe61c15SRodney W. Grimes.Fa HEADNAME
185afe61c15SRodney W. Grimesis the name of the structure to be defined, and
186afe61c15SRodney W. Grimes.Fa TYPE
187afe61c15SRodney W. Grimesis the type of the elements to be linked into the list.
188afe61c15SRodney W. GrimesA pointer to the head of the list can later be declared as:
189afe61c15SRodney W. Grimes.Bd -literal -offset indent
190afe61c15SRodney W. Grimesstruct HEADNAME *headp;
191afe61c15SRodney W. Grimes.Ed
192afe61c15SRodney W. Grimes.sp
193afe61c15SRodney W. Grimes(The names
194afe61c15SRodney W. Grimes.Li head
195afe61c15SRodney W. Grimesand
196afe61c15SRodney W. Grimes.Li headp
197afe61c15SRodney W. Grimesare user selectable.)
198afe61c15SRodney W. Grimes.Pp
199afe61c15SRodney W. GrimesThe macro
200afe61c15SRodney W. Grimes.Nm LIST_ENTRY
201afe61c15SRodney W. Grimesdeclares a structure that connects the elements in
202afe61c15SRodney W. Grimesthe list.
203afe61c15SRodney W. Grimes.Pp
204afe61c15SRodney W. GrimesThe macro
205afe61c15SRodney W. Grimes.Nm LIST_INIT
206afe61c15SRodney W. Grimesinitializes the list referenced by
207afe61c15SRodney W. Grimes.Fa head .
208afe61c15SRodney W. Grimes.Pp
209afe61c15SRodney W. GrimesThe macro
210afe61c15SRodney W. Grimes.Nm LIST_INSERT_HEAD
211afe61c15SRodney W. Grimesinserts the new element
212afe61c15SRodney W. Grimes.Fa elm
213afe61c15SRodney W. Grimesat the head of the list.
214afe61c15SRodney W. Grimes.Pp
215afe61c15SRodney W. GrimesThe macro
216afe61c15SRodney W. Grimes.Nm LIST_INSERT_AFTER
217afe61c15SRodney W. Grimesinserts the new element
218afe61c15SRodney W. Grimes.Fa elm
219afe61c15SRodney W. Grimesafter the element
220afe61c15SRodney W. Grimes.Fa listelm .
221afe61c15SRodney W. Grimes.Pp
222afe61c15SRodney W. GrimesThe macro
2237658b0a2SJustin T. Gibbs.Nm LIST_INSERT_BEFORE
2247658b0a2SJustin T. Gibbsinserts the new element
2257658b0a2SJustin T. Gibbs.Fa elm
2267658b0a2SJustin T. Gibbsbefore the element
2277658b0a2SJustin T. Gibbs.Fa listelm .
2287658b0a2SJustin T. Gibbs.Pp
2297658b0a2SJustin T. GibbsThe macro
230afe61c15SRodney W. Grimes.Nm LIST_REMOVE
231afe61c15SRodney W. Grimesremoves the element
232afe61c15SRodney W. Grimes.Fa elm
233afe61c15SRodney W. Grimesfrom the list.
234afe61c15SRodney W. Grimes.Sh LIST EXAMPLE
235afe61c15SRodney W. Grimes.Bd -literal
236afe61c15SRodney W. GrimesLIST_HEAD(listhead, entry) head;
237afe61c15SRodney W. Grimesstruct listhead *headp;		/* List head. */
238afe61c15SRodney W. Grimesstruct entry {
239afe61c15SRodney W. Grimes	...
240afe61c15SRodney W. Grimes	LIST_ENTRY(entry) entries;	/* List. */
241afe61c15SRodney W. Grimes	...
2427658b0a2SJustin T. Gibbs} *n1, *n2, *n3, *np;
243afe61c15SRodney W. Grimes
244afe61c15SRodney W. GrimesLIST_INIT(&head);			/* Initialize the list. */
245afe61c15SRodney W. Grimes
246afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
247afe61c15SRodney W. GrimesLIST_INSERT_HEAD(&head, n1, entries);
248afe61c15SRodney W. Grimes
249afe61c15SRodney W. Grimesn2 = malloc(sizeof(struct entry));	/* Insert after. */
250afe61c15SRodney W. GrimesLIST_INSERT_AFTER(n1, n2, entries);
2517658b0a2SJustin T. Gibbs
2527658b0a2SJustin T. Gibbsn3 = malloc(sizeof(struct entry));	/* Insert before. */
2537658b0a2SJustin T. GibbsLIST_INSERT_BEFORE(n2, n3, entries);
2547658b0a2SJustin T. Gibbs
2557658b0a2SJustin T. GibbsLIST_REMOVE(n2, entries);		/* Deletion. */
2567658b0a2SJustin T. Gibbsfree(n2);
2577658b0a2SJustin T. Gibbs
258afe61c15SRodney W. Grimes					/* Forward traversal. */
259afe61c15SRodney W. Grimesfor (np = head.lh_first; np != NULL; np = np->entries.le_next)
260afe61c15SRodney W. Grimes	np-> ...
261afe61c15SRodney W. Grimes
2627658b0a2SJustin T. Gibbswhile (head.lh_first != NULL) {		/* List Deletion. */
2637658b0a2SJustin T. Gibbs	n1 = head.lh_first;
2647658b0a2SJustin T. Gibbs	LIST_REMOVE(n1, entries);
2657658b0a2SJustin T. Gibbs	free(n1);
2667658b0a2SJustin T. Gibbs}
2677658b0a2SJustin T. Gibbs
2687658b0a2SJustin T. Gibbsn1 = head.lh_first;			/* Faster List Delete. */
2697658b0a2SJustin T. Gibbswhile (n1 != NULL) {
2707658b0a2SJustin T. Gibbs	n2 = n1->entires.le_next;
2717658b0a2SJustin T. Gibbs	free(n1);
2727658b0a2SJustin T. Gibbs	n1 = n2;
2737658b0a2SJustin T. Gibbs}
2747658b0a2SJustin T. GibbsLIST_INIT(&head);
2757658b0a2SJustin T. Gibbs
276afe61c15SRodney W. Grimes.Ed
277afe61c15SRodney W. Grimes.Sh TAIL QUEUES
278afe61c15SRodney W. GrimesA tail queue is headed by a structure defined by the
279afe61c15SRodney W. Grimes.Nm TAILQ_HEAD
280afe61c15SRodney W. Grimesmacro.
281afe61c15SRodney W. GrimesThis structure contains a pair of pointers,
282afe61c15SRodney W. Grimesone to the first element in the tail queue and the other to
283afe61c15SRodney W. Grimesthe last element in the tail queue.
284afe61c15SRodney W. GrimesThe elements are doubly linked so that an arbitrary element can be
285afe61c15SRodney W. Grimesremoved without traversing the tail queue.
286afe61c15SRodney W. GrimesNew elements can be added to the tail queue after an existing element,
287afe61c15SRodney W. Grimesat the head of the tail queue, or at the end of the tail queue.
288afe61c15SRodney W. GrimesA
289afe61c15SRodney W. Grimes.Fa TAILQ_HEAD
290afe61c15SRodney W. Grimesstructure is declared as follows:
291afe61c15SRodney W. Grimes.Bd -literal -offset indent
292afe61c15SRodney W. GrimesTAILQ_HEAD(HEADNAME, TYPE) head;
293afe61c15SRodney W. Grimes.Ed
294afe61c15SRodney W. Grimes.sp
295afe61c15SRodney W. Grimeswhere
296afe61c15SRodney W. Grimes.Li HEADNAME
297afe61c15SRodney W. Grimesis the name of the structure to be defined, and
298afe61c15SRodney W. Grimes.Li TYPE
299afe61c15SRodney W. Grimesis the type of the elements to be linked into the tail queue.
300afe61c15SRodney W. GrimesA pointer to the head of the tail queue can later be declared as:
301afe61c15SRodney W. Grimes.Bd -literal -offset indent
302afe61c15SRodney W. Grimesstruct HEADNAME *headp;
303afe61c15SRodney W. Grimes.Ed
304afe61c15SRodney W. Grimes.sp
305afe61c15SRodney W. Grimes(The names
306afe61c15SRodney W. Grimes.Li head
307afe61c15SRodney W. Grimesand
308afe61c15SRodney W. Grimes.Li headp
309afe61c15SRodney W. Grimesare user selectable.)
310afe61c15SRodney W. Grimes.Pp
311afe61c15SRodney W. GrimesThe macro
312afe61c15SRodney W. Grimes.Nm TAILQ_ENTRY
313afe61c15SRodney W. Grimesdeclares a structure that connects the elements in
314afe61c15SRodney W. Grimesthe tail queue.
315afe61c15SRodney W. Grimes.Pp
316afe61c15SRodney W. GrimesThe macro
317afe61c15SRodney W. Grimes.Nm TAILQ_INIT
318afe61c15SRodney W. Grimesinitializes the tail queue referenced by
319afe61c15SRodney W. Grimes.Fa head .
320afe61c15SRodney W. Grimes.Pp
321afe61c15SRodney W. GrimesThe macro
322afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_HEAD
323afe61c15SRodney W. Grimesinserts the new element
324afe61c15SRodney W. Grimes.Fa elm
325afe61c15SRodney W. Grimesat the head of the tail queue.
326afe61c15SRodney W. Grimes.Pp
327afe61c15SRodney W. GrimesThe macro
328afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_TAIL
329afe61c15SRodney W. Grimesinserts the new element
330afe61c15SRodney W. Grimes.Fa elm
331afe61c15SRodney W. Grimesat the end of the tail queue.
332afe61c15SRodney W. Grimes.Pp
333afe61c15SRodney W. GrimesThe macro
334afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_AFTER
335afe61c15SRodney W. Grimesinserts the new element
336afe61c15SRodney W. Grimes.Fa elm
337afe61c15SRodney W. Grimesafter the element
338afe61c15SRodney W. Grimes.Fa listelm .
339afe61c15SRodney W. Grimes.Pp
340afe61c15SRodney W. GrimesThe macro
3417658b0a2SJustin T. Gibbs.Nm TAILQ_INSERT_BEFORE
3427658b0a2SJustin T. Gibbsinserts the new element
3437658b0a2SJustin T. Gibbs.Fa elm
3447658b0a2SJustin T. Gibbsbefore the element
3457658b0a2SJustin T. Gibbs.Fa listelm .
3467658b0a2SJustin T. Gibbs.Pp
3477658b0a2SJustin T. GibbsThe macro
348afe61c15SRodney W. Grimes.Nm TAILQ_REMOVE
349afe61c15SRodney W. Grimesremoves the element
350afe61c15SRodney W. Grimes.Fa elm
351afe61c15SRodney W. Grimesfrom the tail queue.
352afe61c15SRodney W. Grimes.Sh TAIL QUEUE EXAMPLE
353afe61c15SRodney W. Grimes.Bd -literal
354afe61c15SRodney W. GrimesTAILQ_HEAD(tailhead, entry) head;
355afe61c15SRodney W. Grimesstruct tailhead *headp;		/* Tail queue head. */
356afe61c15SRodney W. Grimesstruct entry {
357afe61c15SRodney W. Grimes	...
358afe61c15SRodney W. Grimes	TAILQ_ENTRY(entry) entries;	/* Tail queue. */
359afe61c15SRodney W. Grimes	...
3607658b0a2SJustin T. Gibbs} *n1, *n2, *n3, *np;
361afe61c15SRodney W. Grimes
362afe61c15SRodney W. GrimesTAILQ_INIT(&head);			/* Initialize the queue. */
363afe61c15SRodney W. Grimes
364afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
365afe61c15SRodney W. GrimesTAILQ_INSERT_HEAD(&head, n1, entries);
366afe61c15SRodney W. Grimes
367afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the tail. */
368afe61c15SRodney W. GrimesTAILQ_INSERT_TAIL(&head, n1, entries);
369afe61c15SRodney W. Grimes
370afe61c15SRodney W. Grimesn2 = malloc(sizeof(struct entry));	/* Insert after. */
371afe61c15SRodney W. GrimesTAILQ_INSERT_AFTER(&head, n1, n2, entries);
3727658b0a2SJustin T. Gibbs
3737658b0a2SJustin T. Gibbsn3 = malloc(sizeof(struct entry));	/* Insert before. */
3743652ff55SJustin T. GibbsTAILQ_INSERT_BEFORE(n2, n3, entries);
3757658b0a2SJustin T. Gibbs
3767658b0a2SJustin T. GibbsTAILQ_REMOVE(&head, n2, entries);	/* Deletion. */
3777658b0a2SJustin T. Gibbsfree(n2);
378afe61c15SRodney W. Grimes					/* Forward traversal. */
379afe61c15SRodney W. Grimesfor (np = head.tqh_first; np != NULL; np = np->entries.tqe_next)
380afe61c15SRodney W. Grimes	np-> ...
3817658b0a2SJustin T. Gibbs					/* TailQ Deletion. */
3827658b0a2SJustin T. Gibbswhile (head.tqh_first != NULL) {
3837658b0a2SJustin T. Gibbs	n1 = head.tqh_first;
384afe61c15SRodney W. Grimes	TAILQ_REMOVE(&head, head.tqh_first, entries);
3857658b0a2SJustin T. Gibbs	free(n1);
3867658b0a2SJustin T. Gibbs}
3877658b0a2SJustin T. Gibbs					/* Faster TailQ Deletion. */
3887658b0a2SJustin T. Gibbsn1 = head.tqh_first;
3897658b0a2SJustin T. Gibbswhile (n1 != NULL) {
3907658b0a2SJustin T. Gibbs	n2 = n1->entries.tqe_next;
3917658b0a2SJustin T. Gibbs	free(n1);
3927658b0a2SJustin T. Gibbs	n1 = n2;
3937658b0a2SJustin T. Gibbs}
3947658b0a2SJustin T. GibbsTAILQ_INIT(&head);
395afe61c15SRodney W. Grimes.Ed
396afe61c15SRodney W. Grimes.Sh CIRCULAR QUEUES
397afe61c15SRodney W. GrimesA circular queue is headed by a structure defined by the
398afe61c15SRodney W. Grimes.Nm CIRCLEQ_HEAD
399afe61c15SRodney W. Grimesmacro.
400afe61c15SRodney W. GrimesThis structure contains a pair of pointers,
401afe61c15SRodney W. Grimesone to the first element in the circular queue and the other to the
402afe61c15SRodney W. Grimeslast element in the circular queue.
403afe61c15SRodney W. GrimesThe elements are doubly linked so that an arbitrary element can be
404afe61c15SRodney W. Grimesremoved without traversing the queue.
405afe61c15SRodney W. GrimesNew elements can be added to the queue after an existing element,
406afe61c15SRodney W. Grimesbefore an existing element, at the head of the queue, or at the end
407afe61c15SRodney W. Grimesof the queue.
408afe61c15SRodney W. GrimesA
409afe61c15SRodney W. Grimes.Fa CIRCLEQ_HEAD
410afe61c15SRodney W. Grimesstructure is declared as follows:
411afe61c15SRodney W. Grimes.Bd -literal -offset indent
412afe61c15SRodney W. GrimesCIRCLEQ_HEAD(HEADNAME, TYPE) head;
413afe61c15SRodney W. Grimes.Ed
414afe61c15SRodney W. Grimes.sp
415afe61c15SRodney W. Grimeswhere
416afe61c15SRodney W. Grimes.Li HEADNAME
417afe61c15SRodney W. Grimesis the name of the structure to be defined, and
418afe61c15SRodney W. Grimes.Li TYPE
419afe61c15SRodney W. Grimesis the type of the elements to be linked into the circular queue.
420afe61c15SRodney W. GrimesA pointer to the head of the circular queue can later be declared as:
421afe61c15SRodney W. Grimes.Bd -literal -offset indent
422afe61c15SRodney W. Grimesstruct HEADNAME *headp;
423afe61c15SRodney W. Grimes.Ed
424afe61c15SRodney W. Grimes.sp
425afe61c15SRodney W. Grimes(The names
426afe61c15SRodney W. Grimes.Li head
427afe61c15SRodney W. Grimesand
428afe61c15SRodney W. Grimes.Li headp
429afe61c15SRodney W. Grimesare user selectable.)
430afe61c15SRodney W. Grimes.Pp
431afe61c15SRodney W. GrimesThe macro
432afe61c15SRodney W. Grimes.Nm CIRCLEQ_ENTRY
433afe61c15SRodney W. Grimesdeclares a structure that connects the elements in
434afe61c15SRodney W. Grimesthe circular queue.
435afe61c15SRodney W. Grimes.Pp
436afe61c15SRodney W. GrimesThe macro
437afe61c15SRodney W. Grimes.Nm CIRCLEQ_INIT
438afe61c15SRodney W. Grimesinitializes the circular queue referenced by
439afe61c15SRodney W. Grimes.Fa head .
440afe61c15SRodney W. Grimes.Pp
441afe61c15SRodney W. GrimesThe macro
442afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_HEAD
443afe61c15SRodney W. Grimesinserts the new element
444afe61c15SRodney W. Grimes.Fa elm
445afe61c15SRodney W. Grimesat the head of the circular queue.
446afe61c15SRodney W. Grimes.Pp
447afe61c15SRodney W. GrimesThe macro
448afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_TAIL
449afe61c15SRodney W. Grimesinserts the new element
450afe61c15SRodney W. Grimes.Fa elm
451afe61c15SRodney W. Grimesat the end of the circular queue.
452afe61c15SRodney W. Grimes.Pp
453afe61c15SRodney W. GrimesThe macro
454afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_AFTER
455afe61c15SRodney W. Grimesinserts the new element
456afe61c15SRodney W. Grimes.Fa elm
457afe61c15SRodney W. Grimesafter the element
458afe61c15SRodney W. Grimes.Fa listelm .
459afe61c15SRodney W. Grimes.Pp
460afe61c15SRodney W. GrimesThe macro
461afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_BEFORE
462afe61c15SRodney W. Grimesinserts the new element
463afe61c15SRodney W. Grimes.Fa elm
464afe61c15SRodney W. Grimesbefore the element
465afe61c15SRodney W. Grimes.Fa listelm .
466afe61c15SRodney W. Grimes.Pp
467afe61c15SRodney W. GrimesThe macro
468afe61c15SRodney W. Grimes.Nm CIRCLEQ_REMOVE
469afe61c15SRodney W. Grimesremoves the element
470afe61c15SRodney W. Grimes.Fa elm
471afe61c15SRodney W. Grimesfrom the circular queue.
472afe61c15SRodney W. Grimes.Sh CIRCULAR QUEUE EXAMPLE
473afe61c15SRodney W. Grimes.Bd -literal
474afe61c15SRodney W. GrimesCIRCLEQ_HEAD(circleq, entry) head;
475afe61c15SRodney W. Grimesstruct circleq *headp;			/* Circular queue head. */
476afe61c15SRodney W. Grimesstruct entry {
477afe61c15SRodney W. Grimes	...
478afe61c15SRodney W. Grimes	CIRCLEQ_ENTRY entries;		/* Circular queue. */
479afe61c15SRodney W. Grimes	...
480afe61c15SRodney W. Grimes} *n1, *n2, *np;
481afe61c15SRodney W. Grimes
482afe61c15SRodney W. GrimesCIRCLEQ_INIT(&head);			/* Initialize the circular queue. */
483afe61c15SRodney W. Grimes
484afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
485afe61c15SRodney W. GrimesCIRCLEQ_INSERT_HEAD(&head, n1, entries);
486afe61c15SRodney W. Grimes
487afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the tail. */
488afe61c15SRodney W. GrimesCIRCLEQ_INSERT_TAIL(&head, n1, entries);
489afe61c15SRodney W. Grimes
490afe61c15SRodney W. Grimesn2 = malloc(sizeof(struct entry));	/* Insert after. */
491afe61c15SRodney W. GrimesCIRCLEQ_INSERT_AFTER(&head, n1, n2, entries);
492afe61c15SRodney W. Grimes
493afe61c15SRodney W. Grimesn2 = malloc(sizeof(struct entry));	/* Insert before. */
494afe61c15SRodney W. GrimesCIRCLEQ_INSERT_BEFORE(&head, n1, n2, entries);
4957658b0a2SJustin T. Gibbs
4967658b0a2SJustin T. GibbsCIRCLEQ_REMOVE(&head, n1, entries);	/* Deletion. */
4977658b0a2SJustin T. Gibbsfree(n1);
498afe61c15SRodney W. Grimes					/* Forward traversal. */
499afe61c15SRodney W. Grimesfor (np = head.cqh_first; np != (void *)&head; np = np->entries.cqe_next)
500afe61c15SRodney W. Grimes	np-> ...
501afe61c15SRodney W. Grimes					/* Reverse traversal. */
502afe61c15SRodney W. Grimesfor (np = head.cqh_last; np != (void *)&head; np = np->entries.cqe_prev)
503afe61c15SRodney W. Grimes	np-> ...
5047658b0a2SJustin T. Gibbs					/* CircleQ Deletion. */
5057658b0a2SJustin T. Gibbswhile (head.cqh_first != (void *)&head) {
5067658b0a2SJustin T. Gibbs	n1 = head.cqh_first;
507afe61c15SRodney W. Grimes	CIRCLEQ_REMOVE(&head, head.cqh_first, entries);
5087658b0a2SJustin T. Gibbs	free(n1);
5097658b0a2SJustin T. Gibbs}
5107658b0a2SJustin T. Gibbs					/* Faster CircleQ Deletion. */
5117658b0a2SJustin T. Gibbsn1 = head.cqh_first;
5127658b0a2SJustin T. Gibbswhile (n1 != (void *)&head) {
5137658b0a2SJustin T. Gibbs	n2 = n1->entries.cqh_next;
5147658b0a2SJustin T. Gibbs	free(n1);
5157658b0a2SJustin T. Gibbs	n1 = n2;
5167658b0a2SJustin T. Gibbs}
5177658b0a2SJustin T. GibbsCIRCLEQ_INIT(&head);
518afe61c15SRodney W. Grimes.Ed
519afe61c15SRodney W. Grimes.Sh HISTORY
520afe61c15SRodney W. GrimesThe
521afe61c15SRodney W. Grimes.Nm queue
522afe61c15SRodney W. Grimesfunctions first appeared in 4.4BSD.
523