queue.h revision 60938
1/*
2 * Copyright (c) 1991, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *	This product includes software developed by the University of
16 *	California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 *	@(#)queue.h	8.5 (Berkeley) 8/20/94
34 * $FreeBSD: head/sys/sys/queue.h 60938 2000-05-26 02:09:24Z jake $
35 */
36
37#ifndef _SYS_QUEUE_H_
38#define	_SYS_QUEUE_H_
39
40/*
41 * This file defines five types of data structures: singly-linked lists,
42 * singly-linked tail queues, lists, tail queues, and circular queues.
43 *
44 * A singly-linked list is headed by a single forward pointer. The elements
45 * are singly linked for minimum space and pointer manipulation overhead at
46 * the expense of O(n) removal for arbitrary elements. New elements can be
47 * added to the list after an existing element or at the head of the list.
48 * Elements being removed from the head of the list should use the explicit
49 * macro for this purpose for optimum efficiency. A singly-linked list may
50 * only be traversed in the forward direction.  Singly-linked lists are ideal
51 * for applications with large datasets and few or no removals or for
52 * implementing a LIFO queue.
53 *
54 * A singly-linked tail queue is headed by a pair of pointers, one to the
55 * head of the list and the other to the tail of the list. The elements are
56 * singly linked for minimum space and pointer manipulation overhead at the
57 * expense of O(n) removal for arbitrary elements. New elements can be added
58 * to the list after an existing element, at the head of the list, or at the
59 * end of the list. Elements being removed from the head of the tail queue
60 * should use the explicit macro for this purpose for optimum efficiency.
61 * A singly-linked tail queue may only be traversed in the forward direction.
62 * Singly-linked tail queues are ideal for applications with large datasets
63 * and few or no removals or for implementing a FIFO queue.
64 *
65 * A list is headed by a single forward pointer (or an array of forward
66 * pointers for a hash table header). The elements are doubly linked
67 * so that an arbitrary element can be removed without a need to
68 * traverse the list. New elements can be added to the list before
69 * or after an existing element or at the head of the list. A list
70 * may only be traversed in the forward direction.
71 *
72 * A tail queue is headed by a pair of pointers, one to the head of the
73 * list and the other to the tail of the list. The elements are doubly
74 * linked so that an arbitrary element can be removed without a need to
75 * traverse the list. New elements can be added to the list before or
76 * after an existing element, at the head of the list, or at the end of
77 * the list. A tail queue may be traversed in either direction.
78 *
79 * A circle queue is headed by a pair of pointers, one to the head of the
80 * list and the other to the tail of the list. The elements are doubly
81 * linked so that an arbitrary element can be removed without a need to
82 * traverse the list. New elements can be added to the list before or after
83 * an existing element, at the head of the list, or at the end of the list.
84 * A circle queue may be traversed in either direction, but has a more
85 * complex end of list detection.
86 *
87 * For details on the use of these macros, see the queue(3) manual page.
88 *
89 *
90 *			SLIST	LIST	STAILQ	TAILQ	CIRCLEQ
91 * _HEAD		+	+	+	+	+
92 * _HEAD_INITIALIZER	+	+	+	+	+
93 * _ENTRY		+	+	+	+	+
94 * _INIT		+	+	+	+	+
95 * _EMPTY		+	+	+	+	+
96 * _FIRST		+	+	+	+	+
97 * _NEXT		+	+	+	+	+
98 * _PREV		-	-	-	+	+
99 * _LAST		-	-	+	+	+
100 * _FOREACH		+	+	+	+	+
101 * _FOREACH_REVERSE	-	-	-	+	+
102 * _INSERT_HEAD		+	+	+	+	+
103 * _INSERT_BEFORE	-	+	-	+	+
104 * _INSERT_AFTER	+	+	+	+	+
105 * _INSERT_TAIL		-	-	+	+	+
106 * _REMOVE_HEAD		+	-	+	-	-
107 * _REMOVE		+	+	+	+	+
108 *
109 */
110
111/*
112 * Singly-linked List declarations.
113 */
114#define	SLIST_HEAD(name, type)						\
115struct name {								\
116	struct type *slh_first;	/* first element */			\
117}
118
119#define	SLIST_HEAD_INITIALIZER(head)					\
120	{ NULL }
121
122#define	SLIST_ENTRY(type)						\
123struct {								\
124	struct type *sle_next;	/* next element */			\
125}
126
127/*
128 * Singly-linked List functions.
129 */
130#define	SLIST_EMPTY(head)	((head)->slh_first == NULL)
131
132#define	SLIST_FIRST(head)	((head)->slh_first)
133
134#define	SLIST_FOREACH(var, head, field)					\
135	for ((var) = SLIST_FIRST((head));				\
136	    (var);							\
137	    (var) = SLIST_NEXT((var), field))
138
139#define	SLIST_INIT(head) do {						\
140	SLIST_FIRST((head)) = NULL;					\
141} while (0)
142
143#define	SLIST_INSERT_AFTER(slistelm, elm, field) do {			\
144	SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field);	\
145	SLIST_NEXT((slistelm), field) = (elm);				\
146} while (0)
147
148#define	SLIST_INSERT_HEAD(head, elm, field) do {			\
149	SLIST_NEXT((elm), field) = SLIST_FIRST((head));			\
150	SLIST_FIRST((head)) = (elm);					\
151} while (0)
152
153#define	SLIST_NEXT(elm, field)	((elm)->field.sle_next)
154
155#define	SLIST_REMOVE(head, elm, type, field) do {			\
156	if (SLIST_FIRST((head)) == (elm)) {				\
157		SLIST_REMOVE_HEAD((head), field);			\
158	}								\
159	else {								\
160		struct type *curelm = SLIST_FIRST((head));		\
161		while (SLIST_NEXT(curelm, field) != (elm))		\
162			curelm = SLIST_NEXT(curelm, field);		\
163		SLIST_NEXT(curelm, field) =				\
164		    SLIST_NEXT(SLIST_NEXT(curelm, field), field);	\
165	}								\
166} while (0)
167
168#define	SLIST_REMOVE_HEAD(head, field) do {				\
169	SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field);	\
170} while (0)
171
172/*
173 * Singly-linked Tail queue declarations.
174 */
175#define	STAILQ_HEAD(name, type)						\
176struct name {								\
177	struct type *stqh_first;/* first element */			\
178	struct type **stqh_last;/* addr of last next element */		\
179}
180
181#define	STAILQ_HEAD_INITIALIZER(head)					\
182	{ NULL, &(head).stqh_first }
183
184#define	STAILQ_ENTRY(type)						\
185struct {								\
186	struct type *stqe_next;	/* next element */			\
187}
188
189/*
190 * Singly-linked Tail queue functions.
191 */
192#define	STAILQ_EMPTY(head)	((head)->stqh_first == NULL)
193
194#define	STAILQ_FIRST(head)	((head)->stqh_first)
195
196#define	STAILQ_FOREACH(var, head, field)				\
197	for((var) = STAILQ_FIRST((head));				\
198	   (var);							\
199	   (var) = STAILQ_NEXT((var), field))
200
201#define	STAILQ_INIT(head) do {						\
202	STAILQ_FIRST((head)) = NULL;					\
203	(head)->stqh_last = &STAILQ_FIRST((head));			\
204} while (0)
205
206#define	STAILQ_INSERT_AFTER(head, tqelm, elm, field) do {		\
207	if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
208		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
209	STAILQ_NEXT((tqelm), field) = (elm);				\
210} while (0)
211
212#define	STAILQ_INSERT_HEAD(head, elm, field) do {			\
213	if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL)	\
214		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
215	STAILQ_FIRST((head)) = (elm);					\
216} while (0)
217
218#define	STAILQ_INSERT_TAIL(head, elm, field) do {			\
219	STAILQ_NEXT((elm), field) = NULL;				\
220	STAILQ_LAST((head)) = (elm);					\
221	(head)->stqh_last = &STAILQ_NEXT((elm), field);			\
222} while (0)
223
224#define	STAILQ_LAST(head)	(*(head)->stqh_last)
225
226#define	STAILQ_NEXT(elm, field)	((elm)->field.stqe_next)
227
228#define	STAILQ_REMOVE(head, elm, type, field) do {			\
229	if (STAILQ_FIRST((head)) == (elm)) {				\
230		STAILQ_REMOVE_HEAD(head, field);			\
231	}								\
232	else {								\
233		struct type *curelm = STAILQ_FIRST((head));		\
234		while (STAILQ_NEXT(curelm, field) != (elm))		\
235			curelm = STAILQ_NEXT(curelm, field);		\
236		if ((STAILQ_NEXT(curelm, field) =			\
237		     STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\
238			(head)->stqh_last = &STAILQ_NEXT((curelm), field);\
239	}								\
240} while (0)
241
242#define	STAILQ_REMOVE_HEAD(head, field) do {				\
243	if ((STAILQ_FIRST((head)) =					\
244	     STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL)		\
245		(head)->stqh_last = &STAILQ_FIRST((head));		\
246} while (0)
247
248#define	STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do {			\
249	if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL)	\
250		(head)->stqh_last = &STAILQ_FIRST((head));		\
251} while (0)
252
253/*
254 * List declarations.
255 */
256#define	LIST_HEAD(name, type)						\
257struct name {								\
258	struct type *lh_first;	/* first element */			\
259}
260
261#define	LIST_HEAD_INITIALIZER(head)					\
262	{ NULL }
263
264#define	LIST_ENTRY(type)						\
265struct {								\
266	struct type *le_next;	/* next element */			\
267	struct type **le_prev;	/* address of previous next element */	\
268}
269
270/*
271 * List functions.
272 */
273
274#define	LIST_EMPTY(head)	((head)->lh_first == NULL)
275
276#define	LIST_FIRST(head)	((head)->lh_first)
277
278#define	LIST_FOREACH(var, head, field)					\
279	for ((var) = LIST_FIRST((head));				\
280	    (var);							\
281	    (var) = LIST_NEXT((var), field))
282
283#define	LIST_INIT(head) do {						\
284	LIST_FIRST((head)) = NULL;					\
285} while (0)
286
287#define	LIST_INSERT_AFTER(listelm, elm, field) do {			\
288	if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
289		LIST_NEXT((listelm), field)->field.le_prev =		\
290		    &LIST_NEXT((elm), field);				\
291	LIST_NEXT((listelm), field) = (elm);				\
292	(elm)->field.le_prev = &LIST_NEXT((listelm), field);		\
293} while (0)
294
295#define	LIST_INSERT_BEFORE(listelm, elm, field) do {			\
296	(elm)->field.le_prev = (listelm)->field.le_prev;		\
297	LIST_NEXT((elm), field) = (listelm);				\
298	*(listelm)->field.le_prev = (elm);				\
299	(listelm)->field.le_prev = &LIST_NEXT((elm), field);		\
300} while (0)
301
302#define	LIST_INSERT_HEAD(head, elm, field) do {				\
303	if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL)	\
304		LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
305	LIST_FIRST((head)) = (elm);					\
306	(elm)->field.le_prev = &LIST_FIRST((head));			\
307} while (0)
308
309#define	LIST_NEXT(elm, field)	((elm)->field.le_next)
310
311#define	LIST_REMOVE(elm, field) do {					\
312	if (LIST_NEXT((elm), field) != NULL)				\
313		LIST_NEXT((elm), field)->field.le_prev = 		\
314		    (elm)->field.le_prev;				\
315	*(elm)->field.le_prev = LIST_NEXT((elm), field);		\
316} while (0)
317
318/*
319 * Tail queue declarations.
320 */
321#define	TAILQ_HEAD(name, type)						\
322struct name {								\
323	struct type *tqh_first;	/* first element */			\
324	struct type **tqh_last;	/* addr of last next element */		\
325}
326
327#define	TAILQ_HEAD_INITIALIZER(head)					\
328	{ NULL, &(head).tqh_first }
329
330#define	TAILQ_ENTRY(type)						\
331struct {								\
332	struct type *tqe_next;	/* next element */			\
333	struct type **tqe_prev;	/* address of previous next element */	\
334}
335
336/*
337 * Tail queue functions.
338 */
339#define	TAILQ_EMPTY(head)	((head)->tqh_first == NULL)
340
341#define	TAILQ_FIRST(head)	((head)->tqh_first)
342
343#define	TAILQ_FOREACH(var, head, field)					\
344	for ((var) = TAILQ_FIRST((head));				\
345	    (var);							\
346	    (var) = TAILQ_NEXT((var), field))
347
348#define	TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
349	for ((var) = TAILQ_LAST((head), headname);			\
350	    (var);							\
351	    (var) = TAILQ_PREV((var), headname, field))
352
353#define	TAILQ_INIT(head) do {						\
354	TAILQ_FIRST((head)) = NULL;					\
355	(head)->tqh_last = &TAILQ_FIRST((head));			\
356} while (0)
357
358#define	TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
359	if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
360		TAILQ_NEXT((elm), field)->field.tqe_prev = 		\
361		    &TAILQ_NEXT((elm), field);				\
362	else								\
363		(head)->tqh_last = &TAILQ_NEXT((elm), field);		\
364	TAILQ_NEXT((listelm), field) = (elm);				\
365	(elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field);		\
366} while (0)
367
368#define	TAILQ_INSERT_BEFORE(listelm, elm, field) do {			\
369	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
370	TAILQ_NEXT((elm), field) = (listelm);				\
371	*(listelm)->field.tqe_prev = (elm);				\
372	(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field);		\
373} while (0)
374
375#define	TAILQ_INSERT_HEAD(head, elm, field) do {			\
376	if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL)	\
377		TAILQ_FIRST((head))->field.tqe_prev =			\
378		    &TAILQ_NEXT((elm), field);				\
379	else								\
380		(head)->tqh_last = &TAILQ_NEXT((elm), field);		\
381	TAILQ_FIRST((head)) = (elm);					\
382	(elm)->field.tqe_prev = &TAILQ_FIRST((head));			\
383} while (0)
384
385#define	TAILQ_INSERT_TAIL(head, elm, field) do {			\
386	TAILQ_NEXT((elm), field) = NULL;				\
387	(elm)->field.tqe_prev = (head)->tqh_last;			\
388	*(head)->tqh_last = (elm);					\
389	(head)->tqh_last = &TAILQ_NEXT((elm), field);			\
390} while (0)
391
392#define	TAILQ_LAST(head, headname)					\
393	(*(((struct headname *)((head)->tqh_last))->tqh_last))
394
395#define	TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
396
397#define	TAILQ_PREV(elm, headname, field)				\
398	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
399
400#define	TAILQ_REMOVE(head, elm, field) do {				\
401	if ((TAILQ_NEXT((elm), field)) != NULL)				\
402		TAILQ_NEXT((elm), field)->field.tqe_prev = 		\
403		    (elm)->field.tqe_prev;				\
404	else								\
405		(head)->tqh_last = (elm)->field.tqe_prev;		\
406	*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field);		\
407} while (0)
408
409/*
410 * Circular queue declarations.
411 */
412#define	CIRCLEQ_HEAD(name, type)					\
413struct name {								\
414	struct type *cqh_first;		/* first element */		\
415	struct type *cqh_last;		/* last element */		\
416}
417
418#define	CIRCLEQ_HEAD_INITIALIZER(head)					\
419	{ (void *)&(head), (void *)&(head) }
420
421#define	CIRCLEQ_ENTRY(type)						\
422struct {								\
423	struct type *cqe_next;		/* next element */		\
424	struct type *cqe_prev;		/* previous element */		\
425}
426
427/*
428 * Circular queue functions.
429 */
430#define	CIRCLEQ_EMPTY(head)	((head)->cqh_first == (void *)(head))
431
432#define	CIRCLEQ_FIRST(head)	((head)->cqh_first)
433
434#define	CIRCLEQ_FOREACH(var, head, field)				\
435	for ((var) = CIRCLEQ_FIRST((head));				\
436	    (var) != (void *)(head);					\
437	    (var) = CIRCLEQ_NEXT((var), field))
438
439#define	CIRCLEQ_FOREACH_REVERSE(var, head, field)			\
440	for ((var) = CIRCLEQ_LAST((head));				\
441	    (var) != (void *)(head);					\
442	    (var) = CIRCLEQ_PREV((var), field))
443
444#define	CIRCLEQ_INIT(head) do {						\
445	CIRCLEQ_FIRST((head)) = (void *)(head);				\
446	CIRCLEQ_LAST((head)) = (void *)(head);				\
447} while (0)
448
449#define	CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
450	CIRCLEQ_NEXT((elm), field) = CIRCLEQ_NEXT((listelm), field);	\
451	CIRCLEQ_PREV((elm), field) = (listelm);				\
452	if (CIRCLEQ_NEXT((listelm), field) == (void *)(head))		\
453		CIRCLEQ_LAST((head)) = (elm);				\
454	else								\
455		CIRCLEQ_PREV(CIRCLEQ_NEXT((listelm), field), field) = (elm);\
456	CIRCLEQ_NEXT((listelm), field) = (elm);				\
457} while (0)
458
459#define	CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {		\
460	CIRCLEQ_NEXT((elm), field) = (listelm);				\
461	CIRCLEQ_PREV((elm), field) = CIRCLEQ_PREV((listelm), field);	\
462	if (CIRCLEQ_PREV((listelm), field) == (void *)(head))		\
463		CIRCLEQ_FIRST((head)) = (elm);				\
464	else								\
465		CIRCLEQ_NEXT(CIRCLEQ_PREV((listelm), field), field) = (elm);\
466	CIRCLEQ_PREV((listelm), field) = (elm);				\
467} while (0)
468
469#define	CIRCLEQ_INSERT_HEAD(head, elm, field) do {			\
470	CIRCLEQ_NEXT((elm), field) = CIRCLEQ_FIRST((head));		\
471	CIRCLEQ_PREV((elm), field) = (void *)(head);			\
472	if (CIRCLEQ_LAST((head)) == (void *)(head))			\
473		CIRCLEQ_LAST((head)) = (elm);				\
474	else								\
475		CIRCLEQ_PREV(CIRCLEQ_FIRST((head)), field) = (elm);	\
476	CIRCLEQ_FIRST((head)) = (elm);					\
477} while (0)
478
479#define	CIRCLEQ_INSERT_TAIL(head, elm, field) do {			\
480	CIRCLEQ_NEXT((elm), field) = (void *)(head);			\
481	CIRCLEQ_PREV((elm), field) = CIRCLEQ_LAST((head));		\
482	if (CIRCLEQ_FIRST((head)) == (void *)(head))			\
483		CIRCLEQ_FIRST((head)) = (elm);				\
484	else								\
485		CIRCLEQ_NEXT(CIRCLEQ_LAST((head)), field) = (elm);	\
486	CIRCLEQ_LAST((head)) = (elm);					\
487} while (0)
488
489#define	CIRCLEQ_LAST(head)	((head)->cqh_last)
490
491#define	CIRCLEQ_NEXT(elm,field)	((elm)->field.cqe_next)
492
493#define	CIRCLEQ_PREV(elm,field)	((elm)->field.cqe_prev)
494
495#define	CIRCLEQ_REMOVE(head, elm, field) do {				\
496	if (CIRCLEQ_NEXT((elm), field) == (void *)(head))		\
497		CIRCLEQ_LAST((head)) = CIRCLEQ_PREV((elm), field);	\
498	else								\
499		CIRCLEQ_PREV(CIRCLEQ_NEXT((elm), field), field) =	\
500		    CIRCLEQ_PREV((elm), field);				\
501	if (CIRCLEQ_PREV((elm), field) == (void *)(head))		\
502		CIRCLEQ_FIRST((head)) = CIRCLEQ_NEXT((elm), field);	\
503	else								\
504		CIRCLEQ_NEXT(CIRCLEQ_PREV((elm), field), field) =	\
505		    CIRCLEQ_NEXT((elm), field);				\
506} while (0)
507
508#ifdef _KERNEL
509
510/*
511 * XXX insque() and remque() are an old way of handling certain queues.
512 * They bogusly assumes that all queue heads look alike.
513 */
514
515struct quehead {
516	struct quehead *qh_link;
517	struct quehead *qh_rlink;
518};
519
520#ifdef	__GNUC__
521
522static __inline void
523insque(void *a, void *b)
524{
525	struct quehead *element = a, *head = b;
526
527	element->qh_link = head->qh_link;
528	element->qh_rlink = head;
529	head->qh_link = element;
530	element->qh_link->qh_rlink = element;
531}
532
533static __inline void
534remque(void *a)
535{
536	struct quehead *element = a;
537
538	element->qh_link->qh_rlink = element->qh_rlink;
539	element->qh_rlink->qh_link = element->qh_link;
540	element->qh_rlink = 0;
541}
542
543#else /* !__GNUC__ */
544
545void	insque __P((void *a, void *b));
546void	remque __P((void *a));
547
548#endif /* __GNUC__ */
549
550#endif /* _KERNEL */
551
552#endif /* !_SYS_QUEUE_H_ */
553