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