xref: /freebsd/share/man/man3/queue.3 (revision ef5d438ed4bc17ad7ece3e40fe4d1f9baf3aadf7)
1.\" Copyright (c) 1993
2.\"	The Regents of the University of California.  All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\"    notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\"    notice, this list of conditions and the following disclaimer in the
11.\"    documentation and/or other materials provided with the distribution.
12.\" 3. All advertising materials mentioning features or use of this software
13.\"    must display the following acknowledgement:
14.\"	This product includes software developed by the University of
15.\"	California, Berkeley and its contributors.
16.\" 4. Neither the name of the University nor the names of its contributors
17.\"    may be used to endorse or promote products derived from this software
18.\"    without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE.
31.\"
32.\"	@(#)queue.3	8.2 (Berkeley) 1/24/94
33.\"
34.Dd "January 24, 1994"
35.Dt QUEUE 3
36.Os BSD 4
37.Sh NAME
38.Nm LIST_ENTRY ,
39.Nm LIST_HEAD ,
40.Nm LIST_INIT ,
41.Nm LIST_INSERT_AFTER ,
42.Nm LIST_INSERT_BEFORE ,
43.Nm LIST_INSERT_HEAD ,
44.Nm LIST_REMOVE ,
45.Nm TAILQ_ENTRY ,
46.Nm TAILQ_HEAD ,
47.Nm TAILQ_INIT ,
48.Nm TAILQ_INSERT_AFTER ,
49.Nm TAILQ_INSERT_BEFORE ,
50.Nm TAILQ_INSERT_HEAD ,
51.Nm TAILQ_INSERT_TAIL ,
52.Nm TAILQ_REMOVE ,
53.Nm CIRCLEQ_ENTRY ,
54.Nm CIRCLEQ_HEAD ,
55.Nm CIRCLEQ_INIT ,
56.Nm CIRCLEQ_INSERT_AFTER ,
57.Nm CIRCLEQ_INSERT_BEFORE ,
58.Nm CIRCLEQ_INSERT_HEAD ,
59.Nm CIRCLEQ_INSERT_TAIL ,
60.Nm CIRCLEQ_REMOVE
61.Nd implementations of lists, tail queues, and circular queues
62.Sh SYNOPSIS
63.Fd #include <sys/queue.h>
64.sp
65.Fn LIST_ENTRY "TYPE"
66.Fn LIST_HEAD "HEADNAME" "TYPE"
67.Fn LIST_INIT "LIST_HEAD *head"
68.Fn LIST_INSERT_AFTER "LIST_ENTRY *listelm" "TYPE *elm" "LIST_ENTRY NAME"
69.Fn LIST_INSERT_BEFORE "LIST_ENTRY *listelm" "TYPE *elm" "LIST_ENTRY NAME"
70.Fn LIST_INSERT_HEAD "LIST_HEAD *head" "TYPE *elm" "LIST_ENTRY NAME"
71.Fn LIST_REMOVE "TYPE *elm" "LIST_ENTRY NAME"
72.sp
73.Fn TAILQ_ENTRY "TYPE"
74.Fn TAILQ_HEAD "HEADNAME" "TYPE"
75.Fn TAILQ_INIT "TAILQ_HEAD *head"
76.Fn TAILQ_INSERT_AFTER "TAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME"
77.Fn TAILQ_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME"
78.Fn TAILQ_INSERT_HEAD "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
79.Fn TAILQ_INSERT_TAIL "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
80.Fn TAILQ_REMOVE "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
81.sp
82.Fn CIRCLEQ_ENTRY "TYPE"
83.Fn CIRCLEQ_HEAD "HEADNAME" "TYPE"
84.Fn CIRCLEQ_INIT "CIRCLEQ_HEAD *head"
85.Fn CIRCLEQ_INSERT_AFTER "CIRCLEQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
86.Fn CIRCLEQ_INSERT_BEFORE "CIRCLEQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
87.Fn CIRCLEQ_INSERT_HEAD "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
88.Fn CIRCLEQ_INSERT_TAIL "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
89.Fn CIRCLEQ_REMOVE "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
90.Sh DESCRIPTION
91These macros define and operate on three types of data structures:
92lists, tail queues, and circular queues.
93All three structures support the following functionality:
94.Bl -enum -compact -offset indent
95.It
96Insertion of a new entry at the head of the list.
97.It
98Insertion of a new entry after any element in the list.
99.It
100Insertion of a new entry before any element in the list.
101.It
102Removal of any entry in the list.
103.It
104Forward traversal through the list.
105.El
106.Pp
107Lists are the simplest of the three data structures and support
108only the above functionality.
109.Pp
110Tail queues add the following functionality:
111.Bl -enum -compact -offset indent
112.It
113Entries can be added at the end of a list.
114.El
115However:
116.Bl -enum -compact -offset indent
117.It
118All list insertions and removals must specify the head of the list.
119.It
120Each head entry requires two pointers rather than one.
121.It
122Code size is about 15% greater and operations run about 20% slower
123than lists.
124.El
125.Pp
126Circular queues add the following functionality:
127.Bl -enum -compact -offset indent
128.It
129Entries can be added at the end of a list.
130.It
131They may be traversed backwards, from tail to head.
132.El
133However:
134.Bl -enum -compact -offset indent
135.It
136All list insertions and removals must specify the head of the list.
137.It
138Each head entry requires two pointers rather than one.
139.It
140The termination condition for traversal is more complex.
141.It
142Code size is about 40% greater and operations run about 45% slower
143than lists.
144.El
145.Pp
146In the macro definitions,
147.Fa TYPE
148is the name of a user defined structure,
149that must contain a field of type
150.Li LIST_ENTRY ,
151.Li TAILQ_ENTRY ,
152or
153.Li CIRCLEQ_ENTRY ,
154named
155.Fa NAME .
156The argument
157.Fa HEADNAME
158is the name of a user defined structure that must be declared
159using the macros
160.Li LIST_HEAD ,
161.Li TAILQ_HEAD ,
162or
163.Li CIRCLEQ_HEAD .
164See the examples below for further explanation of how these
165macros are used.
166.Sh LISTS
167A list is headed by a structure defined by the
168.Nm LIST_HEAD
169macro.
170This structure contains a single pointer to the first element
171on the list.
172The elements are doubly linked so that an arbitrary element can be
173removed without traversing the list.
174New elements can be added to the list after an existing element or
175at the head of the list.
176A
177.Fa LIST_HEAD
178structure is declared as follows:
179.Bd -literal -offset indent
180LIST_HEAD(HEADNAME, TYPE) head;
181.Ed
182.sp
183where
184.Fa HEADNAME
185is the name of the structure to be defined, and
186.Fa TYPE
187is the type of the elements to be linked into the list.
188A pointer to the head of the list can later be declared as:
189.Bd -literal -offset indent
190struct HEADNAME *headp;
191.Ed
192.sp
193(The names
194.Li head
195and
196.Li headp
197are user selectable.)
198.Pp
199The macro
200.Nm LIST_ENTRY
201declares a structure that connects the elements in
202the list.
203.Pp
204The macro
205.Nm LIST_INIT
206initializes the list referenced by
207.Fa head .
208.Pp
209The macro
210.Nm LIST_INSERT_HEAD
211inserts the new element
212.Fa elm
213at the head of the list.
214.Pp
215The macro
216.Nm LIST_INSERT_AFTER
217inserts the new element
218.Fa elm
219after the element
220.Fa listelm .
221.Pp
222The macro
223.Nm LIST_INSERT_BEFORE
224inserts the new element
225.Fa elm
226before the element
227.Fa listelm .
228.Pp
229The macro
230.Nm LIST_REMOVE
231removes the element
232.Fa elm
233from the list.
234.Sh LIST EXAMPLE
235.Bd -literal
236LIST_HEAD(listhead, entry) head;
237struct listhead *headp;		/* List head. */
238struct entry {
239	...
240	LIST_ENTRY(entry) entries;	/* List. */
241	...
242} *n1, *n2, *n3, *np;
243
244LIST_INIT(&head);			/* Initialize the list. */
245
246n1 = malloc(sizeof(struct entry));	/* Insert at the head. */
247LIST_INSERT_HEAD(&head, n1, entries);
248
249n2 = malloc(sizeof(struct entry));	/* Insert after. */
250LIST_INSERT_AFTER(n1, n2, entries);
251
252n3 = malloc(sizeof(struct entry));	/* Insert before. */
253LIST_INSERT_BEFORE(n2, n3, entries);
254
255LIST_REMOVE(n2, entries);		/* Deletion. */
256free(n2);
257
258					/* Forward traversal. */
259for (np = head.lh_first; np != NULL; np = np->entries.le_next)
260	np-> ...
261
262while (head.lh_first != NULL) {		/* List Deletion. */
263	n1 = head.lh_first;
264	LIST_REMOVE(n1, entries);
265	free(n1);
266}
267
268n1 = head.lh_first;			/* Faster List Delete. */
269while (n1 != NULL) {
270	n2 = n1->entires.le_next;
271	free(n1);
272	n1 = n2;
273}
274LIST_INIT(&head);
275
276.Ed
277.Sh TAIL QUEUES
278A tail queue is headed by a structure defined by the
279.Nm TAILQ_HEAD
280macro.
281This structure contains a pair of pointers,
282one to the first element in the tail queue and the other to
283the last element in the tail queue.
284The elements are doubly linked so that an arbitrary element can be
285removed without traversing the tail queue.
286New elements can be added to the tail queue after an existing element,
287at the head of the tail queue, or at the end of the tail queue.
288A
289.Fa TAILQ_HEAD
290structure is declared as follows:
291.Bd -literal -offset indent
292TAILQ_HEAD(HEADNAME, TYPE) head;
293.Ed
294.sp
295where
296.Li HEADNAME
297is the name of the structure to be defined, and
298.Li TYPE
299is the type of the elements to be linked into the tail queue.
300A pointer to the head of the tail queue can later be declared as:
301.Bd -literal -offset indent
302struct HEADNAME *headp;
303.Ed
304.sp
305(The names
306.Li head
307and
308.Li headp
309are user selectable.)
310.Pp
311The macro
312.Nm TAILQ_ENTRY
313declares a structure that connects the elements in
314the tail queue.
315.Pp
316The macro
317.Nm TAILQ_INIT
318initializes the tail queue referenced by
319.Fa head .
320.Pp
321The macro
322.Nm TAILQ_INSERT_HEAD
323inserts the new element
324.Fa elm
325at the head of the tail queue.
326.Pp
327The macro
328.Nm TAILQ_INSERT_TAIL
329inserts the new element
330.Fa elm
331at the end of the tail queue.
332.Pp
333The macro
334.Nm TAILQ_INSERT_AFTER
335inserts the new element
336.Fa elm
337after the element
338.Fa listelm .
339.Pp
340The macro
341.Nm TAILQ_INSERT_BEFORE
342inserts the new element
343.Fa elm
344before the element
345.Fa listelm .
346.Pp
347The macro
348.Nm TAILQ_REMOVE
349removes the element
350.Fa elm
351from the tail queue.
352.Sh TAIL QUEUE EXAMPLE
353.Bd -literal
354TAILQ_HEAD(tailhead, entry) head;
355struct tailhead *headp;		/* Tail queue head. */
356struct entry {
357	...
358	TAILQ_ENTRY(entry) entries;	/* Tail queue. */
359	...
360} *n1, *n2, *n3, *np;
361
362TAILQ_INIT(&head);			/* Initialize the queue. */
363
364n1 = malloc(sizeof(struct entry));	/* Insert at the head. */
365TAILQ_INSERT_HEAD(&head, n1, entries);
366
367n1 = malloc(sizeof(struct entry));	/* Insert at the tail. */
368TAILQ_INSERT_TAIL(&head, n1, entries);
369
370n2 = malloc(sizeof(struct entry));	/* Insert after. */
371TAILQ_INSERT_AFTER(&head, n1, n2, entries);
372
373n3 = malloc(sizeof(struct entry));	/* Insert before. */
374TAILQ_INSERT_BEFORE(n2, n3, entries);
375
376TAILQ_REMOVE(&head, n2, entries);	/* Deletion. */
377free(n2);
378					/* Forward traversal. */
379for (np = head.tqh_first; np != NULL; np = np->entries.tqe_next)
380	np-> ...
381					/* TailQ Deletion. */
382while (head.tqh_first != NULL) {
383	n1 = head.tqh_first;
384	TAILQ_REMOVE(&head, head.tqh_first, entries);
385	free(n1);
386}
387					/* Faster TailQ Deletion. */
388n1 = head.tqh_first;
389while (n1 != NULL) {
390	n2 = n1->entries.tqe_next;
391	free(n1);
392	n1 = n2;
393}
394TAILQ_INIT(&head);
395.Ed
396.Sh CIRCULAR QUEUES
397A circular queue is headed by a structure defined by the
398.Nm CIRCLEQ_HEAD
399macro.
400This structure contains a pair of pointers,
401one to the first element in the circular queue and the other to the
402last element in the circular queue.
403The elements are doubly linked so that an arbitrary element can be
404removed without traversing the queue.
405New elements can be added to the queue after an existing element,
406before an existing element, at the head of the queue, or at the end
407of the queue.
408A
409.Fa CIRCLEQ_HEAD
410structure is declared as follows:
411.Bd -literal -offset indent
412CIRCLEQ_HEAD(HEADNAME, TYPE) head;
413.Ed
414.sp
415where
416.Li HEADNAME
417is the name of the structure to be defined, and
418.Li TYPE
419is the type of the elements to be linked into the circular queue.
420A pointer to the head of the circular queue can later be declared as:
421.Bd -literal -offset indent
422struct HEADNAME *headp;
423.Ed
424.sp
425(The names
426.Li head
427and
428.Li headp
429are user selectable.)
430.Pp
431The macro
432.Nm CIRCLEQ_ENTRY
433declares a structure that connects the elements in
434the circular queue.
435.Pp
436The macro
437.Nm CIRCLEQ_INIT
438initializes the circular queue referenced by
439.Fa head .
440.Pp
441The macro
442.Nm CIRCLEQ_INSERT_HEAD
443inserts the new element
444.Fa elm
445at the head of the circular queue.
446.Pp
447The macro
448.Nm CIRCLEQ_INSERT_TAIL
449inserts the new element
450.Fa elm
451at the end of the circular queue.
452.Pp
453The macro
454.Nm CIRCLEQ_INSERT_AFTER
455inserts the new element
456.Fa elm
457after the element
458.Fa listelm .
459.Pp
460The macro
461.Nm CIRCLEQ_INSERT_BEFORE
462inserts the new element
463.Fa elm
464before the element
465.Fa listelm .
466.Pp
467The macro
468.Nm CIRCLEQ_REMOVE
469removes the element
470.Fa elm
471from the circular queue.
472.Sh CIRCULAR QUEUE EXAMPLE
473.Bd -literal
474CIRCLEQ_HEAD(circleq, entry) head;
475struct circleq *headp;			/* Circular queue head. */
476struct entry {
477	...
478	CIRCLEQ_ENTRY entries;		/* Circular queue. */
479	...
480} *n1, *n2, *np;
481
482CIRCLEQ_INIT(&head);			/* Initialize the circular queue. */
483
484n1 = malloc(sizeof(struct entry));	/* Insert at the head. */
485CIRCLEQ_INSERT_HEAD(&head, n1, entries);
486
487n1 = malloc(sizeof(struct entry));	/* Insert at the tail. */
488CIRCLEQ_INSERT_TAIL(&head, n1, entries);
489
490n2 = malloc(sizeof(struct entry));	/* Insert after. */
491CIRCLEQ_INSERT_AFTER(&head, n1, n2, entries);
492
493n2 = malloc(sizeof(struct entry));	/* Insert before. */
494CIRCLEQ_INSERT_BEFORE(&head, n1, n2, entries);
495
496CIRCLEQ_REMOVE(&head, n1, entries);	/* Deletion. */
497free(n1);
498					/* Forward traversal. */
499for (np = head.cqh_first; np != (void *)&head; np = np->entries.cqe_next)
500	np-> ...
501					/* Reverse traversal. */
502for (np = head.cqh_last; np != (void *)&head; np = np->entries.cqe_prev)
503	np-> ...
504					/* CircleQ Deletion. */
505while (head.cqh_first != (void *)&head) {
506	n1 = head.cqh_first;
507	CIRCLEQ_REMOVE(&head, head.cqh_first, entries);
508	free(n1);
509}
510					/* Faster CircleQ Deletion. */
511n1 = head.cqh_first;
512while (n1 != (void *)&head) {
513	n2 = n1->entries.cqh_next;
514	free(n1);
515	n1 = n2;
516}
517CIRCLEQ_INIT(&head);
518.Ed
519.Sh HISTORY
520The
521.Nm queue
522functions first appeared in 4.4BSD.
523