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