queue.h revision 242893
155714Skris/*-
2296465Sdelphij * Copyright (c) 1991, 1993
3296465Sdelphij *	The Regents of the University of California.  All rights reserved.
4296465Sdelphij *
555714Skris * Redistribution and use in source and binary forms, with or without
655714Skris * modification, are permitted provided that the following conditions
7160814Ssimon * are met:
855714Skris * 1. Redistributions of source code must retain the above copyright
955714Skris *    notice, this list of conditions and the following disclaimer.
1055714Skris * 2. Redistributions in binary form must reproduce the above copyright
1155714Skris *    notice, this list of conditions and the following disclaimer in the
1255714Skris *    documentation and/or other materials provided with the distribution.
1355714Skris * 4. Neither the name of the University nor the names of its contributors
14296465Sdelphij *    may be used to endorse or promote products derived from this software
1555714Skris *    without specific prior written permission.
1655714Skris *
1755714Skris * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1855714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1955714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2055714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2155714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2255714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2355714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2455714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2555714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2655714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2755714Skris * SUCH DAMAGE.
2855714Skris *
2955714Skris *	@(#)queue.h	8.5 (Berkeley) 8/20/94
3055714Skris * $FreeBSD: stable/9/sys/sys/queue.h 242893 2012-11-11 12:21:51Z ed $
3155714Skris */
3255714Skris
3355714Skris#ifndef _SYS_QUEUE_H_
3455714Skris#define	_SYS_QUEUE_H_
3555714Skris
3655714Skris#include <sys/cdefs.h>
3755714Skris
3855714Skris/*
3955714Skris * This file defines four types of data structures: singly-linked lists,
4055714Skris * singly-linked tail queues, lists and tail queues.
4155714Skris *
4255714Skris * A singly-linked list is headed by a single forward pointer. The elements
4355714Skris * are singly linked for minimum space and pointer manipulation overhead at
4455714Skris * the expense of O(n) removal for arbitrary elements. New elements can be
4555714Skris * added to the list after an existing element or at the head of the list.
4655714Skris * Elements being removed from the head of the list should use the explicit
4755714Skris * macro for this purpose for optimum efficiency. A singly-linked list may
4855714Skris * only be traversed in the forward direction.  Singly-linked lists are ideal
4955714Skris * for applications with large datasets and few or no removals or for
5055714Skris * implementing a LIFO queue.
5155714Skris *
5255714Skris * A singly-linked tail queue is headed by a pair of pointers, one to the
5355714Skris * head of the list and the other to the tail of the list. The elements are
5455714Skris * singly linked for minimum space and pointer manipulation overhead at the
5555714Skris * expense of O(n) removal for arbitrary elements. New elements can be added
5655714Skris * to the list after an existing element, at the head of the list, or at the
5755714Skris * end of the list. Elements being removed from the head of the tail queue
5855714Skris * should use the explicit macro for this purpose for optimum efficiency.
5955714Skris * A singly-linked tail queue may only be traversed in the forward direction.
60296465Sdelphij * Singly-linked tail queues are ideal for applications with large datasets
6155714Skris * and few or no removals or for implementing a FIFO queue.
62296465Sdelphij *
63296465Sdelphij * A list is headed by a single forward pointer (or an array of forward
64296465Sdelphij * pointers for a hash table header). The elements are doubly linked
6568651Skris * so that an arbitrary element can be removed without a need to
6655714Skris * traverse the list. New elements can be added to the list before
6755714Skris * or after an existing element or at the head of the list. A list
6855714Skris * may be traversed in either direction.
6955714Skris *
7055714Skris * A tail queue is headed by a pair of pointers, one to the head of the
7155714Skris * list and the other to the tail of the list. The elements are doubly
7255714Skris * linked so that an arbitrary element can be removed without a need to
7355714Skris * traverse the list. New elements can be added to the list before or
7455714Skris * after an existing element, at the head of the list, or at the end of
7555714Skris * the list. A tail queue may be traversed in either direction.
76296465Sdelphij *
77296465Sdelphij * For details on the use of these macros, see the queue(3) manual page.
78296465Sdelphij *
79296465Sdelphij *
80296465Sdelphij *				SLIST	LIST	STAILQ	TAILQ
81296465Sdelphij * _HEAD			+	+	+	+
82296465Sdelphij * _HEAD_INITIALIZER		+	+	+	+
83296465Sdelphij * _ENTRY			+	+	+	+
84296465Sdelphij * _INIT			+	+	+	+
85296465Sdelphij * _EMPTY			+	+	+	+
86296465Sdelphij * _FIRST			+	+	+	+
87296465Sdelphij * _NEXT			+	+	+	+
88296465Sdelphij * _PREV			-	+	-	+
89296465Sdelphij * _LAST			-	-	+	+
90296465Sdelphij * _FOREACH			+	+	+	+
91296465Sdelphij * _FOREACH_SAFE		+	+	+	+
92296465Sdelphij * _FOREACH_REVERSE		-	-	-	+
93296465Sdelphij * _FOREACH_REVERSE_SAFE	-	-	-	+
9455714Skris * _INSERT_HEAD			+	+	+	+
9555714Skris * _INSERT_BEFORE		-	+	-	+
9655714Skris * _INSERT_AFTER		+	+	+	+
9755714Skris * _INSERT_TAIL			-	-	+	+
98296465Sdelphij * _CONCAT			-	-	+	+
99296465Sdelphij * _REMOVE_AFTER		+	-	+	-
100109998Smarkm * _REMOVE_HEAD			+	-	+	-
101296465Sdelphij * _REMOVE			+	+	+	+
102109998Smarkm * _SWAP			+	+	+	+
103296465Sdelphij *
104296465Sdelphij */
105296465Sdelphij#ifdef QUEUE_MACRO_DEBUG
106296465Sdelphij/* Store the last 2 places the queue element or head was altered */
10755714Skrisstruct qm_trace {
108296465Sdelphij	char * lastfile;
109296465Sdelphij	int lastline;
11055714Skris	char * prevfile;
111296465Sdelphij	int prevline;
112296465Sdelphij};
11355714Skris
114296465Sdelphij#define	TRACEBUF	struct qm_trace trace;
115296465Sdelphij#define	TRASHIT(x)	do {(x) = (void *)-1;} while (0)
116296465Sdelphij#define	QMD_SAVELINK(name, link)	void **name = (void *)&(link)
11755714Skris
11855714Skris#define	QMD_TRACE_HEAD(head) do {					\
11955714Skris	(head)->trace.prevline = (head)->trace.lastline;		\
120296465Sdelphij	(head)->trace.prevfile = (head)->trace.lastfile;		\
121296465Sdelphij	(head)->trace.lastline = __LINE__;				\
122296465Sdelphij	(head)->trace.lastfile = __FILE__;				\
123296465Sdelphij} while (0)
12455714Skris
12555714Skris#define	QMD_TRACE_ELEM(elem) do {					\
12655714Skris	(elem)->trace.prevline = (elem)->trace.lastline;		\
12755714Skris	(elem)->trace.prevfile = (elem)->trace.lastfile;		\
128296465Sdelphij	(elem)->trace.lastline = __LINE__;				\
129296465Sdelphij	(elem)->trace.lastfile = __FILE__;				\
130296465Sdelphij} while (0)
131296465Sdelphij
132296465Sdelphij#else
133296465Sdelphij#define	QMD_TRACE_ELEM(elem)
134296465Sdelphij#define	QMD_TRACE_HEAD(head)
135296465Sdelphij#define	QMD_SAVELINK(name, link)
13655714Skris#define	TRACEBUF
13755714Skris#define	TRASHIT(x)
13855714Skris#endif	/* QUEUE_MACRO_DEBUG */
13955714Skris
14055714Skris/*
14168651Skris * Singly-linked List declarations.
14268651Skris */
14355714Skris#define	SLIST_HEAD(name, type)						\
144296465Sdelphijstruct name {								\
145296465Sdelphij	struct type *slh_first;	/* first element */			\
146296465Sdelphij}
14755714Skris
14855714Skris#define	SLIST_HEAD_INITIALIZER(head)					\
14955714Skris	{ NULL }
15055714Skris
151296465Sdelphij#define	SLIST_ENTRY(type)						\
152296465Sdelphijstruct {								\
15355714Skris	struct type *sle_next;	/* next element */			\
15455714Skris}
15555714Skris
156296465Sdelphij/*
157296465Sdelphij * Singly-linked List functions.
15855714Skris */
15955714Skris#define	SLIST_EMPTY(head)	((head)->slh_first == NULL)
16059191Skris
161296465Sdelphij#define	SLIST_FIRST(head)	((head)->slh_first)
162296465Sdelphij
16359191Skris#define	SLIST_FOREACH(var, head, field)					\
16459191Skris	for ((var) = SLIST_FIRST((head));				\
165109998Smarkm	    (var);							\
166296465Sdelphij	    (var) = SLIST_NEXT((var), field))
167296465Sdelphij
168109998Smarkm#define	SLIST_FOREACH_SAFE(var, head, field, tvar)			\
169109998Smarkm	for ((var) = SLIST_FIRST((head));				\
17055714Skris	    (var) && ((tvar) = SLIST_NEXT((var), field), 1);		\
171296465Sdelphij	    (var) = (tvar))
172296465Sdelphij
173296465Sdelphij#define	SLIST_FOREACH_PREVPTR(var, varp, head, field)			\
174296465Sdelphij	for ((varp) = &SLIST_FIRST((head));				\
175296465Sdelphij	    ((var) = *(varp)) != NULL;					\
176296465Sdelphij	    (varp) = &SLIST_NEXT((var), field))
177296465Sdelphij
178296465Sdelphij#define	SLIST_INIT(head) do {						\
179296465Sdelphij	SLIST_FIRST((head)) = NULL;					\
180296465Sdelphij} while (0)
181296465Sdelphij
182296465Sdelphij#define	SLIST_INSERT_AFTER(slistelm, elm, field) do {			\
183296465Sdelphij	SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field);	\
184296465Sdelphij	SLIST_NEXT((slistelm), field) = (elm);				\
185296465Sdelphij} while (0)
186296465Sdelphij
187296465Sdelphij#define	SLIST_INSERT_HEAD(head, elm, field) do {			\
188296465Sdelphij	SLIST_NEXT((elm), field) = SLIST_FIRST((head));			\
189296465Sdelphij	SLIST_FIRST((head)) = (elm);					\
190296465Sdelphij} while (0)
191296465Sdelphij
192296465Sdelphij#define	SLIST_NEXT(elm, field)	((elm)->field.sle_next)
193296465Sdelphij
194296465Sdelphij#define	SLIST_REMOVE(head, elm, type, field) do {			\
195296465Sdelphij	QMD_SAVELINK(oldnext, (elm)->field.sle_next);			\
196296465Sdelphij	if (SLIST_FIRST((head)) == (elm)) {				\
197296465Sdelphij		SLIST_REMOVE_HEAD((head), field);			\
198296465Sdelphij	}								\
199296465Sdelphij	else {								\
20055714Skris		struct type *curelm = SLIST_FIRST((head));		\
20155714Skris		while (SLIST_NEXT(curelm, field) != (elm))		\
202109998Smarkm			curelm = SLIST_NEXT(curelm, field);		\
203109998Smarkm		SLIST_REMOVE_AFTER(curelm, field);			\
20459191Skris	}								\
205296465Sdelphij	TRASHIT(*oldnext);						\
206296465Sdelphij} while (0)
20759191Skris
20859191Skris#define SLIST_REMOVE_AFTER(elm, field) do {				\
209109998Smarkm	SLIST_NEXT(elm, field) =					\
210109998Smarkm	    SLIST_NEXT(SLIST_NEXT(elm, field), field);			\
211109998Smarkm} while (0)
212109998Smarkm
21355714Skris#define	SLIST_REMOVE_HEAD(head, field) do {				\
21455714Skris	SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field);	\
21555714Skris} while (0)
21659191Skris
21759191Skris#define SLIST_SWAP(head1, head2, type) do {				\
21859191Skris	struct type *swap_first = SLIST_FIRST(head1);			\
21955714Skris	SLIST_FIRST(head1) = SLIST_FIRST(head2);			\
220296465Sdelphij	SLIST_FIRST(head2) = swap_first;				\
221296465Sdelphij} while (0)
222296465Sdelphij
223296465Sdelphij/*
224296465Sdelphij * Singly-linked Tail queue declarations.
22555714Skris */
22655714Skris#define	STAILQ_HEAD(name, type)						\
22755714Skrisstruct name {								\
228296465Sdelphij	struct type *stqh_first;/* first element */			\
229296465Sdelphij	struct type **stqh_last;/* addr of last next element */		\
230296465Sdelphij}
23155714Skris
23255714Skris#define	STAILQ_HEAD_INITIALIZER(head)					\
233109998Smarkm	{ NULL, &(head).stqh_first }
234109998Smarkm
23555714Skris#define	STAILQ_ENTRY(type)						\
23655714Skrisstruct {								\
23755714Skris	struct type *stqe_next;	/* next element */			\
23855714Skris}
239296465Sdelphij
240296465Sdelphij/*
241296465Sdelphij * Singly-linked Tail queue functions.
24255714Skris */
24355714Skris#define	STAILQ_CONCAT(head1, head2) do {				\
24455714Skris	if (!STAILQ_EMPTY((head2))) {					\
24555714Skris		*(head1)->stqh_last = (head2)->stqh_first;		\
24655714Skris		(head1)->stqh_last = (head2)->stqh_last;		\
247296465Sdelphij		STAILQ_INIT((head2));					\
248296465Sdelphij	}								\
24955714Skris} while (0)
25055714Skris
25155714Skris#define	STAILQ_EMPTY(head)	((head)->stqh_first == NULL)
25255714Skris
25355714Skris#define	STAILQ_FIRST(head)	((head)->stqh_first)
25455714Skris
255296465Sdelphij#define	STAILQ_FOREACH(var, head, field)				\
256296465Sdelphij	for((var) = STAILQ_FIRST((head));				\
25755714Skris	   (var);							\
25855714Skris	   (var) = STAILQ_NEXT((var), field))
25955714Skris
260296465Sdelphij
261296465Sdelphij#define	STAILQ_FOREACH_SAFE(var, head, field, tvar)			\
26255714Skris	for ((var) = STAILQ_FIRST((head));				\
26355714Skris	    (var) && ((tvar) = STAILQ_NEXT((var), field), 1);		\
26455714Skris	    (var) = (tvar))
265296465Sdelphij
266296465Sdelphij#define	STAILQ_INIT(head) do {						\
26755714Skris	STAILQ_FIRST((head)) = NULL;					\
26855714Skris	(head)->stqh_last = &STAILQ_FIRST((head));			\
26955714Skris} while (0)
270296465Sdelphij
271296465Sdelphij#define	STAILQ_INSERT_AFTER(head, tqelm, elm, field) do {		\
272296465Sdelphij	if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
273296465Sdelphij		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
274296465Sdelphij	STAILQ_NEXT((tqelm), field) = (elm);				\
275296465Sdelphij} while (0)
27655714Skris
27755714Skris#define	STAILQ_INSERT_HEAD(head, elm, field) do {			\
27855714Skris	if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL)	\
27955714Skris		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
28055714Skris	STAILQ_FIRST((head)) = (elm);					\
28155714Skris} while (0)
282296465Sdelphij
283296465Sdelphij#define	STAILQ_INSERT_TAIL(head, elm, field) do {			\
28455714Skris	STAILQ_NEXT((elm), field) = NULL;				\
28555714Skris	*(head)->stqh_last = (elm);					\
286109998Smarkm	(head)->stqh_last = &STAILQ_NEXT((elm), field);			\
287109998Smarkm} while (0)
28855714Skris
28955714Skris#define	STAILQ_LAST(head, type, field)					\
29055714Skris	(STAILQ_EMPTY((head)) ? NULL :					\
291160814Ssimon	    __containerof((head)->stqh_last, struct type, field.stqe_next))
292296465Sdelphij
293296465Sdelphij#define	STAILQ_NEXT(elm, field)	((elm)->field.stqe_next)
294160814Ssimon
295160814Ssimon#define	STAILQ_REMOVE(head, elm, type, field) do {			\
296160814Ssimon	QMD_SAVELINK(oldnext, (elm)->field.stqe_next);			\
297160814Ssimon	if (STAILQ_FIRST((head)) == (elm)) {				\
298160814Ssimon		STAILQ_REMOVE_HEAD((head), field);			\
299160814Ssimon	}								\
300160814Ssimon	else {								\
301296465Sdelphij		struct type *curelm = STAILQ_FIRST((head));		\
302296465Sdelphij		while (STAILQ_NEXT(curelm, field) != (elm))		\
303296465Sdelphij			curelm = STAILQ_NEXT(curelm, field);		\
304160814Ssimon		STAILQ_REMOVE_AFTER(head, curelm, field);		\
305160814Ssimon	}								\
306160814Ssimon	TRASHIT(*oldnext);						\
307160814Ssimon} while (0)
308160814Ssimon
309296465Sdelphij#define STAILQ_REMOVE_AFTER(head, elm, field) do {			\
310296465Sdelphij	if ((STAILQ_NEXT(elm, field) =					\
311160814Ssimon	     STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL)	\
312160814Ssimon		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
313160814Ssimon} while (0)
314296465Sdelphij
315296465Sdelphij#define	STAILQ_REMOVE_HEAD(head, field) do {				\
316160814Ssimon	if ((STAILQ_FIRST((head)) =					\
317160814Ssimon	     STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL)		\
318160814Ssimon		(head)->stqh_last = &STAILQ_FIRST((head));		\
319296465Sdelphij} while (0)
320296465Sdelphij
321296465Sdelphij#define STAILQ_SWAP(head1, head2, type) do {				\
322296465Sdelphij	struct type *swap_first = STAILQ_FIRST(head1);			\
323160814Ssimon	struct type **swap_last = (head1)->stqh_last;			\
324296465Sdelphij	STAILQ_FIRST(head1) = STAILQ_FIRST(head2);			\
325296465Sdelphij	(head1)->stqh_last = (head2)->stqh_last;			\
326296465Sdelphij	STAILQ_FIRST(head2) = swap_first;				\
327296465Sdelphij	(head2)->stqh_last = swap_last;					\
328160814Ssimon	if (STAILQ_EMPTY(head1))					\
329160814Ssimon		(head1)->stqh_last = &STAILQ_FIRST(head1);		\
330160814Ssimon	if (STAILQ_EMPTY(head2))					\
331160814Ssimon		(head2)->stqh_last = &STAILQ_FIRST(head2);		\
332296465Sdelphij} while (0)
33355714Skris
33455714Skris
335296465Sdelphij/*
336296465Sdelphij * List declarations.
337296465Sdelphij */
33855714Skris#define	LIST_HEAD(name, type)						\
339296465Sdelphijstruct name {								\
340296465Sdelphij	struct type *lh_first;	/* first element */			\
341296465Sdelphij}
342296465Sdelphij
343296465Sdelphij#define	LIST_HEAD_INITIALIZER(head)					\
344296465Sdelphij	{ NULL }
345296465Sdelphij
34655714Skris#define	LIST_ENTRY(type)						\
347296465Sdelphijstruct {								\
348296465Sdelphij	struct type *le_next;	/* next element */			\
349296465Sdelphij	struct type **le_prev;	/* address of previous next element */	\
350296465Sdelphij}
351296465Sdelphij
352296465Sdelphij/*
35355714Skris * List functions.
354296465Sdelphij */
35555714Skris
35659191Skris#if (defined(_KERNEL) && defined(INVARIANTS))
35759191Skris#define	QMD_LIST_CHECK_HEAD(head, field) do {				\
358296465Sdelphij	if (LIST_FIRST((head)) != NULL &&				\
359296465Sdelphij	    LIST_FIRST((head))->field.le_prev !=			\
360296465Sdelphij	     &LIST_FIRST((head)))					\
361296465Sdelphij		panic("Bad list head %p first->prev != head", (head));	\
36259191Skris} while (0)
363296465Sdelphij
364194206Ssimon#define	QMD_LIST_CHECK_NEXT(elm, field) do {				\
365296465Sdelphij	if (LIST_NEXT((elm), field) != NULL &&				\
366296465Sdelphij	    LIST_NEXT((elm), field)->field.le_prev !=			\
367296465Sdelphij	     &((elm)->field.le_next))					\
368296465Sdelphij	     	panic("Bad link elm %p next->prev != elm", (elm));	\
369296465Sdelphij} while (0)
370296465Sdelphij
371296465Sdelphij#define	QMD_LIST_CHECK_PREV(elm, field) do {				\
37259191Skris	if (*(elm)->field.le_prev != (elm))				\
373296465Sdelphij		panic("Bad link elm %p prev->next != elm", (elm));	\
374160814Ssimon} while (0)
375296465Sdelphij#else
376296465Sdelphij#define	QMD_LIST_CHECK_HEAD(head, field)
377296465Sdelphij#define	QMD_LIST_CHECK_NEXT(elm, field)
378296465Sdelphij#define	QMD_LIST_CHECK_PREV(elm, field)
379296465Sdelphij#endif /* (_KERNEL && INVARIANTS) */
380296465Sdelphij
381296465Sdelphij#define	LIST_EMPTY(head)	((head)->lh_first == NULL)
382296465Sdelphij
383296465Sdelphij#define	LIST_FIRST(head)	((head)->lh_first)
38459191Skris
385296465Sdelphij#define	LIST_FOREACH(var, head, field)					\
386296465Sdelphij	for ((var) = LIST_FIRST((head));				\
387296465Sdelphij	    (var);							\
388296465Sdelphij	    (var) = LIST_NEXT((var), field))
389296465Sdelphij
390296465Sdelphij#define	LIST_FOREACH_SAFE(var, head, field, tvar)			\
391296465Sdelphij	for ((var) = LIST_FIRST((head));				\
392296465Sdelphij	    (var) && ((tvar) = LIST_NEXT((var), field), 1);		\
39359191Skris	    (var) = (tvar))
394296465Sdelphij
395296465Sdelphij#define	LIST_INIT(head) do {						\
396296465Sdelphij	LIST_FIRST((head)) = NULL;					\
397296465Sdelphij} while (0)
398296465Sdelphij
399296465Sdelphij#define	LIST_INSERT_AFTER(listelm, elm, field) do {			\
400296465Sdelphij	QMD_LIST_CHECK_NEXT(listelm, field);				\
401296465Sdelphij	if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
40259191Skris		LIST_NEXT((listelm), field)->field.le_prev =		\
403296465Sdelphij		    &LIST_NEXT((elm), field);				\
404296465Sdelphij	LIST_NEXT((listelm), field) = (elm);				\
40559191Skris	(elm)->field.le_prev = &LIST_NEXT((listelm), field);		\
40659191Skris} while (0)
407296465Sdelphij
408296465Sdelphij#define	LIST_INSERT_BEFORE(listelm, elm, field) do {			\
409296465Sdelphij	QMD_LIST_CHECK_PREV(listelm, field);				\
410296465Sdelphij	(elm)->field.le_prev = (listelm)->field.le_prev;		\
411296465Sdelphij	LIST_NEXT((elm), field) = (listelm);				\
412296465Sdelphij	*(listelm)->field.le_prev = (elm);				\
413296465Sdelphij	(listelm)->field.le_prev = &LIST_NEXT((elm), field);		\
41459191Skris} while (0)
41559191Skris
416296465Sdelphij#define	LIST_INSERT_HEAD(head, elm, field) do {				\
417296465Sdelphij	QMD_LIST_CHECK_HEAD((head), field);				\
418296465Sdelphij	if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL)	\
419296465Sdelphij		LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
420296465Sdelphij	LIST_FIRST((head)) = (elm);					\
421296465Sdelphij	(elm)->field.le_prev = &LIST_FIRST((head));			\
422296465Sdelphij} while (0)
423296465Sdelphij
42459191Skris#define	LIST_NEXT(elm, field)	((elm)->field.le_next)
425296465Sdelphij
426296465Sdelphij#define	LIST_PREV(elm, head, type, field)				\
42759191Skris	((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL :		\
428109998Smarkm	    __containerof((elm)->field.le_prev, struct type, field.le_next))
42959191Skris
430296465Sdelphij#define	LIST_REMOVE(elm, field) do {					\
431109998Smarkm	QMD_SAVELINK(oldnext, (elm)->field.le_next);			\
432296465Sdelphij	QMD_SAVELINK(oldprev, (elm)->field.le_prev);			\
433109998Smarkm	QMD_LIST_CHECK_NEXT(elm, field);				\
434296465Sdelphij	QMD_LIST_CHECK_PREV(elm, field);				\
435109998Smarkm	if (LIST_NEXT((elm), field) != NULL)				\
436296465Sdelphij		LIST_NEXT((elm), field)->field.le_prev = 		\
437109998Smarkm		    (elm)->field.le_prev;				\
438296465Sdelphij	*(elm)->field.le_prev = LIST_NEXT((elm), field);		\
43955714Skris	TRASHIT(*oldnext);						\
440109998Smarkm	TRASHIT(*oldprev);						\
44155714Skris} while (0)
442296465Sdelphij
443296465Sdelphij#define LIST_SWAP(head1, head2, type, field) do {			\
444296465Sdelphij	struct type *swap_tmp = LIST_FIRST((head1));			\
445296465Sdelphij	LIST_FIRST((head1)) = LIST_FIRST((head2));			\
446296465Sdelphij	LIST_FIRST((head2)) = swap_tmp;					\
447296465Sdelphij	if ((swap_tmp = LIST_FIRST((head1))) != NULL)			\
448296465Sdelphij		swap_tmp->field.le_prev = &LIST_FIRST((head1));		\
449296465Sdelphij	if ((swap_tmp = LIST_FIRST((head2))) != NULL)			\
45055714Skris		swap_tmp->field.le_prev = &LIST_FIRST((head2));		\
451109998Smarkm} while (0)
45255714Skris
453109998Smarkm/*
454109998Smarkm * Tail queue declarations.
455109998Smarkm */
456109998Smarkm#define	TAILQ_HEAD(name, type)						\
457109998Smarkmstruct name {								\
458296465Sdelphij	struct type *tqh_first;	/* first element */			\
459296465Sdelphij	struct type **tqh_last;	/* addr of last next element */		\
460296465Sdelphij	TRACEBUF							\
461296465Sdelphij}
462296465Sdelphij
46355714Skris#define	TAILQ_HEAD_INITIALIZER(head)					\
46455714Skris	{ NULL, &(head).tqh_first }
46555714Skris
46655714Skris#define	TAILQ_ENTRY(type)						\
46755714Skrisstruct {								\
468109998Smarkm	struct type *tqe_next;	/* next element */			\
46955714Skris	struct type **tqe_prev;	/* address of previous next element */	\
470109998Smarkm	TRACEBUF							\
47155714Skris}
472109998Smarkm
473109998Smarkm/*
474160814Ssimon * Tail queue functions.
475296465Sdelphij */
476296465Sdelphij#if (defined(_KERNEL) && defined(INVARIANTS))
477160814Ssimon#define	QMD_TAILQ_CHECK_HEAD(head, field) do {				\
478296465Sdelphij	if (!TAILQ_EMPTY(head) &&					\
479296465Sdelphij	    TAILQ_FIRST((head))->field.tqe_prev !=			\
480160814Ssimon	     &TAILQ_FIRST((head)))					\
481296465Sdelphij		panic("Bad tailq head %p first->prev != head", (head));	\
482296465Sdelphij} while (0)
483296465Sdelphij
484109998Smarkm#define	QMD_TAILQ_CHECK_TAIL(head, field) do {				\
485109998Smarkm	if (*(head)->tqh_last != NULL)					\
486109998Smarkm	    	panic("Bad tailq NEXT(%p->tqh_last) != NULL", (head)); 	\
487109998Smarkm} while (0)
48855714Skris
489296465Sdelphij#define	QMD_TAILQ_CHECK_NEXT(elm, field) do {				\
490296465Sdelphij	if (TAILQ_NEXT((elm), field) != NULL &&				\
491296465Sdelphij	    TAILQ_NEXT((elm), field)->field.tqe_prev !=			\
492296465Sdelphij	     &((elm)->field.tqe_next))					\
49355714Skris		panic("Bad link elm %p next->prev != elm", (elm));	\
494109998Smarkm} while (0)
495109998Smarkm
49659191Skris#define	QMD_TAILQ_CHECK_PREV(elm, field) do {				\
497296465Sdelphij	if (*(elm)->field.tqe_prev != (elm))				\
498296465Sdelphij		panic("Bad link elm %p prev->next != elm", (elm));	\
499296465Sdelphij} while (0)
500296465Sdelphij#else
50155714Skris#define	QMD_TAILQ_CHECK_HEAD(head, field)
502109998Smarkm#define	QMD_TAILQ_CHECK_TAIL(head, headname)
503296465Sdelphij#define	QMD_TAILQ_CHECK_NEXT(elm, field)
50455714Skris#define	QMD_TAILQ_CHECK_PREV(elm, field)
505109998Smarkm#endif /* (_KERNEL && INVARIANTS) */
506109998Smarkm
507109998Smarkm#define	TAILQ_CONCAT(head1, head2, field) do {				\
508109998Smarkm	if (!TAILQ_EMPTY(head2)) {					\
509109998Smarkm		*(head1)->tqh_last = (head2)->tqh_first;		\
51055714Skris		(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last;	\
511109998Smarkm		(head1)->tqh_last = (head2)->tqh_last;			\
512109998Smarkm		TAILQ_INIT((head2));					\
513109998Smarkm		QMD_TRACE_HEAD(head1);					\
51455714Skris		QMD_TRACE_HEAD(head2);					\
515109998Smarkm	}								\
516109998Smarkm} while (0)
51755714Skris
518160814Ssimon#define	TAILQ_EMPTY(head)	((head)->tqh_first == NULL)
519160814Ssimon
520160814Ssimon#define	TAILQ_FIRST(head)	((head)->tqh_first)
521160814Ssimon
522160814Ssimon#define	TAILQ_FOREACH(var, head, field)					\
523160814Ssimon	for ((var) = TAILQ_FIRST((head));				\
524160814Ssimon	    (var);							\
525160814Ssimon	    (var) = TAILQ_NEXT((var), field))
526160814Ssimon
527160814Ssimon#define	TAILQ_FOREACH_SAFE(var, head, field, tvar)			\
528160814Ssimon	for ((var) = TAILQ_FIRST((head));				\
529160814Ssimon	    (var) && ((tvar) = TAILQ_NEXT((var), field), 1);		\
530160814Ssimon	    (var) = (tvar))
531296465Sdelphij
532160814Ssimon#define	TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
533296465Sdelphij	for ((var) = TAILQ_LAST((head), headname);			\
534296465Sdelphij	    (var);							\
535296465Sdelphij	    (var) = TAILQ_PREV((var), headname, field))
536296465Sdelphij
53755714Skris#define	TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar)	\
538109998Smarkm	for ((var) = TAILQ_LAST((head), headname);			\
539296465Sdelphij	    (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1);	\
540296465Sdelphij	    (var) = (tvar))
541296465Sdelphij
542296465Sdelphij#define	TAILQ_INIT(head) do {						\
543296465Sdelphij	TAILQ_FIRST((head)) = NULL;					\
544296465Sdelphij	(head)->tqh_last = &TAILQ_FIRST((head));			\
545296465Sdelphij	QMD_TRACE_HEAD(head);						\
546296465Sdelphij} while (0)
547296465Sdelphij
548296465Sdelphij#define	TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
549296465Sdelphij	QMD_TAILQ_CHECK_NEXT(listelm, field);				\
550296465Sdelphij	if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
551109998Smarkm		TAILQ_NEXT((elm), field)->field.tqe_prev = 		\
552296465Sdelphij		    &TAILQ_NEXT((elm), field);				\
553296465Sdelphij	else {								\
554296465Sdelphij		(head)->tqh_last = &TAILQ_NEXT((elm), field);		\
555296465Sdelphij		QMD_TRACE_HEAD(head);					\
556296465Sdelphij	}								\
557296465Sdelphij	TAILQ_NEXT((listelm), field) = (elm);				\
558296465Sdelphij	(elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field);		\
559296465Sdelphij	QMD_TRACE_ELEM(&(elm)->field);					\
560296465Sdelphij	QMD_TRACE_ELEM(&listelm->field);				\
561296465Sdelphij} while (0)
562109998Smarkm
56355714Skris#define	TAILQ_INSERT_BEFORE(listelm, elm, field) do {			\
564296465Sdelphij	QMD_TAILQ_CHECK_PREV(listelm, field);				\
56555714Skris	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
56655714Skris	TAILQ_NEXT((elm), field) = (listelm);				\
567109998Smarkm	*(listelm)->field.tqe_prev = (elm);				\
56855714Skris	(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field);		\
569296465Sdelphij	QMD_TRACE_ELEM(&(elm)->field);					\
57055714Skris	QMD_TRACE_ELEM(&listelm->field);				\
571296465Sdelphij} while (0)
572296465Sdelphij
57355714Skris#define	TAILQ_INSERT_HEAD(head, elm, field) do {			\
574296465Sdelphij	QMD_TAILQ_CHECK_HEAD(head, field);				\
57555714Skris	if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL)	\
576296465Sdelphij		TAILQ_FIRST((head))->field.tqe_prev =			\
57755714Skris		    &TAILQ_NEXT((elm), field);				\
57855714Skris	else								\
579296465Sdelphij		(head)->tqh_last = &TAILQ_NEXT((elm), field);		\
58055714Skris	TAILQ_FIRST((head)) = (elm);					\
581296465Sdelphij	(elm)->field.tqe_prev = &TAILQ_FIRST((head));			\
58255714Skris	QMD_TRACE_HEAD(head);						\
583296465Sdelphij	QMD_TRACE_ELEM(&(elm)->field);					\
58455714Skris} while (0)
585296465Sdelphij
586296465Sdelphij#define	TAILQ_INSERT_TAIL(head, elm, field) do {			\
587296465Sdelphij	QMD_TAILQ_CHECK_TAIL(head, field);				\
588296465Sdelphij	TAILQ_NEXT((elm), field) = NULL;				\
589296465Sdelphij	(elm)->field.tqe_prev = (head)->tqh_last;			\
590296465Sdelphij	*(head)->tqh_last = (elm);					\
59155714Skris	(head)->tqh_last = &TAILQ_NEXT((elm), field);			\
59255714Skris	QMD_TRACE_HEAD(head);						\
59355714Skris	QMD_TRACE_ELEM(&(elm)->field);					\
59455714Skris} while (0)
59555714Skris
59655714Skris#define	TAILQ_LAST(head, headname)					\
59755714Skris	(*(((struct headname *)((head)->tqh_last))->tqh_last))
59855714Skris
599109998Smarkm#define	TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
60055714Skris
601296465Sdelphij#define	TAILQ_PREV(elm, headname, field)				\
602296465Sdelphij	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
60359191Skris
60455714Skris#define	TAILQ_REMOVE(head, elm, field) do {				\
605296465Sdelphij	QMD_SAVELINK(oldnext, (elm)->field.tqe_next);			\
606296465Sdelphij	QMD_SAVELINK(oldprev, (elm)->field.tqe_prev);			\
60755714Skris	QMD_TAILQ_CHECK_NEXT(elm, field);				\
60855714Skris	QMD_TAILQ_CHECK_PREV(elm, field);				\
60955714Skris	if ((TAILQ_NEXT((elm), field)) != NULL)				\
61055714Skris		TAILQ_NEXT((elm), field)->field.tqe_prev = 		\
61155714Skris		    (elm)->field.tqe_prev;				\
61255714Skris	else {								\
613296465Sdelphij		(head)->tqh_last = (elm)->field.tqe_prev;		\
614296465Sdelphij		QMD_TRACE_HEAD(head);					\
615296465Sdelphij	}								\
61655714Skris	*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field);		\
61755714Skris	TRASHIT(*oldnext);						\
618296465Sdelphij	TRASHIT(*oldprev);						\
619296465Sdelphij	QMD_TRACE_ELEM(&(elm)->field);					\
620296465Sdelphij} while (0)
621109998Smarkm
622160814Ssimon#define TAILQ_SWAP(head1, head2, type, field) do {			\
62359191Skris	struct type *swap_first = (head1)->tqh_first;			\
624109998Smarkm	struct type **swap_last = (head1)->tqh_last;			\
625109998Smarkm	(head1)->tqh_first = (head2)->tqh_first;			\
62668651Skris	(head1)->tqh_last = (head2)->tqh_last;				\
62759191Skris	(head2)->tqh_first = swap_first;				\
628296465Sdelphij	(head2)->tqh_last = swap_last;					\
62959191Skris	if ((swap_first = (head1)->tqh_first) != NULL)			\
63059191Skris		swap_first->field.tqe_prev = &(head1)->tqh_first;	\
63159191Skris	else								\
632296465Sdelphij		(head1)->tqh_last = &(head1)->tqh_first;		\
633296465Sdelphij	if ((swap_first = (head2)->tqh_first) != NULL)			\
63459191Skris		swap_first->field.tqe_prev = &(head2)->tqh_first;	\
63559191Skris	else								\
63659191Skris		(head2)->tqh_last = &(head2)->tqh_first;		\
63759191Skris} while (0)
63859191Skris
63959191Skris#endif /* !_SYS_QUEUE_H_ */
64068651Skris