xref: /freebsd/share/man/man3/queue.3 (revision afe61c15161c324a7af299a9b8457aba5afc92db)
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 ,
42afe61c15SRodney W. Grimes.Nm LIST_INSERT_HEAD ,
43afe61c15SRodney W. Grimes.Nm LIST_REMOVE ,
44afe61c15SRodney W. Grimes.Nm TAILQ_ENTRY ,
45afe61c15SRodney W. Grimes.Nm TAILQ_HEAD ,
46afe61c15SRodney W. Grimes.Nm TAILQ_INIT ,
47afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_AFTER ,
48afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_HEAD ,
49afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_TAIL ,
50afe61c15SRodney W. Grimes.Nm TAILQ_REMOVE ,
51afe61c15SRodney W. Grimes.Nm CIRCLEQ_ENTRY ,
52afe61c15SRodney W. Grimes.Nm CIRCLEQ_HEAD ,
53afe61c15SRodney W. Grimes.Nm CIRCLEQ_INIT ,
54afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_AFTER ,
55afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_BEFORE ,
56afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_HEAD ,
57afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_TAIL ,
58afe61c15SRodney W. Grimes.Nm CIRCLEQ_REMOVE
59afe61c15SRodney W. Grimes.Nd implementations of lists, tail queues, and circular queues
60afe61c15SRodney W. Grimes.Sh SYNOPSIS
61afe61c15SRodney W. Grimes.Fd #include <sys/queue.h>
62afe61c15SRodney W. Grimes.sp
63afe61c15SRodney W. Grimes.Fn LIST_ENTRY "TYPE"
64afe61c15SRodney W. Grimes.Fn LIST_HEAD "HEADNAME" "TYPE"
65afe61c15SRodney W. Grimes.Fn LIST_INIT "LIST_HEAD *head"
66afe61c15SRodney W. Grimes.Fn LIST_INSERT_AFTER "LIST_ENTRY *listelm" "TYPE *elm" "LIST_ENTRY NAME"
67afe61c15SRodney W. Grimes.Fn LIST_INSERT_HEAD "LIST_HEAD *head" "TYPE *elm" "LIST_ENTRY NAME"
68afe61c15SRodney W. Grimes.Fn LIST_REMOVE "TYPE *elm" "LIST_ENTRY NAME"
69afe61c15SRodney W. Grimes.sp
70afe61c15SRodney W. Grimes.Fn TAILQ_ENTRY "TYPE"
71afe61c15SRodney W. Grimes.Fn TAILQ_HEAD "HEADNAME" "TYPE"
72afe61c15SRodney W. Grimes.Fn TAILQ_INIT "TAILQ_HEAD *head"
73afe61c15SRodney W. Grimes.Fn TAILQ_INSERT_AFTER "TAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME"
74afe61c15SRodney W. Grimes.Fn TAILQ_INSERT_HEAD "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
75afe61c15SRodney W. Grimes.Fn TAILQ_INSERT_TAIL "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
76afe61c15SRodney W. Grimes.Fn TAILQ_REMOVE "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
77afe61c15SRodney W. Grimes.sp
78afe61c15SRodney W. Grimes.Fn CIRCLEQ_ENTRY "TYPE"
79afe61c15SRodney W. Grimes.Fn CIRCLEQ_HEAD "HEADNAME" "TYPE"
80afe61c15SRodney W. Grimes.Fn CIRCLEQ_INIT "CIRCLEQ_HEAD *head"
81afe61c15SRodney W. Grimes.Fn CIRCLEQ_INSERT_AFTER "CIRCLEQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
82afe61c15SRodney W. Grimes.Fn CIRCLEQ_INSERT_BEFORE "CIRCLEQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
83afe61c15SRodney W. Grimes.Fn CIRCLEQ_INSERT_HEAD "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
84afe61c15SRodney W. Grimes.Fn CIRCLEQ_INSERT_TAIL "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
85afe61c15SRodney W. Grimes.Fn CIRCLEQ_REMOVE "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
86afe61c15SRodney W. Grimes.Sh DESCRIPTION
87afe61c15SRodney W. GrimesThese macros define and operate on three types of data structures:
88afe61c15SRodney W. Grimeslists, tail queues, and circular queues.
89afe61c15SRodney W. GrimesAll three structures support the following functionality:
90afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
91afe61c15SRodney W. Grimes.It
92afe61c15SRodney W. GrimesInsertion of a new entry at the head of the list.
93afe61c15SRodney W. Grimes.It
94afe61c15SRodney W. GrimesInsertion of a new entry after any element in the list.
95afe61c15SRodney W. Grimes.It
96afe61c15SRodney W. GrimesRemoval of any entry in the list.
97afe61c15SRodney W. Grimes.It
98afe61c15SRodney W. GrimesForward traversal through the list.
99afe61c15SRodney W. Grimes.El
100afe61c15SRodney W. Grimes.Pp
101afe61c15SRodney W. GrimesLists are the simplest of the three data structures and support
102afe61c15SRodney W. Grimesonly the above functionality.
103afe61c15SRodney W. Grimes.Pp
104afe61c15SRodney W. GrimesTail queues add the following functionality:
105afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
106afe61c15SRodney W. Grimes.It
107afe61c15SRodney W. GrimesEntries can be added at the end of a list.
108afe61c15SRodney W. Grimes.El
109afe61c15SRodney W. GrimesHowever:
110afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
111afe61c15SRodney W. Grimes.It
112afe61c15SRodney W. GrimesAll list insertions and removals must specify the head of the list.
113afe61c15SRodney W. Grimes.It
114afe61c15SRodney W. GrimesEach head entry requires two pointers rather than one.
115afe61c15SRodney W. Grimes.It
116afe61c15SRodney W. GrimesCode size is about 15% greater and operations run about 20% slower
117afe61c15SRodney W. Grimesthan lists.
118afe61c15SRodney W. Grimes.El
119afe61c15SRodney W. Grimes.Pp
120afe61c15SRodney W. GrimesCircular queues add the following functionality:
121afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
122afe61c15SRodney W. Grimes.It
123afe61c15SRodney W. GrimesEntries can be added at the end of a list.
124afe61c15SRodney W. Grimes.It
125afe61c15SRodney W. GrimesEntries can be added before another entry.
126afe61c15SRodney W. Grimes.It
127afe61c15SRodney W. GrimesThey may be traversed backwards, from tail to head.
128afe61c15SRodney W. Grimes.El
129afe61c15SRodney W. GrimesHowever:
130afe61c15SRodney W. Grimes.Bl -enum -compact -offset indent
131afe61c15SRodney W. Grimes.It
132afe61c15SRodney W. GrimesAll list insertions and removals must specify the head of the list.
133afe61c15SRodney W. Grimes.It
134afe61c15SRodney W. GrimesEach head entry requires two pointers rather than one.
135afe61c15SRodney W. Grimes.It
136afe61c15SRodney W. GrimesThe termination condition for traversal is more complex.
137afe61c15SRodney W. Grimes.It
138afe61c15SRodney W. GrimesCode size is about 40% greater and operations run about 45% slower
139afe61c15SRodney W. Grimesthan lists.
140afe61c15SRodney W. Grimes.El
141afe61c15SRodney W. Grimes.Pp
142afe61c15SRodney W. GrimesIn the macro definitions,
143afe61c15SRodney W. Grimes.Fa TYPE
144afe61c15SRodney W. Grimesis the name of a user defined structure,
145afe61c15SRodney W. Grimesthat must contain a field of type
146afe61c15SRodney W. Grimes.Li LIST_ENTRY ,
147afe61c15SRodney W. Grimes.Li TAILQ_ENTRY ,
148afe61c15SRodney W. Grimesor
149afe61c15SRodney W. Grimes.Li CIRCLEQ_ENTRY ,
150afe61c15SRodney W. Grimesnamed
151afe61c15SRodney W. Grimes.Fa NAME .
152afe61c15SRodney W. GrimesThe argument
153afe61c15SRodney W. Grimes.Fa HEADNAME
154afe61c15SRodney W. Grimesis the name of a user defined structure that must be declared
155afe61c15SRodney W. Grimesusing the macros
156afe61c15SRodney W. Grimes.Li LIST_HEAD ,
157afe61c15SRodney W. Grimes.Li TAILQ_HEAD ,
158afe61c15SRodney W. Grimesor
159afe61c15SRodney W. Grimes.Li CIRCLEQ_HEAD .
160afe61c15SRodney W. GrimesSee the examples below for further explanation of how these
161afe61c15SRodney W. Grimesmacros are used.
162afe61c15SRodney W. Grimes.Sh LISTS
163afe61c15SRodney W. GrimesA list is headed by a structure defined by the
164afe61c15SRodney W. Grimes.Nm LIST_HEAD
165afe61c15SRodney W. Grimesmacro.
166afe61c15SRodney W. GrimesThis structure contains a single pointer to the first element
167afe61c15SRodney W. Grimeson the list.
168afe61c15SRodney W. GrimesThe elements are doubly linked so that an arbitrary element can be
169afe61c15SRodney W. Grimesremoved without traversing the list.
170afe61c15SRodney W. GrimesNew elements can be added to the list after an existing element or
171afe61c15SRodney W. Grimesat the head of the list.
172afe61c15SRodney W. GrimesA
173afe61c15SRodney W. Grimes.Fa LIST_HEAD
174afe61c15SRodney W. Grimesstructure is declared as follows:
175afe61c15SRodney W. Grimes.Bd -literal -offset indent
176afe61c15SRodney W. GrimesLIST_HEAD(HEADNAME, TYPE) head;
177afe61c15SRodney W. Grimes.Ed
178afe61c15SRodney W. Grimes.sp
179afe61c15SRodney W. Grimeswhere
180afe61c15SRodney W. Grimes.Fa HEADNAME
181afe61c15SRodney W. Grimesis the name of the structure to be defined, and
182afe61c15SRodney W. Grimes.Fa TYPE
183afe61c15SRodney W. Grimesis the type of the elements to be linked into the list.
184afe61c15SRodney W. GrimesA pointer to the head of the list can later be declared as:
185afe61c15SRodney W. Grimes.Bd -literal -offset indent
186afe61c15SRodney W. Grimesstruct HEADNAME *headp;
187afe61c15SRodney W. Grimes.Ed
188afe61c15SRodney W. Grimes.sp
189afe61c15SRodney W. Grimes(The names
190afe61c15SRodney W. Grimes.Li head
191afe61c15SRodney W. Grimesand
192afe61c15SRodney W. Grimes.Li headp
193afe61c15SRodney W. Grimesare user selectable.)
194afe61c15SRodney W. Grimes.Pp
195afe61c15SRodney W. GrimesThe macro
196afe61c15SRodney W. Grimes.Nm LIST_ENTRY
197afe61c15SRodney W. Grimesdeclares a structure that connects the elements in
198afe61c15SRodney W. Grimesthe list.
199afe61c15SRodney W. Grimes.Pp
200afe61c15SRodney W. GrimesThe macro
201afe61c15SRodney W. Grimes.Nm LIST_INIT
202afe61c15SRodney W. Grimesinitializes the list referenced by
203afe61c15SRodney W. Grimes.Fa head .
204afe61c15SRodney W. Grimes.Pp
205afe61c15SRodney W. GrimesThe macro
206afe61c15SRodney W. Grimes.Nm LIST_INSERT_HEAD
207afe61c15SRodney W. Grimesinserts the new element
208afe61c15SRodney W. Grimes.Fa elm
209afe61c15SRodney W. Grimesat the head of the list.
210afe61c15SRodney W. Grimes.Pp
211afe61c15SRodney W. GrimesThe macro
212afe61c15SRodney W. Grimes.Nm LIST_INSERT_AFTER
213afe61c15SRodney W. Grimesinserts the new element
214afe61c15SRodney W. Grimes.Fa elm
215afe61c15SRodney W. Grimesafter the element
216afe61c15SRodney W. Grimes.Fa listelm .
217afe61c15SRodney W. Grimes.Pp
218afe61c15SRodney W. GrimesThe macro
219afe61c15SRodney W. Grimes.Nm LIST_REMOVE
220afe61c15SRodney W. Grimesremoves the element
221afe61c15SRodney W. Grimes.Fa elm
222afe61c15SRodney W. Grimesfrom the list.
223afe61c15SRodney W. Grimes.Sh LIST EXAMPLE
224afe61c15SRodney W. Grimes.Bd -literal
225afe61c15SRodney W. GrimesLIST_HEAD(listhead, entry) head;
226afe61c15SRodney W. Grimesstruct listhead *headp;		/* List head. */
227afe61c15SRodney W. Grimesstruct entry {
228afe61c15SRodney W. Grimes	...
229afe61c15SRodney W. Grimes	LIST_ENTRY(entry) entries;	/* List. */
230afe61c15SRodney W. Grimes	...
231afe61c15SRodney W. Grimes} *n1, *n2, *np;
232afe61c15SRodney W. Grimes
233afe61c15SRodney W. GrimesLIST_INIT(&head);			/* Initialize the list. */
234afe61c15SRodney W. Grimes
235afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
236afe61c15SRodney W. GrimesLIST_INSERT_HEAD(&head, n1, entries);
237afe61c15SRodney W. Grimes
238afe61c15SRodney W. Grimesn2 = malloc(sizeof(struct entry));	/* Insert after. */
239afe61c15SRodney W. GrimesLIST_INSERT_AFTER(n1, n2, entries);
240afe61c15SRodney W. Grimes					/* Forward traversal. */
241afe61c15SRodney W. Grimesfor (np = head.lh_first; np != NULL; np = np->entries.le_next)
242afe61c15SRodney W. Grimes	np-> ...
243afe61c15SRodney W. Grimes
244afe61c15SRodney W. Grimeswhile (head.lh_first != NULL)		/* Delete. */
245afe61c15SRodney W. Grimes	LIST_REMOVE(head.lh_first, entries);
246afe61c15SRodney W. Grimes.Ed
247afe61c15SRodney W. Grimes.Sh TAIL QUEUES
248afe61c15SRodney W. GrimesA tail queue is headed by a structure defined by the
249afe61c15SRodney W. Grimes.Nm TAILQ_HEAD
250afe61c15SRodney W. Grimesmacro.
251afe61c15SRodney W. GrimesThis structure contains a pair of pointers,
252afe61c15SRodney W. Grimesone to the first element in the tail queue and the other to
253afe61c15SRodney W. Grimesthe last element in the tail queue.
254afe61c15SRodney W. GrimesThe elements are doubly linked so that an arbitrary element can be
255afe61c15SRodney W. Grimesremoved without traversing the tail queue.
256afe61c15SRodney W. GrimesNew elements can be added to the tail queue after an existing element,
257afe61c15SRodney W. Grimesat the head of the tail queue, or at the end of the tail queue.
258afe61c15SRodney W. GrimesA
259afe61c15SRodney W. Grimes.Fa TAILQ_HEAD
260afe61c15SRodney W. Grimesstructure is declared as follows:
261afe61c15SRodney W. Grimes.Bd -literal -offset indent
262afe61c15SRodney W. GrimesTAILQ_HEAD(HEADNAME, TYPE) head;
263afe61c15SRodney W. Grimes.Ed
264afe61c15SRodney W. Grimes.sp
265afe61c15SRodney W. Grimeswhere
266afe61c15SRodney W. Grimes.Li HEADNAME
267afe61c15SRodney W. Grimesis the name of the structure to be defined, and
268afe61c15SRodney W. Grimes.Li TYPE
269afe61c15SRodney W. Grimesis the type of the elements to be linked into the tail queue.
270afe61c15SRodney W. GrimesA pointer to the head of the tail queue can later be declared as:
271afe61c15SRodney W. Grimes.Bd -literal -offset indent
272afe61c15SRodney W. Grimesstruct HEADNAME *headp;
273afe61c15SRodney W. Grimes.Ed
274afe61c15SRodney W. Grimes.sp
275afe61c15SRodney W. Grimes(The names
276afe61c15SRodney W. Grimes.Li head
277afe61c15SRodney W. Grimesand
278afe61c15SRodney W. Grimes.Li headp
279afe61c15SRodney W. Grimesare user selectable.)
280afe61c15SRodney W. Grimes.Pp
281afe61c15SRodney W. GrimesThe macro
282afe61c15SRodney W. Grimes.Nm TAILQ_ENTRY
283afe61c15SRodney W. Grimesdeclares a structure that connects the elements in
284afe61c15SRodney W. Grimesthe tail queue.
285afe61c15SRodney W. Grimes.Pp
286afe61c15SRodney W. GrimesThe macro
287afe61c15SRodney W. Grimes.Nm TAILQ_INIT
288afe61c15SRodney W. Grimesinitializes the tail queue referenced by
289afe61c15SRodney W. Grimes.Fa head .
290afe61c15SRodney W. Grimes.Pp
291afe61c15SRodney W. GrimesThe macro
292afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_HEAD
293afe61c15SRodney W. Grimesinserts the new element
294afe61c15SRodney W. Grimes.Fa elm
295afe61c15SRodney W. Grimesat the head of the tail queue.
296afe61c15SRodney W. Grimes.Pp
297afe61c15SRodney W. GrimesThe macro
298afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_TAIL
299afe61c15SRodney W. Grimesinserts the new element
300afe61c15SRodney W. Grimes.Fa elm
301afe61c15SRodney W. Grimesat the end of the tail queue.
302afe61c15SRodney W. Grimes.Pp
303afe61c15SRodney W. GrimesThe macro
304afe61c15SRodney W. Grimes.Nm TAILQ_INSERT_AFTER
305afe61c15SRodney W. Grimesinserts the new element
306afe61c15SRodney W. Grimes.Fa elm
307afe61c15SRodney W. Grimesafter the element
308afe61c15SRodney W. Grimes.Fa listelm .
309afe61c15SRodney W. Grimes.Pp
310afe61c15SRodney W. GrimesThe macro
311afe61c15SRodney W. Grimes.Nm TAILQ_REMOVE
312afe61c15SRodney W. Grimesremoves the element
313afe61c15SRodney W. Grimes.Fa elm
314afe61c15SRodney W. Grimesfrom the tail queue.
315afe61c15SRodney W. Grimes.Sh TAIL QUEUE EXAMPLE
316afe61c15SRodney W. Grimes.Bd -literal
317afe61c15SRodney W. GrimesTAILQ_HEAD(tailhead, entry) head;
318afe61c15SRodney W. Grimesstruct tailhead *headp;		/* Tail queue head. */
319afe61c15SRodney W. Grimesstruct entry {
320afe61c15SRodney W. Grimes	...
321afe61c15SRodney W. Grimes	TAILQ_ENTRY(entry) entries;	/* Tail queue. */
322afe61c15SRodney W. Grimes	...
323afe61c15SRodney W. Grimes} *n1, *n2, *np;
324afe61c15SRodney W. Grimes
325afe61c15SRodney W. GrimesTAILQ_INIT(&head);			/* Initialize the queue. */
326afe61c15SRodney W. Grimes
327afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
328afe61c15SRodney W. GrimesTAILQ_INSERT_HEAD(&head, n1, entries);
329afe61c15SRodney W. Grimes
330afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the tail. */
331afe61c15SRodney W. GrimesTAILQ_INSERT_TAIL(&head, n1, entries);
332afe61c15SRodney W. Grimes
333afe61c15SRodney W. Grimesn2 = malloc(sizeof(struct entry));	/* Insert after. */
334afe61c15SRodney W. GrimesTAILQ_INSERT_AFTER(&head, n1, n2, entries);
335afe61c15SRodney W. Grimes					/* Forward traversal. */
336afe61c15SRodney W. Grimesfor (np = head.tqh_first; np != NULL; np = np->entries.tqe_next)
337afe61c15SRodney W. Grimes	np-> ...
338afe61c15SRodney W. Grimes					/* Delete. */
339afe61c15SRodney W. Grimeswhile (head.tqh_first != NULL)
340afe61c15SRodney W. Grimes	TAILQ_REMOVE(&head, head.tqh_first, entries);
341afe61c15SRodney W. Grimes.Ed
342afe61c15SRodney W. Grimes.Sh CIRCULAR QUEUES
343afe61c15SRodney W. GrimesA circular queue is headed by a structure defined by the
344afe61c15SRodney W. Grimes.Nm CIRCLEQ_HEAD
345afe61c15SRodney W. Grimesmacro.
346afe61c15SRodney W. GrimesThis structure contains a pair of pointers,
347afe61c15SRodney W. Grimesone to the first element in the circular queue and the other to the
348afe61c15SRodney W. Grimeslast element in the circular queue.
349afe61c15SRodney W. GrimesThe elements are doubly linked so that an arbitrary element can be
350afe61c15SRodney W. Grimesremoved without traversing the queue.
351afe61c15SRodney W. GrimesNew elements can be added to the queue after an existing element,
352afe61c15SRodney W. Grimesbefore an existing element, at the head of the queue, or at the end
353afe61c15SRodney W. Grimesof the queue.
354afe61c15SRodney W. GrimesA
355afe61c15SRodney W. Grimes.Fa CIRCLEQ_HEAD
356afe61c15SRodney W. Grimesstructure is declared as follows:
357afe61c15SRodney W. Grimes.Bd -literal -offset indent
358afe61c15SRodney W. GrimesCIRCLEQ_HEAD(HEADNAME, TYPE) head;
359afe61c15SRodney W. Grimes.Ed
360afe61c15SRodney W. Grimes.sp
361afe61c15SRodney W. Grimeswhere
362afe61c15SRodney W. Grimes.Li HEADNAME
363afe61c15SRodney W. Grimesis the name of the structure to be defined, and
364afe61c15SRodney W. Grimes.Li TYPE
365afe61c15SRodney W. Grimesis the type of the elements to be linked into the circular queue.
366afe61c15SRodney W. GrimesA pointer to the head of the circular queue can later be declared as:
367afe61c15SRodney W. Grimes.Bd -literal -offset indent
368afe61c15SRodney W. Grimesstruct HEADNAME *headp;
369afe61c15SRodney W. Grimes.Ed
370afe61c15SRodney W. Grimes.sp
371afe61c15SRodney W. Grimes(The names
372afe61c15SRodney W. Grimes.Li head
373afe61c15SRodney W. Grimesand
374afe61c15SRodney W. Grimes.Li headp
375afe61c15SRodney W. Grimesare user selectable.)
376afe61c15SRodney W. Grimes.Pp
377afe61c15SRodney W. GrimesThe macro
378afe61c15SRodney W. Grimes.Nm CIRCLEQ_ENTRY
379afe61c15SRodney W. Grimesdeclares a structure that connects the elements in
380afe61c15SRodney W. Grimesthe circular queue.
381afe61c15SRodney W. Grimes.Pp
382afe61c15SRodney W. GrimesThe macro
383afe61c15SRodney W. Grimes.Nm CIRCLEQ_INIT
384afe61c15SRodney W. Grimesinitializes the circular queue referenced by
385afe61c15SRodney W. Grimes.Fa head .
386afe61c15SRodney W. Grimes.Pp
387afe61c15SRodney W. GrimesThe macro
388afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_HEAD
389afe61c15SRodney W. Grimesinserts the new element
390afe61c15SRodney W. Grimes.Fa elm
391afe61c15SRodney W. Grimesat the head of the circular queue.
392afe61c15SRodney W. Grimes.Pp
393afe61c15SRodney W. GrimesThe macro
394afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_TAIL
395afe61c15SRodney W. Grimesinserts the new element
396afe61c15SRodney W. Grimes.Fa elm
397afe61c15SRodney W. Grimesat the end of the circular queue.
398afe61c15SRodney W. Grimes.Pp
399afe61c15SRodney W. GrimesThe macro
400afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_AFTER
401afe61c15SRodney W. Grimesinserts the new element
402afe61c15SRodney W. Grimes.Fa elm
403afe61c15SRodney W. Grimesafter the element
404afe61c15SRodney W. Grimes.Fa listelm .
405afe61c15SRodney W. Grimes.Pp
406afe61c15SRodney W. GrimesThe macro
407afe61c15SRodney W. Grimes.Nm CIRCLEQ_INSERT_BEFORE
408afe61c15SRodney W. Grimesinserts the new element
409afe61c15SRodney W. Grimes.Fa elm
410afe61c15SRodney W. Grimesbefore the element
411afe61c15SRodney W. Grimes.Fa listelm .
412afe61c15SRodney W. Grimes.Pp
413afe61c15SRodney W. GrimesThe macro
414afe61c15SRodney W. Grimes.Nm CIRCLEQ_REMOVE
415afe61c15SRodney W. Grimesremoves the element
416afe61c15SRodney W. Grimes.Fa elm
417afe61c15SRodney W. Grimesfrom the circular queue.
418afe61c15SRodney W. Grimes.Sh CIRCULAR QUEUE EXAMPLE
419afe61c15SRodney W. Grimes.Bd -literal
420afe61c15SRodney W. GrimesCIRCLEQ_HEAD(circleq, entry) head;
421afe61c15SRodney W. Grimesstruct circleq *headp;			/* Circular queue head. */
422afe61c15SRodney W. Grimesstruct entry {
423afe61c15SRodney W. Grimes	...
424afe61c15SRodney W. Grimes	CIRCLEQ_ENTRY entries;		/* Circular queue. */
425afe61c15SRodney W. Grimes	...
426afe61c15SRodney W. Grimes} *n1, *n2, *np;
427afe61c15SRodney W. Grimes
428afe61c15SRodney W. GrimesCIRCLEQ_INIT(&head);			/* Initialize the circular queue. */
429afe61c15SRodney W. Grimes
430afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the head. */
431afe61c15SRodney W. GrimesCIRCLEQ_INSERT_HEAD(&head, n1, entries);
432afe61c15SRodney W. Grimes
433afe61c15SRodney W. Grimesn1 = malloc(sizeof(struct entry));	/* Insert at the tail. */
434afe61c15SRodney W. GrimesCIRCLEQ_INSERT_TAIL(&head, n1, entries);
435afe61c15SRodney W. Grimes
436afe61c15SRodney W. Grimesn2 = malloc(sizeof(struct entry));	/* Insert after. */
437afe61c15SRodney W. GrimesCIRCLEQ_INSERT_AFTER(&head, n1, n2, entries);
438afe61c15SRodney W. Grimes
439afe61c15SRodney W. Grimesn2 = malloc(sizeof(struct entry));	/* Insert before. */
440afe61c15SRodney W. GrimesCIRCLEQ_INSERT_BEFORE(&head, n1, n2, entries);
441afe61c15SRodney W. Grimes					/* Forward traversal. */
442afe61c15SRodney W. Grimesfor (np = head.cqh_first; np != (void *)&head; np = np->entries.cqe_next)
443afe61c15SRodney W. Grimes	np-> ...
444afe61c15SRodney W. Grimes					/* Reverse traversal. */
445afe61c15SRodney W. Grimesfor (np = head.cqh_last; np != (void *)&head; np = np->entries.cqe_prev)
446afe61c15SRodney W. Grimes	np-> ...
447afe61c15SRodney W. Grimes					/* Delete. */
448afe61c15SRodney W. Grimeswhile (head.cqh_first != (void *)&head)
449afe61c15SRodney W. Grimes	CIRCLEQ_REMOVE(&head, head.cqh_first, entries);
450afe61c15SRodney W. Grimes.Ed
451afe61c15SRodney W. Grimes.Sh HISTORY
452afe61c15SRodney W. GrimesThe
453afe61c15SRodney W. Grimes.Nm queue
454afe61c15SRodney W. Grimesfunctions first appeared in 4.4BSD.
455