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