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