1*2d9fd380Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause
2*2d9fd380Sjfb8856606  *
3*2d9fd380Sjfb8856606  * Copyright (c) 1991, 1993
4*2d9fd380Sjfb8856606  *	The Regents of the University of California.  All rights reserved.
5*2d9fd380Sjfb8856606  */
6*2d9fd380Sjfb8856606 
7*2d9fd380Sjfb8856606 #ifndef _SYS_QUEUE_H_
8*2d9fd380Sjfb8856606 #define	_SYS_QUEUE_H_
9*2d9fd380Sjfb8856606 
10*2d9fd380Sjfb8856606 /*
11*2d9fd380Sjfb8856606  * This file defines four types of data structures: singly-linked lists,
12*2d9fd380Sjfb8856606  * singly-linked tail queues, lists and tail queues.
13*2d9fd380Sjfb8856606  *
14*2d9fd380Sjfb8856606  * A singly-linked list is headed by a single forward pointer. The elements
15*2d9fd380Sjfb8856606  * are singly linked for minimum space and pointer manipulation overhead at
16*2d9fd380Sjfb8856606  * the expense of O(n) removal for arbitrary elements. New elements can be
17*2d9fd380Sjfb8856606  * added to the list after an existing element or at the head of the list.
18*2d9fd380Sjfb8856606  * Elements being removed from the head of the list should use the explicit
19*2d9fd380Sjfb8856606  * macro for this purpose for optimum efficiency. A singly-linked list may
20*2d9fd380Sjfb8856606  * only be traversed in the forward direction.  Singly-linked lists are ideal
21*2d9fd380Sjfb8856606  * for applications with large datasets and few or no removals or for
22*2d9fd380Sjfb8856606  * implementing a LIFO queue.
23*2d9fd380Sjfb8856606  *
24*2d9fd380Sjfb8856606  * A singly-linked tail queue is headed by a pair of pointers, one to the
25*2d9fd380Sjfb8856606  * head of the list and the other to the tail of the list. The elements are
26*2d9fd380Sjfb8856606  * singly linked for minimum space and pointer manipulation overhead at the
27*2d9fd380Sjfb8856606  * expense of O(n) removal for arbitrary elements. New elements can be added
28*2d9fd380Sjfb8856606  * to the list after an existing element, at the head of the list, or at the
29*2d9fd380Sjfb8856606  * end of the list. Elements being removed from the head of the tail queue
30*2d9fd380Sjfb8856606  * should use the explicit macro for this purpose for optimum efficiency.
31*2d9fd380Sjfb8856606  * A singly-linked tail queue may only be traversed in the forward direction.
32*2d9fd380Sjfb8856606  * Singly-linked tail queues are ideal for applications with large datasets
33*2d9fd380Sjfb8856606  * and few or no removals or for implementing a FIFO queue.
34*2d9fd380Sjfb8856606  *
35*2d9fd380Sjfb8856606  * A list is headed by a single forward pointer (or an array of forward
36*2d9fd380Sjfb8856606  * pointers for a hash table header). The elements are doubly linked
37*2d9fd380Sjfb8856606  * so that an arbitrary element can be removed without a need to
38*2d9fd380Sjfb8856606  * traverse the list. New elements can be added to the list before
39*2d9fd380Sjfb8856606  * or after an existing element or at the head of the list. A list
40*2d9fd380Sjfb8856606  * may be traversed in either direction.
41*2d9fd380Sjfb8856606  *
42*2d9fd380Sjfb8856606  * A tail queue is headed by a pair of pointers, one to the head of the
43*2d9fd380Sjfb8856606  * list and the other to the tail of the list. The elements are doubly
44*2d9fd380Sjfb8856606  * linked so that an arbitrary element can be removed without a need to
45*2d9fd380Sjfb8856606  * traverse the list. New elements can be added to the list before or
46*2d9fd380Sjfb8856606  * after an existing element, at the head of the list, or at the end of
47*2d9fd380Sjfb8856606  * the list. A tail queue may be traversed in either direction.
48*2d9fd380Sjfb8856606  *
49*2d9fd380Sjfb8856606  * For details on the use of these macros, see the queue(3) manual page.
50*2d9fd380Sjfb8856606  *
51*2d9fd380Sjfb8856606  * Below is a summary of implemented functions where:
52*2d9fd380Sjfb8856606  *  +  means the macro is available
53*2d9fd380Sjfb8856606  *  -  means the macro is not available
54*2d9fd380Sjfb8856606  *  s  means the macro is available but is slow (runs in O(n) time)
55*2d9fd380Sjfb8856606  *
56*2d9fd380Sjfb8856606  *				SLIST	LIST	STAILQ	TAILQ
57*2d9fd380Sjfb8856606  * _HEAD			+	+	+	+
58*2d9fd380Sjfb8856606  * _CLASS_HEAD			+	+	+	+
59*2d9fd380Sjfb8856606  * _HEAD_INITIALIZER		+	+	+	+
60*2d9fd380Sjfb8856606  * _ENTRY			+	+	+	+
61*2d9fd380Sjfb8856606  * _CLASS_ENTRY			+	+	+	+
62*2d9fd380Sjfb8856606  * _INIT			+	+	+	+
63*2d9fd380Sjfb8856606  * _EMPTY			+	+	+	+
64*2d9fd380Sjfb8856606  * _FIRST			+	+	+	+
65*2d9fd380Sjfb8856606  * _NEXT			+	+	+	+
66*2d9fd380Sjfb8856606  * _PREV			-	+	-	+
67*2d9fd380Sjfb8856606  * _LAST			-	-	+	+
68*2d9fd380Sjfb8856606  * _LAST_FAST			-	-	-	+
69*2d9fd380Sjfb8856606  * _FOREACH			+	+	+	+
70*2d9fd380Sjfb8856606  * _FOREACH_FROM		+	+	+	+
71*2d9fd380Sjfb8856606  * _FOREACH_SAFE		+	+	+	+
72*2d9fd380Sjfb8856606  * _FOREACH_FROM_SAFE		+	+	+	+
73*2d9fd380Sjfb8856606  * _FOREACH_REVERSE		-	-	-	+
74*2d9fd380Sjfb8856606  * _FOREACH_REVERSE_FROM	-	-	-	+
75*2d9fd380Sjfb8856606  * _FOREACH_REVERSE_SAFE	-	-	-	+
76*2d9fd380Sjfb8856606  * _FOREACH_REVERSE_FROM_SAFE	-	-	-	+
77*2d9fd380Sjfb8856606  * _INSERT_HEAD			+	+	+	+
78*2d9fd380Sjfb8856606  * _INSERT_BEFORE		-	+	-	+
79*2d9fd380Sjfb8856606  * _INSERT_AFTER		+	+	+	+
80*2d9fd380Sjfb8856606  * _INSERT_TAIL			-	-	+	+
81*2d9fd380Sjfb8856606  * _CONCAT			s	s	+	+
82*2d9fd380Sjfb8856606  * _REMOVE_AFTER		+	-	+	-
83*2d9fd380Sjfb8856606  * _REMOVE_HEAD			+	-	+	-
84*2d9fd380Sjfb8856606  * _REMOVE			s	+	s	+
85*2d9fd380Sjfb8856606  * _SWAP			+	+	+	+
86*2d9fd380Sjfb8856606  *
87*2d9fd380Sjfb8856606  */
88*2d9fd380Sjfb8856606 #ifdef QUEUE_MACRO_DEBUG
89*2d9fd380Sjfb8856606 #warn Use QUEUE_MACRO_DEBUG_TRACE and/or QUEUE_MACRO_DEBUG_TRASH
90*2d9fd380Sjfb8856606 #define	QUEUE_MACRO_DEBUG_TRACE
91*2d9fd380Sjfb8856606 #define	QUEUE_MACRO_DEBUG_TRASH
92*2d9fd380Sjfb8856606 #endif
93*2d9fd380Sjfb8856606 
94*2d9fd380Sjfb8856606 #ifdef QUEUE_MACRO_DEBUG_TRACE
95*2d9fd380Sjfb8856606 /* Store the last 2 places the queue element or head was altered */
96*2d9fd380Sjfb8856606 struct qm_trace {
97*2d9fd380Sjfb8856606 	unsigned long	 lastline;
98*2d9fd380Sjfb8856606 	unsigned long	 prevline;
99*2d9fd380Sjfb8856606 	const char	*lastfile;
100*2d9fd380Sjfb8856606 	const char	*prevfile;
101*2d9fd380Sjfb8856606 };
102*2d9fd380Sjfb8856606 
103*2d9fd380Sjfb8856606 #define	TRACEBUF	struct qm_trace trace;
104*2d9fd380Sjfb8856606 #define	TRACEBUF_INITIALIZER	{ __LINE__, 0, __FILE__, NULL } ,
105*2d9fd380Sjfb8856606 
106*2d9fd380Sjfb8856606 #define	QMD_TRACE_HEAD(head) do {					\
107*2d9fd380Sjfb8856606 	(head)->trace.prevline = (head)->trace.lastline;		\
108*2d9fd380Sjfb8856606 	(head)->trace.prevfile = (head)->trace.lastfile;		\
109*2d9fd380Sjfb8856606 	(head)->trace.lastline = __LINE__;				\
110*2d9fd380Sjfb8856606 	(head)->trace.lastfile = __FILE__;				\
111*2d9fd380Sjfb8856606 } while (0)
112*2d9fd380Sjfb8856606 
113*2d9fd380Sjfb8856606 #define	QMD_TRACE_ELEM(elem) do {					\
114*2d9fd380Sjfb8856606 	(elem)->trace.prevline = (elem)->trace.lastline;		\
115*2d9fd380Sjfb8856606 	(elem)->trace.prevfile = (elem)->trace.lastfile;		\
116*2d9fd380Sjfb8856606 	(elem)->trace.lastline = __LINE__;				\
117*2d9fd380Sjfb8856606 	(elem)->trace.lastfile = __FILE__;				\
118*2d9fd380Sjfb8856606 } while (0)
119*2d9fd380Sjfb8856606 
120*2d9fd380Sjfb8856606 #else	/* !QUEUE_MACRO_DEBUG_TRACE */
121*2d9fd380Sjfb8856606 #define	QMD_TRACE_ELEM(elem)
122*2d9fd380Sjfb8856606 #define	QMD_TRACE_HEAD(head)
123*2d9fd380Sjfb8856606 #define	TRACEBUF
124*2d9fd380Sjfb8856606 #define	TRACEBUF_INITIALIZER
125*2d9fd380Sjfb8856606 #endif	/* QUEUE_MACRO_DEBUG_TRACE */
126*2d9fd380Sjfb8856606 
127*2d9fd380Sjfb8856606 #ifdef QUEUE_MACRO_DEBUG_TRASH
128*2d9fd380Sjfb8856606 #define	QMD_SAVELINK(name, link)	void **name = (void *)&(link)
129*2d9fd380Sjfb8856606 #define	TRASHIT(x)		do {(x) = (void *)-1;} while (0)
130*2d9fd380Sjfb8856606 #define	QMD_IS_TRASHED(x)	((x) == (void *)(intptr_t)-1)
131*2d9fd380Sjfb8856606 #else	/* !QUEUE_MACRO_DEBUG_TRASH */
132*2d9fd380Sjfb8856606 #define	QMD_SAVELINK(name, link)
133*2d9fd380Sjfb8856606 #define	TRASHIT(x)
134*2d9fd380Sjfb8856606 #define	QMD_IS_TRASHED(x)	0
135*2d9fd380Sjfb8856606 #endif	/* QUEUE_MACRO_DEBUG_TRASH */
136*2d9fd380Sjfb8856606 
137*2d9fd380Sjfb8856606 #ifdef __cplusplus
138*2d9fd380Sjfb8856606 /*
139*2d9fd380Sjfb8856606  * In C++ there can be structure lists and class lists:
140*2d9fd380Sjfb8856606  */
141*2d9fd380Sjfb8856606 #define	QUEUE_TYPEOF(type) type
142*2d9fd380Sjfb8856606 #else
143*2d9fd380Sjfb8856606 #define	QUEUE_TYPEOF(type) struct type
144*2d9fd380Sjfb8856606 #endif
145*2d9fd380Sjfb8856606 
146*2d9fd380Sjfb8856606 /*
147*2d9fd380Sjfb8856606  * Singly-linked List declarations.
148*2d9fd380Sjfb8856606  */
149*2d9fd380Sjfb8856606 #define	SLIST_HEAD(name, type)						\
150*2d9fd380Sjfb8856606 struct name {								\
151*2d9fd380Sjfb8856606 	struct type *slh_first;	/* first element */			\
152*2d9fd380Sjfb8856606 }
153*2d9fd380Sjfb8856606 
154*2d9fd380Sjfb8856606 #define	SLIST_CLASS_HEAD(name, type)					\
155*2d9fd380Sjfb8856606 struct name {								\
156*2d9fd380Sjfb8856606 	class type *slh_first;	/* first element */			\
157*2d9fd380Sjfb8856606 }
158*2d9fd380Sjfb8856606 
159*2d9fd380Sjfb8856606 #define	SLIST_HEAD_INITIALIZER(head)					\
160*2d9fd380Sjfb8856606 	{ NULL }
161*2d9fd380Sjfb8856606 
162*2d9fd380Sjfb8856606 #define	SLIST_ENTRY(type)						\
163*2d9fd380Sjfb8856606 struct {								\
164*2d9fd380Sjfb8856606 	struct type *sle_next;	/* next element */			\
165*2d9fd380Sjfb8856606 }
166*2d9fd380Sjfb8856606 
167*2d9fd380Sjfb8856606 #define	SLIST_CLASS_ENTRY(type)						\
168*2d9fd380Sjfb8856606 struct {								\
169*2d9fd380Sjfb8856606 	class type *sle_next;		/* next element */		\
170*2d9fd380Sjfb8856606 }
171*2d9fd380Sjfb8856606 
172*2d9fd380Sjfb8856606 /*
173*2d9fd380Sjfb8856606  * Singly-linked List functions.
174*2d9fd380Sjfb8856606  */
175*2d9fd380Sjfb8856606 #if (defined(_KERNEL) && defined(INVARIANTS))
176*2d9fd380Sjfb8856606 #define	QMD_SLIST_CHECK_PREVPTR(prevp, elm) do {			\
177*2d9fd380Sjfb8856606 	if (*(prevp) != (elm))						\
178*2d9fd380Sjfb8856606 		panic("Bad prevptr *(%p) == %p != %p",			\
179*2d9fd380Sjfb8856606 		    (prevp), *(prevp), (elm));				\
180*2d9fd380Sjfb8856606 } while (0)
181*2d9fd380Sjfb8856606 #else
182*2d9fd380Sjfb8856606 #define	QMD_SLIST_CHECK_PREVPTR(prevp, elm)
183*2d9fd380Sjfb8856606 #endif
184*2d9fd380Sjfb8856606 
185*2d9fd380Sjfb8856606 #define SLIST_CONCAT(head1, head2, type, field) do {			\
186*2d9fd380Sjfb8856606 	QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head1);		\
187*2d9fd380Sjfb8856606 	if (curelm == NULL) {						\
188*2d9fd380Sjfb8856606 		if ((SLIST_FIRST(head1) = SLIST_FIRST(head2)) != NULL)	\
189*2d9fd380Sjfb8856606 			SLIST_INIT(head2);				\
190*2d9fd380Sjfb8856606 	} else if (SLIST_FIRST(head2) != NULL) {			\
191*2d9fd380Sjfb8856606 		while (SLIST_NEXT(curelm, field) != NULL)		\
192*2d9fd380Sjfb8856606 			curelm = SLIST_NEXT(curelm, field);		\
193*2d9fd380Sjfb8856606 		SLIST_NEXT(curelm, field) = SLIST_FIRST(head2);		\
194*2d9fd380Sjfb8856606 		SLIST_INIT(head2);					\
195*2d9fd380Sjfb8856606 	}								\
196*2d9fd380Sjfb8856606 } while (0)
197*2d9fd380Sjfb8856606 
198*2d9fd380Sjfb8856606 #define	SLIST_EMPTY(head)	((head)->slh_first == NULL)
199*2d9fd380Sjfb8856606 
200*2d9fd380Sjfb8856606 #define	SLIST_FIRST(head)	((head)->slh_first)
201*2d9fd380Sjfb8856606 
202*2d9fd380Sjfb8856606 #define	SLIST_FOREACH(var, head, field)					\
203*2d9fd380Sjfb8856606 	for ((var) = SLIST_FIRST((head));				\
204*2d9fd380Sjfb8856606 	    (var);							\
205*2d9fd380Sjfb8856606 	    (var) = SLIST_NEXT((var), field))
206*2d9fd380Sjfb8856606 
207*2d9fd380Sjfb8856606 #define	SLIST_FOREACH_FROM(var, head, field)				\
208*2d9fd380Sjfb8856606 	for ((var) = ((var) ? (var) : SLIST_FIRST((head)));		\
209*2d9fd380Sjfb8856606 	    (var);							\
210*2d9fd380Sjfb8856606 	    (var) = SLIST_NEXT((var), field))
211*2d9fd380Sjfb8856606 
212*2d9fd380Sjfb8856606 #define	SLIST_FOREACH_SAFE(var, head, field, tvar)			\
213*2d9fd380Sjfb8856606 	for ((var) = SLIST_FIRST((head));				\
214*2d9fd380Sjfb8856606 	    (var) && ((tvar) = SLIST_NEXT((var), field), 1);		\
215*2d9fd380Sjfb8856606 	    (var) = (tvar))
216*2d9fd380Sjfb8856606 
217*2d9fd380Sjfb8856606 #define	SLIST_FOREACH_FROM_SAFE(var, head, field, tvar)			\
218*2d9fd380Sjfb8856606 	for ((var) = ((var) ? (var) : SLIST_FIRST((head)));		\
219*2d9fd380Sjfb8856606 	    (var) && ((tvar) = SLIST_NEXT((var), field), 1);		\
220*2d9fd380Sjfb8856606 	    (var) = (tvar))
221*2d9fd380Sjfb8856606 
222*2d9fd380Sjfb8856606 #define	SLIST_FOREACH_PREVPTR(var, varp, head, field)			\
223*2d9fd380Sjfb8856606 	for ((varp) = &SLIST_FIRST((head));				\
224*2d9fd380Sjfb8856606 	    ((var) = *(varp)) != NULL;					\
225*2d9fd380Sjfb8856606 	    (varp) = &SLIST_NEXT((var), field))
226*2d9fd380Sjfb8856606 
227*2d9fd380Sjfb8856606 #define	SLIST_INIT(head) do {						\
228*2d9fd380Sjfb8856606 	SLIST_FIRST((head)) = NULL;					\
229*2d9fd380Sjfb8856606 } while (0)
230*2d9fd380Sjfb8856606 
231*2d9fd380Sjfb8856606 #define	SLIST_INSERT_AFTER(slistelm, elm, field) do {			\
232*2d9fd380Sjfb8856606 	SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field);	\
233*2d9fd380Sjfb8856606 	SLIST_NEXT((slistelm), field) = (elm);				\
234*2d9fd380Sjfb8856606 } while (0)
235*2d9fd380Sjfb8856606 
236*2d9fd380Sjfb8856606 #define	SLIST_INSERT_HEAD(head, elm, field) do {			\
237*2d9fd380Sjfb8856606 	SLIST_NEXT((elm), field) = SLIST_FIRST((head));			\
238*2d9fd380Sjfb8856606 	SLIST_FIRST((head)) = (elm);					\
239*2d9fd380Sjfb8856606 } while (0)
240*2d9fd380Sjfb8856606 
241*2d9fd380Sjfb8856606 #define	SLIST_NEXT(elm, field)	((elm)->field.sle_next)
242*2d9fd380Sjfb8856606 
243*2d9fd380Sjfb8856606 #define	SLIST_REMOVE(head, elm, type, field) do {			\
244*2d9fd380Sjfb8856606 	QMD_SAVELINK(oldnext, (elm)->field.sle_next);			\
245*2d9fd380Sjfb8856606 	if (SLIST_FIRST((head)) == (elm)) {				\
246*2d9fd380Sjfb8856606 		SLIST_REMOVE_HEAD((head), field);			\
247*2d9fd380Sjfb8856606 	}								\
248*2d9fd380Sjfb8856606 	else {								\
249*2d9fd380Sjfb8856606 		QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head);		\
250*2d9fd380Sjfb8856606 		while (SLIST_NEXT(curelm, field) != (elm))		\
251*2d9fd380Sjfb8856606 			curelm = SLIST_NEXT(curelm, field);		\
252*2d9fd380Sjfb8856606 		SLIST_REMOVE_AFTER(curelm, field);			\
253*2d9fd380Sjfb8856606 	}								\
254*2d9fd380Sjfb8856606 	TRASHIT(*oldnext);						\
255*2d9fd380Sjfb8856606 } while (0)
256*2d9fd380Sjfb8856606 
257*2d9fd380Sjfb8856606 #define SLIST_REMOVE_AFTER(elm, field) do {				\
258*2d9fd380Sjfb8856606 	SLIST_NEXT(elm, field) =					\
259*2d9fd380Sjfb8856606 	    SLIST_NEXT(SLIST_NEXT(elm, field), field);			\
260*2d9fd380Sjfb8856606 } while (0)
261*2d9fd380Sjfb8856606 
262*2d9fd380Sjfb8856606 #define	SLIST_REMOVE_HEAD(head, field) do {				\
263*2d9fd380Sjfb8856606 	SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field);	\
264*2d9fd380Sjfb8856606 } while (0)
265*2d9fd380Sjfb8856606 
266*2d9fd380Sjfb8856606 #define	SLIST_REMOVE_PREVPTR(prevp, elm, field) do {			\
267*2d9fd380Sjfb8856606 	QMD_SLIST_CHECK_PREVPTR(prevp, elm);				\
268*2d9fd380Sjfb8856606 	*(prevp) = SLIST_NEXT(elm, field);				\
269*2d9fd380Sjfb8856606 	TRASHIT((elm)->field.sle_next);					\
270*2d9fd380Sjfb8856606 } while (0)
271*2d9fd380Sjfb8856606 
272*2d9fd380Sjfb8856606 #define SLIST_SWAP(head1, head2, type) do {				\
273*2d9fd380Sjfb8856606 	QUEUE_TYPEOF(type) *swap_first = SLIST_FIRST(head1);		\
274*2d9fd380Sjfb8856606 	SLIST_FIRST(head1) = SLIST_FIRST(head2);			\
275*2d9fd380Sjfb8856606 	SLIST_FIRST(head2) = swap_first;				\
276*2d9fd380Sjfb8856606 } while (0)
277*2d9fd380Sjfb8856606 
278*2d9fd380Sjfb8856606 /*
279*2d9fd380Sjfb8856606  * Singly-linked Tail queue declarations.
280*2d9fd380Sjfb8856606  */
281*2d9fd380Sjfb8856606 #define	STAILQ_HEAD(name, type)						\
282*2d9fd380Sjfb8856606 struct name {								\
283*2d9fd380Sjfb8856606 	struct type *stqh_first;/* first element */			\
284*2d9fd380Sjfb8856606 	struct type **stqh_last;/* addr of last next element */		\
285*2d9fd380Sjfb8856606 }
286*2d9fd380Sjfb8856606 
287*2d9fd380Sjfb8856606 #define	STAILQ_CLASS_HEAD(name, type)					\
288*2d9fd380Sjfb8856606 struct name {								\
289*2d9fd380Sjfb8856606 	class type *stqh_first;	/* first element */			\
290*2d9fd380Sjfb8856606 	class type **stqh_last;	/* addr of last next element */		\
291*2d9fd380Sjfb8856606 }
292*2d9fd380Sjfb8856606 
293*2d9fd380Sjfb8856606 #define	STAILQ_HEAD_INITIALIZER(head)					\
294*2d9fd380Sjfb8856606 	{ NULL, &(head).stqh_first }
295*2d9fd380Sjfb8856606 
296*2d9fd380Sjfb8856606 #define	STAILQ_ENTRY(type)						\
297*2d9fd380Sjfb8856606 struct {								\
298*2d9fd380Sjfb8856606 	struct type *stqe_next;	/* next element */			\
299*2d9fd380Sjfb8856606 }
300*2d9fd380Sjfb8856606 
301*2d9fd380Sjfb8856606 #define	STAILQ_CLASS_ENTRY(type)					\
302*2d9fd380Sjfb8856606 struct {								\
303*2d9fd380Sjfb8856606 	class type *stqe_next;	/* next element */			\
304*2d9fd380Sjfb8856606 }
305*2d9fd380Sjfb8856606 
306*2d9fd380Sjfb8856606 /*
307*2d9fd380Sjfb8856606  * Singly-linked Tail queue functions.
308*2d9fd380Sjfb8856606  */
309*2d9fd380Sjfb8856606 #define	STAILQ_CONCAT(head1, head2) do {				\
310*2d9fd380Sjfb8856606 	if (!STAILQ_EMPTY((head2))) {					\
311*2d9fd380Sjfb8856606 		*(head1)->stqh_last = (head2)->stqh_first;		\
312*2d9fd380Sjfb8856606 		(head1)->stqh_last = (head2)->stqh_last;		\
313*2d9fd380Sjfb8856606 		STAILQ_INIT((head2));					\
314*2d9fd380Sjfb8856606 	}								\
315*2d9fd380Sjfb8856606 } while (0)
316*2d9fd380Sjfb8856606 
317*2d9fd380Sjfb8856606 #define	STAILQ_EMPTY(head)	((head)->stqh_first == NULL)
318*2d9fd380Sjfb8856606 
319*2d9fd380Sjfb8856606 #define	STAILQ_FIRST(head)	((head)->stqh_first)
320*2d9fd380Sjfb8856606 
321*2d9fd380Sjfb8856606 #define	STAILQ_FOREACH(var, head, field)				\
322*2d9fd380Sjfb8856606 	for((var) = STAILQ_FIRST((head));				\
323*2d9fd380Sjfb8856606 	   (var);							\
324*2d9fd380Sjfb8856606 	   (var) = STAILQ_NEXT((var), field))
325*2d9fd380Sjfb8856606 
326*2d9fd380Sjfb8856606 #define	STAILQ_FOREACH_FROM(var, head, field)				\
327*2d9fd380Sjfb8856606 	for ((var) = ((var) ? (var) : STAILQ_FIRST((head)));		\
328*2d9fd380Sjfb8856606 	   (var);							\
329*2d9fd380Sjfb8856606 	   (var) = STAILQ_NEXT((var), field))
330*2d9fd380Sjfb8856606 
331*2d9fd380Sjfb8856606 #define	STAILQ_FOREACH_SAFE(var, head, field, tvar)			\
332*2d9fd380Sjfb8856606 	for ((var) = STAILQ_FIRST((head));				\
333*2d9fd380Sjfb8856606 	    (var) && ((tvar) = STAILQ_NEXT((var), field), 1);		\
334*2d9fd380Sjfb8856606 	    (var) = (tvar))
335*2d9fd380Sjfb8856606 
336*2d9fd380Sjfb8856606 #define	STAILQ_FOREACH_FROM_SAFE(var, head, field, tvar)		\
337*2d9fd380Sjfb8856606 	for ((var) = ((var) ? (var) : STAILQ_FIRST((head)));		\
338*2d9fd380Sjfb8856606 	    (var) && ((tvar) = STAILQ_NEXT((var), field), 1);		\
339*2d9fd380Sjfb8856606 	    (var) = (tvar))
340*2d9fd380Sjfb8856606 
341*2d9fd380Sjfb8856606 #define	STAILQ_INIT(head) do {						\
342*2d9fd380Sjfb8856606 	STAILQ_FIRST((head)) = NULL;					\
343*2d9fd380Sjfb8856606 	(head)->stqh_last = &STAILQ_FIRST((head));			\
344*2d9fd380Sjfb8856606 } while (0)
345*2d9fd380Sjfb8856606 
346*2d9fd380Sjfb8856606 #define	STAILQ_INSERT_AFTER(head, tqelm, elm, field) do {		\
347*2d9fd380Sjfb8856606 	if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
348*2d9fd380Sjfb8856606 		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
349*2d9fd380Sjfb8856606 	STAILQ_NEXT((tqelm), field) = (elm);				\
350*2d9fd380Sjfb8856606 } while (0)
351*2d9fd380Sjfb8856606 
352*2d9fd380Sjfb8856606 #define	STAILQ_INSERT_HEAD(head, elm, field) do {			\
353*2d9fd380Sjfb8856606 	if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL)	\
354*2d9fd380Sjfb8856606 		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
355*2d9fd380Sjfb8856606 	STAILQ_FIRST((head)) = (elm);					\
356*2d9fd380Sjfb8856606 } while (0)
357*2d9fd380Sjfb8856606 
358*2d9fd380Sjfb8856606 #define	STAILQ_INSERT_TAIL(head, elm, field) do {			\
359*2d9fd380Sjfb8856606 	STAILQ_NEXT((elm), field) = NULL;				\
360*2d9fd380Sjfb8856606 	*(head)->stqh_last = (elm);					\
361*2d9fd380Sjfb8856606 	(head)->stqh_last = &STAILQ_NEXT((elm), field);			\
362*2d9fd380Sjfb8856606 } while (0)
363*2d9fd380Sjfb8856606 
364*2d9fd380Sjfb8856606 #define	STAILQ_LAST(head, type, field)				\
365*2d9fd380Sjfb8856606 	(STAILQ_EMPTY((head)) ? NULL :				\
366*2d9fd380Sjfb8856606 	    __containerof((head)->stqh_last,			\
367*2d9fd380Sjfb8856606 	    QUEUE_TYPEOF(type), field.stqe_next))
368*2d9fd380Sjfb8856606 
369*2d9fd380Sjfb8856606 #define	STAILQ_NEXT(elm, field)	((elm)->field.stqe_next)
370*2d9fd380Sjfb8856606 
371*2d9fd380Sjfb8856606 #define	STAILQ_REMOVE(head, elm, type, field) do {			\
372*2d9fd380Sjfb8856606 	QMD_SAVELINK(oldnext, (elm)->field.stqe_next);			\
373*2d9fd380Sjfb8856606 	if (STAILQ_FIRST((head)) == (elm)) {				\
374*2d9fd380Sjfb8856606 		STAILQ_REMOVE_HEAD((head), field);			\
375*2d9fd380Sjfb8856606 	}								\
376*2d9fd380Sjfb8856606 	else {								\
377*2d9fd380Sjfb8856606 		QUEUE_TYPEOF(type) *curelm = STAILQ_FIRST(head);	\
378*2d9fd380Sjfb8856606 		while (STAILQ_NEXT(curelm, field) != (elm))		\
379*2d9fd380Sjfb8856606 			curelm = STAILQ_NEXT(curelm, field);		\
380*2d9fd380Sjfb8856606 		STAILQ_REMOVE_AFTER(head, curelm, field);		\
381*2d9fd380Sjfb8856606 	}								\
382*2d9fd380Sjfb8856606 	TRASHIT(*oldnext);						\
383*2d9fd380Sjfb8856606 } while (0)
384*2d9fd380Sjfb8856606 
385*2d9fd380Sjfb8856606 #define STAILQ_REMOVE_AFTER(head, elm, field) do {			\
386*2d9fd380Sjfb8856606 	if ((STAILQ_NEXT(elm, field) =					\
387*2d9fd380Sjfb8856606 	     STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL)	\
388*2d9fd380Sjfb8856606 		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
389*2d9fd380Sjfb8856606 } while (0)
390*2d9fd380Sjfb8856606 
391*2d9fd380Sjfb8856606 #define	STAILQ_REMOVE_HEAD(head, field) do {				\
392*2d9fd380Sjfb8856606 	if ((STAILQ_FIRST((head)) =					\
393*2d9fd380Sjfb8856606 	     STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL)		\
394*2d9fd380Sjfb8856606 		(head)->stqh_last = &STAILQ_FIRST((head));		\
395*2d9fd380Sjfb8856606 } while (0)
396*2d9fd380Sjfb8856606 
397*2d9fd380Sjfb8856606 #define STAILQ_SWAP(head1, head2, type) do {				\
398*2d9fd380Sjfb8856606 	QUEUE_TYPEOF(type) *swap_first = STAILQ_FIRST(head1);		\
399*2d9fd380Sjfb8856606 	QUEUE_TYPEOF(type) **swap_last = (head1)->stqh_last;		\
400*2d9fd380Sjfb8856606 	STAILQ_FIRST(head1) = STAILQ_FIRST(head2);			\
401*2d9fd380Sjfb8856606 	(head1)->stqh_last = (head2)->stqh_last;			\
402*2d9fd380Sjfb8856606 	STAILQ_FIRST(head2) = swap_first;				\
403*2d9fd380Sjfb8856606 	(head2)->stqh_last = swap_last;					\
404*2d9fd380Sjfb8856606 	if (STAILQ_EMPTY(head1))					\
405*2d9fd380Sjfb8856606 		(head1)->stqh_last = &STAILQ_FIRST(head1);		\
406*2d9fd380Sjfb8856606 	if (STAILQ_EMPTY(head2))					\
407*2d9fd380Sjfb8856606 		(head2)->stqh_last = &STAILQ_FIRST(head2);		\
408*2d9fd380Sjfb8856606 } while (0)
409*2d9fd380Sjfb8856606 
410*2d9fd380Sjfb8856606 
411*2d9fd380Sjfb8856606 /*
412*2d9fd380Sjfb8856606  * List declarations.
413*2d9fd380Sjfb8856606  */
414*2d9fd380Sjfb8856606 #define	LIST_HEAD(name, type)						\
415*2d9fd380Sjfb8856606 struct name {								\
416*2d9fd380Sjfb8856606 	struct type *lh_first;	/* first element */			\
417*2d9fd380Sjfb8856606 }
418*2d9fd380Sjfb8856606 
419*2d9fd380Sjfb8856606 #define	LIST_CLASS_HEAD(name, type)					\
420*2d9fd380Sjfb8856606 struct name {								\
421*2d9fd380Sjfb8856606 	class type *lh_first;	/* first element */			\
422*2d9fd380Sjfb8856606 }
423*2d9fd380Sjfb8856606 
424*2d9fd380Sjfb8856606 #define	LIST_HEAD_INITIALIZER(head)					\
425*2d9fd380Sjfb8856606 	{ NULL }
426*2d9fd380Sjfb8856606 
427*2d9fd380Sjfb8856606 #define	LIST_ENTRY(type)						\
428*2d9fd380Sjfb8856606 struct {								\
429*2d9fd380Sjfb8856606 	struct type *le_next;	/* next element */			\
430*2d9fd380Sjfb8856606 	struct type **le_prev;	/* address of previous next element */	\
431*2d9fd380Sjfb8856606 }
432*2d9fd380Sjfb8856606 
433*2d9fd380Sjfb8856606 #define	LIST_CLASS_ENTRY(type)						\
434*2d9fd380Sjfb8856606 struct {								\
435*2d9fd380Sjfb8856606 	class type *le_next;	/* next element */			\
436*2d9fd380Sjfb8856606 	class type **le_prev;	/* address of previous next element */	\
437*2d9fd380Sjfb8856606 }
438*2d9fd380Sjfb8856606 
439*2d9fd380Sjfb8856606 /*
440*2d9fd380Sjfb8856606  * List functions.
441*2d9fd380Sjfb8856606  */
442*2d9fd380Sjfb8856606 
443*2d9fd380Sjfb8856606 #if (defined(_KERNEL) && defined(INVARIANTS))
444*2d9fd380Sjfb8856606 /*
445*2d9fd380Sjfb8856606  * QMD_LIST_CHECK_HEAD(LIST_HEAD *head, LIST_ENTRY NAME)
446*2d9fd380Sjfb8856606  *
447*2d9fd380Sjfb8856606  * If the list is non-empty, validates that the first element of the list
448*2d9fd380Sjfb8856606  * points back at 'head.'
449*2d9fd380Sjfb8856606  */
450*2d9fd380Sjfb8856606 #define	QMD_LIST_CHECK_HEAD(head, field) do {				\
451*2d9fd380Sjfb8856606 	if (LIST_FIRST((head)) != NULL &&				\
452*2d9fd380Sjfb8856606 	    LIST_FIRST((head))->field.le_prev !=			\
453*2d9fd380Sjfb8856606 	     &LIST_FIRST((head)))					\
454*2d9fd380Sjfb8856606 		panic("Bad list head %p first->prev != head", (head));	\
455*2d9fd380Sjfb8856606 } while (0)
456*2d9fd380Sjfb8856606 
457*2d9fd380Sjfb8856606 /*
458*2d9fd380Sjfb8856606  * QMD_LIST_CHECK_NEXT(TYPE *elm, LIST_ENTRY NAME)
459*2d9fd380Sjfb8856606  *
460*2d9fd380Sjfb8856606  * If an element follows 'elm' in the list, validates that the next element
461*2d9fd380Sjfb8856606  * points back at 'elm.'
462*2d9fd380Sjfb8856606  */
463*2d9fd380Sjfb8856606 #define	QMD_LIST_CHECK_NEXT(elm, field) do {				\
464*2d9fd380Sjfb8856606 	if (LIST_NEXT((elm), field) != NULL &&				\
465*2d9fd380Sjfb8856606 	    LIST_NEXT((elm), field)->field.le_prev !=			\
466*2d9fd380Sjfb8856606 	     &((elm)->field.le_next))					\
467*2d9fd380Sjfb8856606 	     	panic("Bad link elm %p next->prev != elm", (elm));	\
468*2d9fd380Sjfb8856606 } while (0)
469*2d9fd380Sjfb8856606 
470*2d9fd380Sjfb8856606 /*
471*2d9fd380Sjfb8856606  * QMD_LIST_CHECK_PREV(TYPE *elm, LIST_ENTRY NAME)
472*2d9fd380Sjfb8856606  *
473*2d9fd380Sjfb8856606  * Validates that the previous element (or head of the list) points to 'elm.'
474*2d9fd380Sjfb8856606  */
475*2d9fd380Sjfb8856606 #define	QMD_LIST_CHECK_PREV(elm, field) do {				\
476*2d9fd380Sjfb8856606 	if (*(elm)->field.le_prev != (elm))				\
477*2d9fd380Sjfb8856606 		panic("Bad link elm %p prev->next != elm", (elm));	\
478*2d9fd380Sjfb8856606 } while (0)
479*2d9fd380Sjfb8856606 #else
480*2d9fd380Sjfb8856606 #define	QMD_LIST_CHECK_HEAD(head, field)
481*2d9fd380Sjfb8856606 #define	QMD_LIST_CHECK_NEXT(elm, field)
482*2d9fd380Sjfb8856606 #define	QMD_LIST_CHECK_PREV(elm, field)
483*2d9fd380Sjfb8856606 #endif /* (_KERNEL && INVARIANTS) */
484*2d9fd380Sjfb8856606 
485*2d9fd380Sjfb8856606 #define LIST_CONCAT(head1, head2, type, field) do {			      \
486*2d9fd380Sjfb8856606 	QUEUE_TYPEOF(type) *curelm = LIST_FIRST(head1);			      \
487*2d9fd380Sjfb8856606 	if (curelm == NULL) {						      \
488*2d9fd380Sjfb8856606 		if ((LIST_FIRST(head1) = LIST_FIRST(head2)) != NULL) {	      \
489*2d9fd380Sjfb8856606 			LIST_FIRST(head2)->field.le_prev =		      \
490*2d9fd380Sjfb8856606 			    &LIST_FIRST((head1));			      \
491*2d9fd380Sjfb8856606 			LIST_INIT(head2);				      \
492*2d9fd380Sjfb8856606 		}							      \
493*2d9fd380Sjfb8856606 	} else if (LIST_FIRST(head2) != NULL) {				      \
494*2d9fd380Sjfb8856606 		while (LIST_NEXT(curelm, field) != NULL)		      \
495*2d9fd380Sjfb8856606 			curelm = LIST_NEXT(curelm, field);		      \
496*2d9fd380Sjfb8856606 		LIST_NEXT(curelm, field) = LIST_FIRST(head2);		      \
497*2d9fd380Sjfb8856606 		LIST_FIRST(head2)->field.le_prev = &LIST_NEXT(curelm, field); \
498*2d9fd380Sjfb8856606 		LIST_INIT(head2);					      \
499*2d9fd380Sjfb8856606 	}								      \
500*2d9fd380Sjfb8856606 } while (0)
501*2d9fd380Sjfb8856606 
502*2d9fd380Sjfb8856606 #define	LIST_EMPTY(head)	((head)->lh_first == NULL)
503*2d9fd380Sjfb8856606 
504*2d9fd380Sjfb8856606 #define	LIST_FIRST(head)	((head)->lh_first)
505*2d9fd380Sjfb8856606 
506*2d9fd380Sjfb8856606 #define	LIST_FOREACH(var, head, field)					\
507*2d9fd380Sjfb8856606 	for ((var) = LIST_FIRST((head));				\
508*2d9fd380Sjfb8856606 	    (var);							\
509*2d9fd380Sjfb8856606 	    (var) = LIST_NEXT((var), field))
510*2d9fd380Sjfb8856606 
511*2d9fd380Sjfb8856606 #define	LIST_FOREACH_FROM(var, head, field)				\
512*2d9fd380Sjfb8856606 	for ((var) = ((var) ? (var) : LIST_FIRST((head)));		\
513*2d9fd380Sjfb8856606 	    (var);							\
514*2d9fd380Sjfb8856606 	    (var) = LIST_NEXT((var), field))
515*2d9fd380Sjfb8856606 
516*2d9fd380Sjfb8856606 #define	LIST_FOREACH_SAFE(var, head, field, tvar)			\
517*2d9fd380Sjfb8856606 	for ((var) = LIST_FIRST((head));				\
518*2d9fd380Sjfb8856606 	    (var) && ((tvar) = LIST_NEXT((var), field), 1);		\
519*2d9fd380Sjfb8856606 	    (var) = (tvar))
520*2d9fd380Sjfb8856606 
521*2d9fd380Sjfb8856606 #define	LIST_FOREACH_FROM_SAFE(var, head, field, tvar)			\
522*2d9fd380Sjfb8856606 	for ((var) = ((var) ? (var) : LIST_FIRST((head)));		\
523*2d9fd380Sjfb8856606 	    (var) && ((tvar) = LIST_NEXT((var), field), 1);		\
524*2d9fd380Sjfb8856606 	    (var) = (tvar))
525*2d9fd380Sjfb8856606 
526*2d9fd380Sjfb8856606 #define	LIST_INIT(head) do {						\
527*2d9fd380Sjfb8856606 	LIST_FIRST((head)) = NULL;					\
528*2d9fd380Sjfb8856606 } while (0)
529*2d9fd380Sjfb8856606 
530*2d9fd380Sjfb8856606 #define	LIST_INSERT_AFTER(listelm, elm, field) do {			\
531*2d9fd380Sjfb8856606 	QMD_LIST_CHECK_NEXT(listelm, field);				\
532*2d9fd380Sjfb8856606 	if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
533*2d9fd380Sjfb8856606 		LIST_NEXT((listelm), field)->field.le_prev =		\
534*2d9fd380Sjfb8856606 		    &LIST_NEXT((elm), field);				\
535*2d9fd380Sjfb8856606 	LIST_NEXT((listelm), field) = (elm);				\
536*2d9fd380Sjfb8856606 	(elm)->field.le_prev = &LIST_NEXT((listelm), field);		\
537*2d9fd380Sjfb8856606 } while (0)
538*2d9fd380Sjfb8856606 
539*2d9fd380Sjfb8856606 #define	LIST_INSERT_BEFORE(listelm, elm, field) do {			\
540*2d9fd380Sjfb8856606 	QMD_LIST_CHECK_PREV(listelm, field);				\
541*2d9fd380Sjfb8856606 	(elm)->field.le_prev = (listelm)->field.le_prev;		\
542*2d9fd380Sjfb8856606 	LIST_NEXT((elm), field) = (listelm);				\
543*2d9fd380Sjfb8856606 	*(listelm)->field.le_prev = (elm);				\
544*2d9fd380Sjfb8856606 	(listelm)->field.le_prev = &LIST_NEXT((elm), field);		\
545*2d9fd380Sjfb8856606 } while (0)
546*2d9fd380Sjfb8856606 
547*2d9fd380Sjfb8856606 #define	LIST_INSERT_HEAD(head, elm, field) do {				\
548*2d9fd380Sjfb8856606 	QMD_LIST_CHECK_HEAD((head), field);				\
549*2d9fd380Sjfb8856606 	if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL)	\
550*2d9fd380Sjfb8856606 		LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
551*2d9fd380Sjfb8856606 	LIST_FIRST((head)) = (elm);					\
552*2d9fd380Sjfb8856606 	(elm)->field.le_prev = &LIST_FIRST((head));			\
553*2d9fd380Sjfb8856606 } while (0)
554*2d9fd380Sjfb8856606 
555*2d9fd380Sjfb8856606 #define	LIST_NEXT(elm, field)	((elm)->field.le_next)
556*2d9fd380Sjfb8856606 
557*2d9fd380Sjfb8856606 #define	LIST_PREV(elm, head, type, field)			\
558*2d9fd380Sjfb8856606 	((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL :	\
559*2d9fd380Sjfb8856606 	    __containerof((elm)->field.le_prev,			\
560*2d9fd380Sjfb8856606 	    QUEUE_TYPEOF(type), field.le_next))
561*2d9fd380Sjfb8856606 
562*2d9fd380Sjfb8856606 #define	LIST_REMOVE(elm, field) do {					\
563*2d9fd380Sjfb8856606 	QMD_SAVELINK(oldnext, (elm)->field.le_next);			\
564*2d9fd380Sjfb8856606 	QMD_SAVELINK(oldprev, (elm)->field.le_prev);			\
565*2d9fd380Sjfb8856606 	QMD_LIST_CHECK_NEXT(elm, field);				\
566*2d9fd380Sjfb8856606 	QMD_LIST_CHECK_PREV(elm, field);				\
567*2d9fd380Sjfb8856606 	if (LIST_NEXT((elm), field) != NULL)				\
568*2d9fd380Sjfb8856606 		LIST_NEXT((elm), field)->field.le_prev = 		\
569*2d9fd380Sjfb8856606 		    (elm)->field.le_prev;				\
570*2d9fd380Sjfb8856606 	*(elm)->field.le_prev = LIST_NEXT((elm), field);		\
571*2d9fd380Sjfb8856606 	TRASHIT(*oldnext);						\
572*2d9fd380Sjfb8856606 	TRASHIT(*oldprev);						\
573*2d9fd380Sjfb8856606 } while (0)
574*2d9fd380Sjfb8856606 
575*2d9fd380Sjfb8856606 #define LIST_SWAP(head1, head2, type, field) do {			\
576*2d9fd380Sjfb8856606 	QUEUE_TYPEOF(type) *swap_tmp = LIST_FIRST(head1);		\
577*2d9fd380Sjfb8856606 	LIST_FIRST((head1)) = LIST_FIRST((head2));			\
578*2d9fd380Sjfb8856606 	LIST_FIRST((head2)) = swap_tmp;					\
579*2d9fd380Sjfb8856606 	if ((swap_tmp = LIST_FIRST((head1))) != NULL)			\
580*2d9fd380Sjfb8856606 		swap_tmp->field.le_prev = &LIST_FIRST((head1));		\
581*2d9fd380Sjfb8856606 	if ((swap_tmp = LIST_FIRST((head2))) != NULL)			\
582*2d9fd380Sjfb8856606 		swap_tmp->field.le_prev = &LIST_FIRST((head2));		\
583*2d9fd380Sjfb8856606 } while (0)
584*2d9fd380Sjfb8856606 
585*2d9fd380Sjfb8856606 /*
586*2d9fd380Sjfb8856606  * Tail queue declarations.
587*2d9fd380Sjfb8856606  */
588*2d9fd380Sjfb8856606 #define	TAILQ_HEAD(name, type)						\
589*2d9fd380Sjfb8856606 struct name {								\
590*2d9fd380Sjfb8856606 	struct type *tqh_first;	/* first element */			\
591*2d9fd380Sjfb8856606 	struct type **tqh_last;	/* addr of last next element */		\
592*2d9fd380Sjfb8856606 	TRACEBUF							\
593*2d9fd380Sjfb8856606 }
594*2d9fd380Sjfb8856606 
595*2d9fd380Sjfb8856606 #define	TAILQ_CLASS_HEAD(name, type)					\
596*2d9fd380Sjfb8856606 struct name {								\
597*2d9fd380Sjfb8856606 	class type *tqh_first;	/* first element */			\
598*2d9fd380Sjfb8856606 	class type **tqh_last;	/* addr of last next element */		\
599*2d9fd380Sjfb8856606 	TRACEBUF							\
600*2d9fd380Sjfb8856606 }
601*2d9fd380Sjfb8856606 
602*2d9fd380Sjfb8856606 #define	TAILQ_HEAD_INITIALIZER(head)					\
603*2d9fd380Sjfb8856606 	{ NULL, &(head).tqh_first, TRACEBUF_INITIALIZER }
604*2d9fd380Sjfb8856606 
605*2d9fd380Sjfb8856606 #define	TAILQ_ENTRY(type)						\
606*2d9fd380Sjfb8856606 struct {								\
607*2d9fd380Sjfb8856606 	struct type *tqe_next;	/* next element */			\
608*2d9fd380Sjfb8856606 	struct type **tqe_prev;	/* address of previous next element */	\
609*2d9fd380Sjfb8856606 	TRACEBUF							\
610*2d9fd380Sjfb8856606 }
611*2d9fd380Sjfb8856606 
612*2d9fd380Sjfb8856606 #define	TAILQ_CLASS_ENTRY(type)						\
613*2d9fd380Sjfb8856606 struct {								\
614*2d9fd380Sjfb8856606 	class type *tqe_next;	/* next element */			\
615*2d9fd380Sjfb8856606 	class type **tqe_prev;	/* address of previous next element */	\
616*2d9fd380Sjfb8856606 	TRACEBUF							\
617*2d9fd380Sjfb8856606 }
618*2d9fd380Sjfb8856606 
619*2d9fd380Sjfb8856606 /*
620*2d9fd380Sjfb8856606  * Tail queue functions.
621*2d9fd380Sjfb8856606  */
622*2d9fd380Sjfb8856606 #if (defined(_KERNEL) && defined(INVARIANTS))
623*2d9fd380Sjfb8856606 /*
624*2d9fd380Sjfb8856606  * QMD_TAILQ_CHECK_HEAD(TAILQ_HEAD *head, TAILQ_ENTRY NAME)
625*2d9fd380Sjfb8856606  *
626*2d9fd380Sjfb8856606  * If the tailq is non-empty, validates that the first element of the tailq
627*2d9fd380Sjfb8856606  * points back at 'head.'
628*2d9fd380Sjfb8856606  */
629*2d9fd380Sjfb8856606 #define	QMD_TAILQ_CHECK_HEAD(head, field) do {				\
630*2d9fd380Sjfb8856606 	if (!TAILQ_EMPTY(head) &&					\
631*2d9fd380Sjfb8856606 	    TAILQ_FIRST((head))->field.tqe_prev !=			\
632*2d9fd380Sjfb8856606 	     &TAILQ_FIRST((head)))					\
633*2d9fd380Sjfb8856606 		panic("Bad tailq head %p first->prev != head", (head));	\
634*2d9fd380Sjfb8856606 } while (0)
635*2d9fd380Sjfb8856606 
636*2d9fd380Sjfb8856606 /*
637*2d9fd380Sjfb8856606  * QMD_TAILQ_CHECK_TAIL(TAILQ_HEAD *head, TAILQ_ENTRY NAME)
638*2d9fd380Sjfb8856606  *
639*2d9fd380Sjfb8856606  * Validates that the tail of the tailq is a pointer to pointer to NULL.
640*2d9fd380Sjfb8856606  */
641*2d9fd380Sjfb8856606 #define	QMD_TAILQ_CHECK_TAIL(head, field) do {				\
642*2d9fd380Sjfb8856606 	if (*(head)->tqh_last != NULL)					\
643*2d9fd380Sjfb8856606 	    	panic("Bad tailq NEXT(%p->tqh_last) != NULL", (head)); 	\
644*2d9fd380Sjfb8856606 } while (0)
645*2d9fd380Sjfb8856606 
646*2d9fd380Sjfb8856606 /*
647*2d9fd380Sjfb8856606  * QMD_TAILQ_CHECK_NEXT(TYPE *elm, TAILQ_ENTRY NAME)
648*2d9fd380Sjfb8856606  *
649*2d9fd380Sjfb8856606  * If an element follows 'elm' in the tailq, validates that the next element
650*2d9fd380Sjfb8856606  * points back at 'elm.'
651*2d9fd380Sjfb8856606  */
652*2d9fd380Sjfb8856606 #define	QMD_TAILQ_CHECK_NEXT(elm, field) do {				\
653*2d9fd380Sjfb8856606 	if (TAILQ_NEXT((elm), field) != NULL &&				\
654*2d9fd380Sjfb8856606 	    TAILQ_NEXT((elm), field)->field.tqe_prev !=			\
655*2d9fd380Sjfb8856606 	     &((elm)->field.tqe_next))					\
656*2d9fd380Sjfb8856606 		panic("Bad link elm %p next->prev != elm", (elm));	\
657*2d9fd380Sjfb8856606 } while (0)
658*2d9fd380Sjfb8856606 
659*2d9fd380Sjfb8856606 /*
660*2d9fd380Sjfb8856606  * QMD_TAILQ_CHECK_PREV(TYPE *elm, TAILQ_ENTRY NAME)
661*2d9fd380Sjfb8856606  *
662*2d9fd380Sjfb8856606  * Validates that the previous element (or head of the tailq) points to 'elm.'
663*2d9fd380Sjfb8856606  */
664*2d9fd380Sjfb8856606 #define	QMD_TAILQ_CHECK_PREV(elm, field) do {				\
665*2d9fd380Sjfb8856606 	if (*(elm)->field.tqe_prev != (elm))				\
666*2d9fd380Sjfb8856606 		panic("Bad link elm %p prev->next != elm", (elm));	\
667*2d9fd380Sjfb8856606 } while (0)
668*2d9fd380Sjfb8856606 #else
669*2d9fd380Sjfb8856606 #define	QMD_TAILQ_CHECK_HEAD(head, field)
670*2d9fd380Sjfb8856606 #define	QMD_TAILQ_CHECK_TAIL(head, headname)
671*2d9fd380Sjfb8856606 #define	QMD_TAILQ_CHECK_NEXT(elm, field)
672*2d9fd380Sjfb8856606 #define	QMD_TAILQ_CHECK_PREV(elm, field)
673*2d9fd380Sjfb8856606 #endif /* (_KERNEL && INVARIANTS) */
674*2d9fd380Sjfb8856606 
675*2d9fd380Sjfb8856606 #define	TAILQ_CONCAT(head1, head2, field) do {				\
676*2d9fd380Sjfb8856606 	if (!TAILQ_EMPTY(head2)) {					\
677*2d9fd380Sjfb8856606 		*(head1)->tqh_last = (head2)->tqh_first;		\
678*2d9fd380Sjfb8856606 		(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last;	\
679*2d9fd380Sjfb8856606 		(head1)->tqh_last = (head2)->tqh_last;			\
680*2d9fd380Sjfb8856606 		TAILQ_INIT((head2));					\
681*2d9fd380Sjfb8856606 		QMD_TRACE_HEAD(head1);					\
682*2d9fd380Sjfb8856606 		QMD_TRACE_HEAD(head2);					\
683*2d9fd380Sjfb8856606 	}								\
684*2d9fd380Sjfb8856606 } while (0)
685*2d9fd380Sjfb8856606 
686*2d9fd380Sjfb8856606 #define	TAILQ_EMPTY(head)	((head)->tqh_first == NULL)
687*2d9fd380Sjfb8856606 
688*2d9fd380Sjfb8856606 #define	TAILQ_FIRST(head)	((head)->tqh_first)
689*2d9fd380Sjfb8856606 
690*2d9fd380Sjfb8856606 #define	TAILQ_FOREACH(var, head, field)					\
691*2d9fd380Sjfb8856606 	for ((var) = TAILQ_FIRST((head));				\
692*2d9fd380Sjfb8856606 	    (var);							\
693*2d9fd380Sjfb8856606 	    (var) = TAILQ_NEXT((var), field))
694*2d9fd380Sjfb8856606 
695*2d9fd380Sjfb8856606 #define	TAILQ_FOREACH_FROM(var, head, field)				\
696*2d9fd380Sjfb8856606 	for ((var) = ((var) ? (var) : TAILQ_FIRST((head)));		\
697*2d9fd380Sjfb8856606 	    (var);							\
698*2d9fd380Sjfb8856606 	    (var) = TAILQ_NEXT((var), field))
699*2d9fd380Sjfb8856606 
700*2d9fd380Sjfb8856606 #define	TAILQ_FOREACH_SAFE(var, head, field, tvar)			\
701*2d9fd380Sjfb8856606 	for ((var) = TAILQ_FIRST((head));				\
702*2d9fd380Sjfb8856606 	    (var) && ((tvar) = TAILQ_NEXT((var), field), 1);		\
703*2d9fd380Sjfb8856606 	    (var) = (tvar))
704*2d9fd380Sjfb8856606 
705*2d9fd380Sjfb8856606 #define	TAILQ_FOREACH_FROM_SAFE(var, head, field, tvar)			\
706*2d9fd380Sjfb8856606 	for ((var) = ((var) ? (var) : TAILQ_FIRST((head)));		\
707*2d9fd380Sjfb8856606 	    (var) && ((tvar) = TAILQ_NEXT((var), field), 1);		\
708*2d9fd380Sjfb8856606 	    (var) = (tvar))
709*2d9fd380Sjfb8856606 
710*2d9fd380Sjfb8856606 #define	TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
711*2d9fd380Sjfb8856606 	for ((var) = TAILQ_LAST((head), headname);			\
712*2d9fd380Sjfb8856606 	    (var);							\
713*2d9fd380Sjfb8856606 	    (var) = TAILQ_PREV((var), headname, field))
714*2d9fd380Sjfb8856606 
715*2d9fd380Sjfb8856606 #define	TAILQ_FOREACH_REVERSE_FROM(var, head, headname, field)		\
716*2d9fd380Sjfb8856606 	for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname));	\
717*2d9fd380Sjfb8856606 	    (var);							\
718*2d9fd380Sjfb8856606 	    (var) = TAILQ_PREV((var), headname, field))
719*2d9fd380Sjfb8856606 
720*2d9fd380Sjfb8856606 #define	TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar)	\
721*2d9fd380Sjfb8856606 	for ((var) = TAILQ_LAST((head), headname);			\
722*2d9fd380Sjfb8856606 	    (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1);	\
723*2d9fd380Sjfb8856606 	    (var) = (tvar))
724*2d9fd380Sjfb8856606 
725*2d9fd380Sjfb8856606 #define	TAILQ_FOREACH_REVERSE_FROM_SAFE(var, head, headname, field, tvar) \
726*2d9fd380Sjfb8856606 	for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname));	\
727*2d9fd380Sjfb8856606 	    (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1);	\
728*2d9fd380Sjfb8856606 	    (var) = (tvar))
729*2d9fd380Sjfb8856606 
730*2d9fd380Sjfb8856606 #define	TAILQ_INIT(head) do {						\
731*2d9fd380Sjfb8856606 	TAILQ_FIRST((head)) = NULL;					\
732*2d9fd380Sjfb8856606 	(head)->tqh_last = &TAILQ_FIRST((head));			\
733*2d9fd380Sjfb8856606 	QMD_TRACE_HEAD(head);						\
734*2d9fd380Sjfb8856606 } while (0)
735*2d9fd380Sjfb8856606 
736*2d9fd380Sjfb8856606 #define	TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
737*2d9fd380Sjfb8856606 	QMD_TAILQ_CHECK_NEXT(listelm, field);				\
738*2d9fd380Sjfb8856606 	if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
739*2d9fd380Sjfb8856606 		TAILQ_NEXT((elm), field)->field.tqe_prev = 		\
740*2d9fd380Sjfb8856606 		    &TAILQ_NEXT((elm), field);				\
741*2d9fd380Sjfb8856606 	else {								\
742*2d9fd380Sjfb8856606 		(head)->tqh_last = &TAILQ_NEXT((elm), field);		\
743*2d9fd380Sjfb8856606 		QMD_TRACE_HEAD(head);					\
744*2d9fd380Sjfb8856606 	}								\
745*2d9fd380Sjfb8856606 	TAILQ_NEXT((listelm), field) = (elm);				\
746*2d9fd380Sjfb8856606 	(elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field);		\
747*2d9fd380Sjfb8856606 	QMD_TRACE_ELEM(&(elm)->field);					\
748*2d9fd380Sjfb8856606 	QMD_TRACE_ELEM(&(listelm)->field);				\
749*2d9fd380Sjfb8856606 } while (0)
750*2d9fd380Sjfb8856606 
751*2d9fd380Sjfb8856606 #define	TAILQ_INSERT_BEFORE(listelm, elm, field) do {			\
752*2d9fd380Sjfb8856606 	QMD_TAILQ_CHECK_PREV(listelm, field);				\
753*2d9fd380Sjfb8856606 	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
754*2d9fd380Sjfb8856606 	TAILQ_NEXT((elm), field) = (listelm);				\
755*2d9fd380Sjfb8856606 	*(listelm)->field.tqe_prev = (elm);				\
756*2d9fd380Sjfb8856606 	(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field);		\
757*2d9fd380Sjfb8856606 	QMD_TRACE_ELEM(&(elm)->field);					\
758*2d9fd380Sjfb8856606 	QMD_TRACE_ELEM(&(listelm)->field);				\
759*2d9fd380Sjfb8856606 } while (0)
760*2d9fd380Sjfb8856606 
761*2d9fd380Sjfb8856606 #define	TAILQ_INSERT_HEAD(head, elm, field) do {			\
762*2d9fd380Sjfb8856606 	QMD_TAILQ_CHECK_HEAD(head, field);				\
763*2d9fd380Sjfb8856606 	if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL)	\
764*2d9fd380Sjfb8856606 		TAILQ_FIRST((head))->field.tqe_prev =			\
765*2d9fd380Sjfb8856606 		    &TAILQ_NEXT((elm), field);				\
766*2d9fd380Sjfb8856606 	else								\
767*2d9fd380Sjfb8856606 		(head)->tqh_last = &TAILQ_NEXT((elm), field);		\
768*2d9fd380Sjfb8856606 	TAILQ_FIRST((head)) = (elm);					\
769*2d9fd380Sjfb8856606 	(elm)->field.tqe_prev = &TAILQ_FIRST((head));			\
770*2d9fd380Sjfb8856606 	QMD_TRACE_HEAD(head);						\
771*2d9fd380Sjfb8856606 	QMD_TRACE_ELEM(&(elm)->field);					\
772*2d9fd380Sjfb8856606 } while (0)
773*2d9fd380Sjfb8856606 
774*2d9fd380Sjfb8856606 #define	TAILQ_INSERT_TAIL(head, elm, field) do {			\
775*2d9fd380Sjfb8856606 	QMD_TAILQ_CHECK_TAIL(head, field);				\
776*2d9fd380Sjfb8856606 	TAILQ_NEXT((elm), field) = NULL;				\
777*2d9fd380Sjfb8856606 	(elm)->field.tqe_prev = (head)->tqh_last;			\
778*2d9fd380Sjfb8856606 	*(head)->tqh_last = (elm);					\
779*2d9fd380Sjfb8856606 	(head)->tqh_last = &TAILQ_NEXT((elm), field);			\
780*2d9fd380Sjfb8856606 	QMD_TRACE_HEAD(head);						\
781*2d9fd380Sjfb8856606 	QMD_TRACE_ELEM(&(elm)->field);					\
782*2d9fd380Sjfb8856606 } while (0)
783*2d9fd380Sjfb8856606 
784*2d9fd380Sjfb8856606 #define	TAILQ_LAST(head, headname)					\
785*2d9fd380Sjfb8856606 	(*(((struct headname *)((head)->tqh_last))->tqh_last))
786*2d9fd380Sjfb8856606 
787*2d9fd380Sjfb8856606 /*
788*2d9fd380Sjfb8856606  * The FAST function is fast in that it causes no data access other
789*2d9fd380Sjfb8856606  * then the access to the head. The standard LAST function above
790*2d9fd380Sjfb8856606  * will cause a data access of both the element you want and
791*2d9fd380Sjfb8856606  * the previous element. FAST is very useful for instances when
792*2d9fd380Sjfb8856606  * you may want to prefetch the last data element.
793*2d9fd380Sjfb8856606  */
794*2d9fd380Sjfb8856606 #define	TAILQ_LAST_FAST(head, type, field)			\
795*2d9fd380Sjfb8856606     (TAILQ_EMPTY(head) ? NULL : __containerof((head)->tqh_last, QUEUE_TYPEOF(type), field.tqe_next))
796*2d9fd380Sjfb8856606 
797*2d9fd380Sjfb8856606 #define	TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
798*2d9fd380Sjfb8856606 
799*2d9fd380Sjfb8856606 #define	TAILQ_PREV(elm, headname, field)				\
800*2d9fd380Sjfb8856606 	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
801*2d9fd380Sjfb8856606 
802*2d9fd380Sjfb8856606 #define	TAILQ_PREV_FAST(elm, head, type, field)				\
803*2d9fd380Sjfb8856606     ((elm)->field.tqe_prev == &(head)->tqh_first ? NULL :		\
804*2d9fd380Sjfb8856606      __containerof((elm)->field.tqe_prev, QUEUE_TYPEOF(type), field.tqe_next))
805*2d9fd380Sjfb8856606 
806*2d9fd380Sjfb8856606 #define	TAILQ_REMOVE(head, elm, field) do {				\
807*2d9fd380Sjfb8856606 	QMD_SAVELINK(oldnext, (elm)->field.tqe_next);			\
808*2d9fd380Sjfb8856606 	QMD_SAVELINK(oldprev, (elm)->field.tqe_prev);			\
809*2d9fd380Sjfb8856606 	QMD_TAILQ_CHECK_NEXT(elm, field);				\
810*2d9fd380Sjfb8856606 	QMD_TAILQ_CHECK_PREV(elm, field);				\
811*2d9fd380Sjfb8856606 	if ((TAILQ_NEXT((elm), field)) != NULL)				\
812*2d9fd380Sjfb8856606 		TAILQ_NEXT((elm), field)->field.tqe_prev = 		\
813*2d9fd380Sjfb8856606 		    (elm)->field.tqe_prev;				\
814*2d9fd380Sjfb8856606 	else {								\
815*2d9fd380Sjfb8856606 		(head)->tqh_last = (elm)->field.tqe_prev;		\
816*2d9fd380Sjfb8856606 		QMD_TRACE_HEAD(head);					\
817*2d9fd380Sjfb8856606 	}								\
818*2d9fd380Sjfb8856606 	*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field);		\
819*2d9fd380Sjfb8856606 	TRASHIT(*oldnext);						\
820*2d9fd380Sjfb8856606 	TRASHIT(*oldprev);						\
821*2d9fd380Sjfb8856606 	QMD_TRACE_ELEM(&(elm)->field);					\
822*2d9fd380Sjfb8856606 } while (0)
823*2d9fd380Sjfb8856606 
824*2d9fd380Sjfb8856606 #define TAILQ_SWAP(head1, head2, type, field) do {			\
825*2d9fd380Sjfb8856606 	QUEUE_TYPEOF(type) *swap_first = (head1)->tqh_first;		\
826*2d9fd380Sjfb8856606 	QUEUE_TYPEOF(type) **swap_last = (head1)->tqh_last;		\
827*2d9fd380Sjfb8856606 	(head1)->tqh_first = (head2)->tqh_first;			\
828*2d9fd380Sjfb8856606 	(head1)->tqh_last = (head2)->tqh_last;				\
829*2d9fd380Sjfb8856606 	(head2)->tqh_first = swap_first;				\
830*2d9fd380Sjfb8856606 	(head2)->tqh_last = swap_last;					\
831*2d9fd380Sjfb8856606 	if ((swap_first = (head1)->tqh_first) != NULL)			\
832*2d9fd380Sjfb8856606 		swap_first->field.tqe_prev = &(head1)->tqh_first;	\
833*2d9fd380Sjfb8856606 	else								\
834*2d9fd380Sjfb8856606 		(head1)->tqh_last = &(head1)->tqh_first;		\
835*2d9fd380Sjfb8856606 	if ((swap_first = (head2)->tqh_first) != NULL)			\
836*2d9fd380Sjfb8856606 		swap_first->field.tqe_prev = &(head2)->tqh_first;	\
837*2d9fd380Sjfb8856606 	else								\
838*2d9fd380Sjfb8856606 		(head2)->tqh_last = &(head2)->tqh_first;		\
839*2d9fd380Sjfb8856606 } while (0)
840*2d9fd380Sjfb8856606 
841*2d9fd380Sjfb8856606 #endif /* !_SYS_QUEUE_H_ */
842