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