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