1d74d50a8SDag-Erling Smørgrav /*	$OpenBSD: queue.h,v 1.45 2018/07/12 14:22:54 sashan Exp $	*/
24b17dab0SDag-Erling Smørgrav /*	$NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $	*/
34b17dab0SDag-Erling Smørgrav 
44b17dab0SDag-Erling Smørgrav /*
54b17dab0SDag-Erling Smørgrav  * Copyright (c) 1991, 1993
64b17dab0SDag-Erling Smørgrav  *	The Regents of the University of California.  All rights reserved.
74b17dab0SDag-Erling Smørgrav  *
84b17dab0SDag-Erling Smørgrav  * Redistribution and use in source and binary forms, with or without
94b17dab0SDag-Erling Smørgrav  * modification, are permitted provided that the following conditions
104b17dab0SDag-Erling Smørgrav  * are met:
114b17dab0SDag-Erling Smørgrav  * 1. Redistributions of source code must retain the above copyright
124b17dab0SDag-Erling Smørgrav  *    notice, this list of conditions and the following disclaimer.
134b17dab0SDag-Erling Smørgrav  * 2. Redistributions in binary form must reproduce the above copyright
144b17dab0SDag-Erling Smørgrav  *    notice, this list of conditions and the following disclaimer in the
154b17dab0SDag-Erling Smørgrav  *    documentation and/or other materials provided with the distribution.
16d95e11bfSDag-Erling Smørgrav  * 3. Neither the name of the University nor the names of its contributors
174b17dab0SDag-Erling Smørgrav  *    may be used to endorse or promote products derived from this software
184b17dab0SDag-Erling Smørgrav  *    without specific prior written permission.
194b17dab0SDag-Erling Smørgrav  *
204b17dab0SDag-Erling Smørgrav  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
214b17dab0SDag-Erling Smørgrav  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
224b17dab0SDag-Erling Smørgrav  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
234b17dab0SDag-Erling Smørgrav  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
244b17dab0SDag-Erling Smørgrav  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
254b17dab0SDag-Erling Smørgrav  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
264b17dab0SDag-Erling Smørgrav  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
274b17dab0SDag-Erling Smørgrav  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
284b17dab0SDag-Erling Smørgrav  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
294b17dab0SDag-Erling Smørgrav  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
304b17dab0SDag-Erling Smørgrav  * SUCH DAMAGE.
314b17dab0SDag-Erling Smørgrav  *
324b17dab0SDag-Erling Smørgrav  *	@(#)queue.h	8.5 (Berkeley) 8/20/94
334b17dab0SDag-Erling Smørgrav  */
344b17dab0SDag-Erling Smørgrav 
35*021d409fSDag-Erling Smørgrav /* OPENBSD ORIGINAL: sys/sys/queue.h */
36*021d409fSDag-Erling Smørgrav 
374b17dab0SDag-Erling Smørgrav #ifndef	_FAKE_QUEUE_H_
384b17dab0SDag-Erling Smørgrav #define	_FAKE_QUEUE_H_
394b17dab0SDag-Erling Smørgrav 
404b17dab0SDag-Erling Smørgrav /*
41d74d50a8SDag-Erling Smørgrav  * Require for OS/X and other platforms that have old/broken/incomplete
42d74d50a8SDag-Erling Smørgrav  * <sys/queue.h>.
434b17dab0SDag-Erling Smørgrav  */
444b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_EMPTY
454b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_END
464b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_ENTRY
47d74d50a8SDag-Erling Smørgrav #undef CIRCLEQ_FIRST
484b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_FOREACH
494b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_FOREACH_REVERSE
504b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_HEAD
514b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_HEAD_INITIALIZER
524b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_INIT
534b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_INSERT_AFTER
544b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_INSERT_BEFORE
554b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_INSERT_HEAD
564b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_INSERT_TAIL
574b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_LAST
58d74d50a8SDag-Erling Smørgrav #undef CIRCLEQ_NEXT
594b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_PREV
604b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_REMOVE
614b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_REPLACE
624b17dab0SDag-Erling Smørgrav #undef LIST_EMPTY
634b17dab0SDag-Erling Smørgrav #undef LIST_END
644b17dab0SDag-Erling Smørgrav #undef LIST_ENTRY
654b17dab0SDag-Erling Smørgrav #undef LIST_FIRST
664b17dab0SDag-Erling Smørgrav #undef LIST_FOREACH
674b17dab0SDag-Erling Smørgrav #undef LIST_FOREACH_SAFE
684b17dab0SDag-Erling Smørgrav #undef LIST_HEAD
694b17dab0SDag-Erling Smørgrav #undef LIST_HEAD_INITIALIZER
704b17dab0SDag-Erling Smørgrav #undef LIST_INIT
714b17dab0SDag-Erling Smørgrav #undef LIST_INSERT_AFTER
724b17dab0SDag-Erling Smørgrav #undef LIST_INSERT_BEFORE
734b17dab0SDag-Erling Smørgrav #undef LIST_INSERT_HEAD
744b17dab0SDag-Erling Smørgrav #undef LIST_NEXT
754b17dab0SDag-Erling Smørgrav #undef LIST_REMOVE
764b17dab0SDag-Erling Smørgrav #undef LIST_REPLACE
774b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_CONCAT
784b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_EMPTY
794b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_END
804b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_ENTRY
814b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_FIRST
824b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_FOREACH
834b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_FOREACH_SAFE
844b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_HEAD
854b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_HEAD_INITIALIZER
864b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_INIT
874b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_INSERT_AFTER
884b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_INSERT_HEAD
894b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_INSERT_TAIL
904b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_NEXT
914b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_REMOVE_AFTER
924b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_REMOVE_HEAD
934b17dab0SDag-Erling Smørgrav #undef SLIST_EMPTY
944b17dab0SDag-Erling Smørgrav #undef SLIST_END
954b17dab0SDag-Erling Smørgrav #undef SLIST_ENTRY
964b17dab0SDag-Erling Smørgrav #undef SLIST_FIRST
974b17dab0SDag-Erling Smørgrav #undef SLIST_FOREACH
984b17dab0SDag-Erling Smørgrav #undef SLIST_FOREACH_PREVPTR
994b17dab0SDag-Erling Smørgrav #undef SLIST_FOREACH_SAFE
1004b17dab0SDag-Erling Smørgrav #undef SLIST_HEAD
1014b17dab0SDag-Erling Smørgrav #undef SLIST_HEAD_INITIALIZER
1024b17dab0SDag-Erling Smørgrav #undef SLIST_INIT
1034b17dab0SDag-Erling Smørgrav #undef SLIST_INSERT_AFTER
1044b17dab0SDag-Erling Smørgrav #undef SLIST_INSERT_HEAD
1054b17dab0SDag-Erling Smørgrav #undef SLIST_NEXT
1064b17dab0SDag-Erling Smørgrav #undef SLIST_REMOVE
1074b17dab0SDag-Erling Smørgrav #undef SLIST_REMOVE_AFTER
1084b17dab0SDag-Erling Smørgrav #undef SLIST_REMOVE_HEAD
1094b17dab0SDag-Erling Smørgrav #undef SLIST_REMOVE_NEXT
1104b17dab0SDag-Erling Smørgrav #undef TAILQ_CONCAT
1114b17dab0SDag-Erling Smørgrav #undef TAILQ_EMPTY
1124b17dab0SDag-Erling Smørgrav #undef TAILQ_END
1134b17dab0SDag-Erling Smørgrav #undef TAILQ_ENTRY
1144b17dab0SDag-Erling Smørgrav #undef TAILQ_FIRST
1154b17dab0SDag-Erling Smørgrav #undef TAILQ_FOREACH
1164b17dab0SDag-Erling Smørgrav #undef TAILQ_FOREACH_REVERSE
1174b17dab0SDag-Erling Smørgrav #undef TAILQ_FOREACH_REVERSE_SAFE
1184b17dab0SDag-Erling Smørgrav #undef TAILQ_FOREACH_SAFE
1194b17dab0SDag-Erling Smørgrav #undef TAILQ_HEAD
1204b17dab0SDag-Erling Smørgrav #undef TAILQ_HEAD_INITIALIZER
1214b17dab0SDag-Erling Smørgrav #undef TAILQ_INIT
1224b17dab0SDag-Erling Smørgrav #undef TAILQ_INSERT_AFTER
1234b17dab0SDag-Erling Smørgrav #undef TAILQ_INSERT_BEFORE
1244b17dab0SDag-Erling Smørgrav #undef TAILQ_INSERT_HEAD
1254b17dab0SDag-Erling Smørgrav #undef TAILQ_INSERT_TAIL
1264b17dab0SDag-Erling Smørgrav #undef TAILQ_LAST
1274b17dab0SDag-Erling Smørgrav #undef TAILQ_NEXT
1284b17dab0SDag-Erling Smørgrav #undef TAILQ_PREV
1294b17dab0SDag-Erling Smørgrav #undef TAILQ_REMOVE
1304b17dab0SDag-Erling Smørgrav #undef TAILQ_REPLACE
1314b17dab0SDag-Erling Smørgrav 
1324b17dab0SDag-Erling Smørgrav /*
1334b17dab0SDag-Erling Smørgrav  * This file defines five types of data structures: singly-linked lists,
1344b17dab0SDag-Erling Smørgrav  * lists, simple queues, tail queues and XOR simple queues.
1354b17dab0SDag-Erling Smørgrav  *
1364b17dab0SDag-Erling Smørgrav  *
1374b17dab0SDag-Erling Smørgrav  * A singly-linked list is headed by a single forward pointer. The elements
1384b17dab0SDag-Erling Smørgrav  * are singly linked for minimum space and pointer manipulation overhead at
1394b17dab0SDag-Erling Smørgrav  * the expense of O(n) removal for arbitrary elements. New elements can be
1404b17dab0SDag-Erling Smørgrav  * added to the list after an existing element or at the head of the list.
1414b17dab0SDag-Erling Smørgrav  * Elements being removed from the head of the list should use the explicit
1424b17dab0SDag-Erling Smørgrav  * macro for this purpose for optimum efficiency. A singly-linked list may
1434b17dab0SDag-Erling Smørgrav  * only be traversed in the forward direction.  Singly-linked lists are ideal
1444b17dab0SDag-Erling Smørgrav  * for applications with large datasets and few or no removals or for
1454b17dab0SDag-Erling Smørgrav  * implementing a LIFO queue.
1464b17dab0SDag-Erling Smørgrav  *
1474b17dab0SDag-Erling Smørgrav  * A list is headed by a single forward pointer (or an array of forward
1484b17dab0SDag-Erling Smørgrav  * pointers for a hash table header). The elements are doubly linked
1494b17dab0SDag-Erling Smørgrav  * so that an arbitrary element can be removed without a need to
1504b17dab0SDag-Erling Smørgrav  * traverse the list. New elements can be added to the list before
1514b17dab0SDag-Erling Smørgrav  * or after an existing element or at the head of the list. A list
1524b17dab0SDag-Erling Smørgrav  * may only be traversed in the forward direction.
1534b17dab0SDag-Erling Smørgrav  *
1544b17dab0SDag-Erling Smørgrav  * A simple queue is headed by a pair of pointers, one to the head of the
1554b17dab0SDag-Erling Smørgrav  * list and the other to the tail of the list. The elements are singly
1564b17dab0SDag-Erling Smørgrav  * linked to save space, so elements can only be removed from the
1574b17dab0SDag-Erling Smørgrav  * head of the list. New elements can be added to the list before or after
1584b17dab0SDag-Erling Smørgrav  * an existing element, at the head of the list, or at the end of the
1594b17dab0SDag-Erling Smørgrav  * list. A simple queue may only be traversed in the forward direction.
1604b17dab0SDag-Erling Smørgrav  *
1614b17dab0SDag-Erling Smørgrav  * A tail queue is headed by a pair of pointers, one to the head of the
1624b17dab0SDag-Erling Smørgrav  * list and the other to the tail of the list. The elements are doubly
1634b17dab0SDag-Erling Smørgrav  * linked so that an arbitrary element can be removed without a need to
1644b17dab0SDag-Erling Smørgrav  * traverse the list. New elements can be added to the list before or
1654b17dab0SDag-Erling Smørgrav  * after an existing element, at the head of the list, or at the end of
1664b17dab0SDag-Erling Smørgrav  * the list. A tail queue may be traversed in either direction.
1674b17dab0SDag-Erling Smørgrav  *
1684b17dab0SDag-Erling Smørgrav  * An XOR simple queue is used in the same way as a regular simple queue.
1694b17dab0SDag-Erling Smørgrav  * The difference is that the head structure also includes a "cookie" that
1704b17dab0SDag-Erling Smørgrav  * is XOR'd with the queue pointer (first, last or next) to generate the
1714b17dab0SDag-Erling Smørgrav  * real pointer value.
1724b17dab0SDag-Erling Smørgrav  *
1734b17dab0SDag-Erling Smørgrav  * For details on the use of these macros, see the queue(3) manual page.
1744b17dab0SDag-Erling Smørgrav  */
1754b17dab0SDag-Erling Smørgrav 
1764b17dab0SDag-Erling Smørgrav #if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC))
1774b17dab0SDag-Erling Smørgrav #define _Q_INVALID ((void *)-1)
1784b17dab0SDag-Erling Smørgrav #define _Q_INVALIDATE(a) (a) = _Q_INVALID
1794b17dab0SDag-Erling Smørgrav #else
1804b17dab0SDag-Erling Smørgrav #define _Q_INVALIDATE(a)
1814b17dab0SDag-Erling Smørgrav #endif
1824b17dab0SDag-Erling Smørgrav 
1834b17dab0SDag-Erling Smørgrav /*
1844b17dab0SDag-Erling Smørgrav  * Singly-linked List definitions.
1854b17dab0SDag-Erling Smørgrav  */
1864b17dab0SDag-Erling Smørgrav #define SLIST_HEAD(name, type)						\
1874b17dab0SDag-Erling Smørgrav struct name {								\
1884b17dab0SDag-Erling Smørgrav 	struct type *slh_first;	/* first element */			\
1894b17dab0SDag-Erling Smørgrav }
1904b17dab0SDag-Erling Smørgrav 
1914b17dab0SDag-Erling Smørgrav #define	SLIST_HEAD_INITIALIZER(head)					\
1924b17dab0SDag-Erling Smørgrav 	{ NULL }
1934b17dab0SDag-Erling Smørgrav 
1944b17dab0SDag-Erling Smørgrav #define SLIST_ENTRY(type)						\
1954b17dab0SDag-Erling Smørgrav struct {								\
1964b17dab0SDag-Erling Smørgrav 	struct type *sle_next;	/* next element */			\
1974b17dab0SDag-Erling Smørgrav }
1984b17dab0SDag-Erling Smørgrav 
199d74d50a8SDag-Erling Smørgrav /*
200d74d50a8SDag-Erling Smørgrav  * Singly-linked List access methods.
201d74d50a8SDag-Erling Smørgrav  */
202d74d50a8SDag-Erling Smørgrav #define	SLIST_FIRST(head)	((head)->slh_first)
203d74d50a8SDag-Erling Smørgrav #define	SLIST_END(head)		NULL
2044b17dab0SDag-Erling Smørgrav #define	SLIST_EMPTY(head)	(SLIST_FIRST(head) == SLIST_END(head))
2054b17dab0SDag-Erling Smørgrav #define	SLIST_NEXT(elm, field)	((elm)->field.sle_next)
2064b17dab0SDag-Erling Smørgrav 
2074b17dab0SDag-Erling Smørgrav #define	SLIST_FOREACH(var, head, field)					\
2084b17dab0SDag-Erling Smørgrav 	for((var) = SLIST_FIRST(head);					\
2094b17dab0SDag-Erling Smørgrav 	    (var) != SLIST_END(head);					\
2104b17dab0SDag-Erling Smørgrav 	    (var) = SLIST_NEXT(var, field))
2114b17dab0SDag-Erling Smørgrav 
2124b17dab0SDag-Erling Smørgrav #define	SLIST_FOREACH_SAFE(var, head, field, tvar)			\
2134b17dab0SDag-Erling Smørgrav 	for ((var) = SLIST_FIRST(head);				\
2144b17dab0SDag-Erling Smørgrav 	    (var) && ((tvar) = SLIST_NEXT(var, field), 1);		\
2154b17dab0SDag-Erling Smørgrav 	    (var) = (tvar))
2164b17dab0SDag-Erling Smørgrav 
2174b17dab0SDag-Erling Smørgrav /*
2184b17dab0SDag-Erling Smørgrav  * Singly-linked List functions.
2194b17dab0SDag-Erling Smørgrav  */
2204b17dab0SDag-Erling Smørgrav #define	SLIST_INIT(head) {						\
221d74d50a8SDag-Erling Smørgrav 	SLIST_FIRST(head) = SLIST_END(head);				\
222d74d50a8SDag-Erling Smørgrav }
223d74d50a8SDag-Erling Smørgrav 
224d74d50a8SDag-Erling Smørgrav #define	SLIST_INSERT_AFTER(slistelm, elm, field) do {			\
2254b17dab0SDag-Erling Smørgrav 	(elm)->field.sle_next = (slistelm)->field.sle_next;		\
2264b17dab0SDag-Erling Smørgrav 	(slistelm)->field.sle_next = (elm);				\
2274b17dab0SDag-Erling Smørgrav } while (0)
2284b17dab0SDag-Erling Smørgrav 
2294b17dab0SDag-Erling Smørgrav #define	SLIST_INSERT_HEAD(head, elm, field) do {			\
2304b17dab0SDag-Erling Smørgrav 	(elm)->field.sle_next = (head)->slh_first;			\
2314b17dab0SDag-Erling Smørgrav 	(head)->slh_first = (elm);					\
2324b17dab0SDag-Erling Smørgrav } while (0)
2334b17dab0SDag-Erling Smørgrav 
2344b17dab0SDag-Erling Smørgrav #define	SLIST_REMOVE_AFTER(elm, field) do {				\
2354b17dab0SDag-Erling Smørgrav 	(elm)->field.sle_next = (elm)->field.sle_next->field.sle_next;	\
2364b17dab0SDag-Erling Smørgrav } while (0)
2374b17dab0SDag-Erling Smørgrav 
2384b17dab0SDag-Erling Smørgrav #define	SLIST_REMOVE_HEAD(head, field) do {				\
2394b17dab0SDag-Erling Smørgrav 	(head)->slh_first = (head)->slh_first->field.sle_next;		\
2404b17dab0SDag-Erling Smørgrav } while (0)
2414b17dab0SDag-Erling Smørgrav 
2424b17dab0SDag-Erling Smørgrav #define SLIST_REMOVE(head, elm, type, field) do {			\
2434b17dab0SDag-Erling Smørgrav 	if ((head)->slh_first == (elm)) {				\
2444b17dab0SDag-Erling Smørgrav 		SLIST_REMOVE_HEAD((head), field);			\
2454b17dab0SDag-Erling Smørgrav 	} else {							\
2464b17dab0SDag-Erling Smørgrav 		struct type *curelm = (head)->slh_first;		\
2474b17dab0SDag-Erling Smørgrav 									\
2484b17dab0SDag-Erling Smørgrav 		while (curelm->field.sle_next != (elm))			\
2494b17dab0SDag-Erling Smørgrav 			curelm = curelm->field.sle_next;		\
2504b17dab0SDag-Erling Smørgrav 		curelm->field.sle_next =				\
2514b17dab0SDag-Erling Smørgrav 		    curelm->field.sle_next->field.sle_next;		\
2524b17dab0SDag-Erling Smørgrav 	}								\
2534b17dab0SDag-Erling Smørgrav 	_Q_INVALIDATE((elm)->field.sle_next);				\
2544b17dab0SDag-Erling Smørgrav } while (0)
2554b17dab0SDag-Erling Smørgrav 
2564b17dab0SDag-Erling Smørgrav /*
2574b17dab0SDag-Erling Smørgrav  * List definitions.
2584b17dab0SDag-Erling Smørgrav  */
2594b17dab0SDag-Erling Smørgrav #define LIST_HEAD(name, type)						\
2604b17dab0SDag-Erling Smørgrav struct name {								\
2614b17dab0SDag-Erling Smørgrav 	struct type *lh_first;	/* first element */			\
2624b17dab0SDag-Erling Smørgrav }
2634b17dab0SDag-Erling Smørgrav 
2644b17dab0SDag-Erling Smørgrav #define LIST_HEAD_INITIALIZER(head)					\
2654b17dab0SDag-Erling Smørgrav 	{ NULL }
2664b17dab0SDag-Erling Smørgrav 
2674b17dab0SDag-Erling Smørgrav #define LIST_ENTRY(type)						\
2684b17dab0SDag-Erling Smørgrav struct {								\
2694b17dab0SDag-Erling Smørgrav 	struct type *le_next;	/* next element */			\
2704b17dab0SDag-Erling Smørgrav 	struct type **le_prev;	/* address of previous next element */	\
2714b17dab0SDag-Erling Smørgrav }
2724b17dab0SDag-Erling Smørgrav 
2734b17dab0SDag-Erling Smørgrav /*
2744b17dab0SDag-Erling Smørgrav  * List access methods.
2754b17dab0SDag-Erling Smørgrav  */
2764b17dab0SDag-Erling Smørgrav #define	LIST_FIRST(head)		((head)->lh_first)
2774b17dab0SDag-Erling Smørgrav #define	LIST_END(head)			NULL
2784b17dab0SDag-Erling Smørgrav #define	LIST_EMPTY(head)		(LIST_FIRST(head) == LIST_END(head))
2794b17dab0SDag-Erling Smørgrav #define	LIST_NEXT(elm, field)		((elm)->field.le_next)
2804b17dab0SDag-Erling Smørgrav 
2814b17dab0SDag-Erling Smørgrav #define LIST_FOREACH(var, head, field)					\
2824b17dab0SDag-Erling Smørgrav 	for((var) = LIST_FIRST(head);					\
2834b17dab0SDag-Erling Smørgrav 	    (var)!= LIST_END(head);					\
2844b17dab0SDag-Erling Smørgrav 	    (var) = LIST_NEXT(var, field))
2854b17dab0SDag-Erling Smørgrav 
2864b17dab0SDag-Erling Smørgrav #define	LIST_FOREACH_SAFE(var, head, field, tvar)			\
2874b17dab0SDag-Erling Smørgrav 	for ((var) = LIST_FIRST(head);				\
2884b17dab0SDag-Erling Smørgrav 	    (var) && ((tvar) = LIST_NEXT(var, field), 1);		\
2894b17dab0SDag-Erling Smørgrav 	    (var) = (tvar))
2904b17dab0SDag-Erling Smørgrav 
2914b17dab0SDag-Erling Smørgrav /*
2924b17dab0SDag-Erling Smørgrav  * List functions.
2934b17dab0SDag-Erling Smørgrav  */
2944b17dab0SDag-Erling Smørgrav #define	LIST_INIT(head) do {						\
2954b17dab0SDag-Erling Smørgrav 	LIST_FIRST(head) = LIST_END(head);				\
2964b17dab0SDag-Erling Smørgrav } while (0)
2974b17dab0SDag-Erling Smørgrav 
2984b17dab0SDag-Erling Smørgrav #define LIST_INSERT_AFTER(listelm, elm, field) do {			\
2994b17dab0SDag-Erling Smørgrav 	if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)	\
3004b17dab0SDag-Erling Smørgrav 		(listelm)->field.le_next->field.le_prev =		\
3014b17dab0SDag-Erling Smørgrav 		    &(elm)->field.le_next;				\
3024b17dab0SDag-Erling Smørgrav 	(listelm)->field.le_next = (elm);				\
3034b17dab0SDag-Erling Smørgrav 	(elm)->field.le_prev = &(listelm)->field.le_next;		\
3044b17dab0SDag-Erling Smørgrav } while (0)
3054b17dab0SDag-Erling Smørgrav 
3064b17dab0SDag-Erling Smørgrav #define	LIST_INSERT_BEFORE(listelm, elm, field) do {			\
3074b17dab0SDag-Erling Smørgrav 	(elm)->field.le_prev = (listelm)->field.le_prev;		\
3084b17dab0SDag-Erling Smørgrav 	(elm)->field.le_next = (listelm);				\
3094b17dab0SDag-Erling Smørgrav 	*(listelm)->field.le_prev = (elm);				\
3104b17dab0SDag-Erling Smørgrav 	(listelm)->field.le_prev = &(elm)->field.le_next;		\
3114b17dab0SDag-Erling Smørgrav } while (0)
3124b17dab0SDag-Erling Smørgrav 
3134b17dab0SDag-Erling Smørgrav #define LIST_INSERT_HEAD(head, elm, field) do {				\
3144b17dab0SDag-Erling Smørgrav 	if (((elm)->field.le_next = (head)->lh_first) != NULL)		\
3154b17dab0SDag-Erling Smørgrav 		(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
3164b17dab0SDag-Erling Smørgrav 	(head)->lh_first = (elm);					\
3174b17dab0SDag-Erling Smørgrav 	(elm)->field.le_prev = &(head)->lh_first;			\
3184b17dab0SDag-Erling Smørgrav } while (0)
3194b17dab0SDag-Erling Smørgrav 
3204b17dab0SDag-Erling Smørgrav #define LIST_REMOVE(elm, field) do {					\
3214b17dab0SDag-Erling Smørgrav 	if ((elm)->field.le_next != NULL)				\
3224b17dab0SDag-Erling Smørgrav 		(elm)->field.le_next->field.le_prev =			\
3234b17dab0SDag-Erling Smørgrav 		    (elm)->field.le_prev;				\
3244b17dab0SDag-Erling Smørgrav 	*(elm)->field.le_prev = (elm)->field.le_next;			\
3254b17dab0SDag-Erling Smørgrav 	_Q_INVALIDATE((elm)->field.le_prev);				\
3264b17dab0SDag-Erling Smørgrav 	_Q_INVALIDATE((elm)->field.le_next);				\
3274b17dab0SDag-Erling Smørgrav } while (0)
3284b17dab0SDag-Erling Smørgrav 
3294b17dab0SDag-Erling Smørgrav #define LIST_REPLACE(elm, elm2, field) do {				\
3304b17dab0SDag-Erling Smørgrav 	if (((elm2)->field.le_next = (elm)->field.le_next) != NULL)	\
3314b17dab0SDag-Erling Smørgrav 		(elm2)->field.le_next->field.le_prev =			\
3324b17dab0SDag-Erling Smørgrav 		    &(elm2)->field.le_next;				\
3334b17dab0SDag-Erling Smørgrav 	(elm2)->field.le_prev = (elm)->field.le_prev;			\
3344b17dab0SDag-Erling Smørgrav 	*(elm2)->field.le_prev = (elm2);				\
3354b17dab0SDag-Erling Smørgrav 	_Q_INVALIDATE((elm)->field.le_prev);				\
3364b17dab0SDag-Erling Smørgrav 	_Q_INVALIDATE((elm)->field.le_next);				\
3374b17dab0SDag-Erling Smørgrav } while (0)
3384b17dab0SDag-Erling Smørgrav 
3394b17dab0SDag-Erling Smørgrav /*
3404b17dab0SDag-Erling Smørgrav  * Simple queue definitions.
3414b17dab0SDag-Erling Smørgrav  */
3424b17dab0SDag-Erling Smørgrav #define SIMPLEQ_HEAD(name, type)					\
3434b17dab0SDag-Erling Smørgrav struct name {								\
3444b17dab0SDag-Erling Smørgrav 	struct type *sqh_first;	/* first element */			\
3454b17dab0SDag-Erling Smørgrav 	struct type **sqh_last;	/* addr of last next element */		\
3464b17dab0SDag-Erling Smørgrav }
3474b17dab0SDag-Erling Smørgrav 
3484b17dab0SDag-Erling Smørgrav #define SIMPLEQ_HEAD_INITIALIZER(head)					\
3494b17dab0SDag-Erling Smørgrav 	{ NULL, &(head).sqh_first }
3504b17dab0SDag-Erling Smørgrav 
3514b17dab0SDag-Erling Smørgrav #define SIMPLEQ_ENTRY(type)						\
3524b17dab0SDag-Erling Smørgrav struct {								\
3534b17dab0SDag-Erling Smørgrav 	struct type *sqe_next;	/* next element */			\
3544b17dab0SDag-Erling Smørgrav }
3554b17dab0SDag-Erling Smørgrav 
3564b17dab0SDag-Erling Smørgrav /*
3574b17dab0SDag-Erling Smørgrav  * Simple queue access methods.
3584b17dab0SDag-Erling Smørgrav  */
3594b17dab0SDag-Erling Smørgrav #define	SIMPLEQ_FIRST(head)	    ((head)->sqh_first)
3604b17dab0SDag-Erling Smørgrav #define	SIMPLEQ_END(head)	    NULL
3614b17dab0SDag-Erling Smørgrav #define	SIMPLEQ_EMPTY(head)	    (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
3624b17dab0SDag-Erling Smørgrav #define	SIMPLEQ_NEXT(elm, field)    ((elm)->field.sqe_next)
3634b17dab0SDag-Erling Smørgrav 
3644b17dab0SDag-Erling Smørgrav #define SIMPLEQ_FOREACH(var, head, field)				\
3654b17dab0SDag-Erling Smørgrav 	for((var) = SIMPLEQ_FIRST(head);				\
3664b17dab0SDag-Erling Smørgrav 	    (var) != SIMPLEQ_END(head);					\
3674b17dab0SDag-Erling Smørgrav 	    (var) = SIMPLEQ_NEXT(var, field))
3684b17dab0SDag-Erling Smørgrav 
3694b17dab0SDag-Erling Smørgrav #define	SIMPLEQ_FOREACH_SAFE(var, head, field, tvar)			\
3704b17dab0SDag-Erling Smørgrav 	for ((var) = SIMPLEQ_FIRST(head);				\
3714b17dab0SDag-Erling Smørgrav 	    (var) && ((tvar) = SIMPLEQ_NEXT(var, field), 1);		\
3724b17dab0SDag-Erling Smørgrav 	    (var) = (tvar))
3734b17dab0SDag-Erling Smørgrav 
3744b17dab0SDag-Erling Smørgrav /*
3754b17dab0SDag-Erling Smørgrav  * Simple queue functions.
3764b17dab0SDag-Erling Smørgrav  */
3774b17dab0SDag-Erling Smørgrav #define	SIMPLEQ_INIT(head) do {						\
3784b17dab0SDag-Erling Smørgrav 	(head)->sqh_first = NULL;					\
3794b17dab0SDag-Erling Smørgrav 	(head)->sqh_last = &(head)->sqh_first;				\
3804b17dab0SDag-Erling Smørgrav } while (0)
3814b17dab0SDag-Erling Smørgrav 
3824b17dab0SDag-Erling Smørgrav #define SIMPLEQ_INSERT_HEAD(head, elm, field) do {			\
3834b17dab0SDag-Erling Smørgrav 	if (((elm)->field.sqe_next = (head)->sqh_first) == NULL)	\
3844b17dab0SDag-Erling Smørgrav 		(head)->sqh_last = &(elm)->field.sqe_next;		\
3854b17dab0SDag-Erling Smørgrav 	(head)->sqh_first = (elm);					\
3864b17dab0SDag-Erling Smørgrav } while (0)
3874b17dab0SDag-Erling Smørgrav 
3884b17dab0SDag-Erling Smørgrav #define SIMPLEQ_INSERT_TAIL(head, elm, field) do {			\
3894b17dab0SDag-Erling Smørgrav 	(elm)->field.sqe_next = NULL;					\
3904b17dab0SDag-Erling Smørgrav 	*(head)->sqh_last = (elm);					\
3914b17dab0SDag-Erling Smørgrav 	(head)->sqh_last = &(elm)->field.sqe_next;			\
3924b17dab0SDag-Erling Smørgrav } while (0)
3934b17dab0SDag-Erling Smørgrav 
3944b17dab0SDag-Erling Smørgrav #define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
3954b17dab0SDag-Erling Smørgrav 	if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
3964b17dab0SDag-Erling Smørgrav 		(head)->sqh_last = &(elm)->field.sqe_next;		\
3974b17dab0SDag-Erling Smørgrav 	(listelm)->field.sqe_next = (elm);				\
3984b17dab0SDag-Erling Smørgrav } while (0)
3994b17dab0SDag-Erling Smørgrav 
4004b17dab0SDag-Erling Smørgrav #define SIMPLEQ_REMOVE_HEAD(head, field) do {			\
4014b17dab0SDag-Erling Smørgrav 	if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
4024b17dab0SDag-Erling Smørgrav 		(head)->sqh_last = &(head)->sqh_first;			\
4034b17dab0SDag-Erling Smørgrav } while (0)
4044b17dab0SDag-Erling Smørgrav 
4054b17dab0SDag-Erling Smørgrav #define SIMPLEQ_REMOVE_AFTER(head, elm, field) do {			\
4064b17dab0SDag-Erling Smørgrav 	if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \
4074b17dab0SDag-Erling Smørgrav 	    == NULL)							\
4084b17dab0SDag-Erling Smørgrav 		(head)->sqh_last = &(elm)->field.sqe_next;		\
4094b17dab0SDag-Erling Smørgrav } while (0)
4104b17dab0SDag-Erling Smørgrav 
4114b17dab0SDag-Erling Smørgrav #define SIMPLEQ_CONCAT(head1, head2) do {				\
4124b17dab0SDag-Erling Smørgrav 	if (!SIMPLEQ_EMPTY((head2))) {					\
4134b17dab0SDag-Erling Smørgrav 		*(head1)->sqh_last = (head2)->sqh_first;		\
414d74d50a8SDag-Erling Smørgrav 		(head1)->sqh_last = (head2)->sqh_last;			\
4154b17dab0SDag-Erling Smørgrav 		SIMPLEQ_INIT((head2));					\
4164b17dab0SDag-Erling Smørgrav 	}								\
4174b17dab0SDag-Erling Smørgrav } while (0)
4184b17dab0SDag-Erling Smørgrav 
4194b17dab0SDag-Erling Smørgrav /*
4204b17dab0SDag-Erling Smørgrav  * XOR Simple queue definitions.
4214b17dab0SDag-Erling Smørgrav  */
4224b17dab0SDag-Erling Smørgrav #define XSIMPLEQ_HEAD(name, type)					\
4234b17dab0SDag-Erling Smørgrav struct name {								\
4244b17dab0SDag-Erling Smørgrav 	struct type *sqx_first;	/* first element */			\
4254b17dab0SDag-Erling Smørgrav 	struct type **sqx_last;	/* addr of last next element */		\
4264b17dab0SDag-Erling Smørgrav 	unsigned long sqx_cookie;					\
4274b17dab0SDag-Erling Smørgrav }
4284b17dab0SDag-Erling Smørgrav 
4294b17dab0SDag-Erling Smørgrav #define XSIMPLEQ_ENTRY(type)						\
4304b17dab0SDag-Erling Smørgrav struct {								\
4314b17dab0SDag-Erling Smørgrav 	struct type *sqx_next;	/* next element */			\
4324b17dab0SDag-Erling Smørgrav }
4334b17dab0SDag-Erling Smørgrav 
4344b17dab0SDag-Erling Smørgrav /*
4354b17dab0SDag-Erling Smørgrav  * XOR Simple queue access methods.
4364b17dab0SDag-Erling Smørgrav  */
4374b17dab0SDag-Erling Smørgrav #define XSIMPLEQ_XOR(head, ptr)	    ((__typeof(ptr))((head)->sqx_cookie ^ \
4384b17dab0SDag-Erling Smørgrav 					(unsigned long)(ptr)))
4394b17dab0SDag-Erling Smørgrav #define	XSIMPLEQ_FIRST(head)	    XSIMPLEQ_XOR(head, ((head)->sqx_first))
4404b17dab0SDag-Erling Smørgrav #define	XSIMPLEQ_END(head)	    NULL
4414b17dab0SDag-Erling Smørgrav #define	XSIMPLEQ_EMPTY(head)	    (XSIMPLEQ_FIRST(head) == XSIMPLEQ_END(head))
4424b17dab0SDag-Erling Smørgrav #define	XSIMPLEQ_NEXT(head, elm, field)    XSIMPLEQ_XOR(head, ((elm)->field.sqx_next))
4434b17dab0SDag-Erling Smørgrav 
4444b17dab0SDag-Erling Smørgrav 
4454b17dab0SDag-Erling Smørgrav #define XSIMPLEQ_FOREACH(var, head, field)				\
4464b17dab0SDag-Erling Smørgrav 	for ((var) = XSIMPLEQ_FIRST(head);				\
4474b17dab0SDag-Erling Smørgrav 	    (var) != XSIMPLEQ_END(head);				\
4484b17dab0SDag-Erling Smørgrav 	    (var) = XSIMPLEQ_NEXT(head, var, field))
4494b17dab0SDag-Erling Smørgrav 
4504b17dab0SDag-Erling Smørgrav #define	XSIMPLEQ_FOREACH_SAFE(var, head, field, tvar)			\
4514b17dab0SDag-Erling Smørgrav 	for ((var) = XSIMPLEQ_FIRST(head);				\
4524b17dab0SDag-Erling Smørgrav 	    (var) && ((tvar) = XSIMPLEQ_NEXT(head, var, field), 1);	\
4534b17dab0SDag-Erling Smørgrav 	    (var) = (tvar))
4544b17dab0SDag-Erling Smørgrav 
4554b17dab0SDag-Erling Smørgrav /*
4564b17dab0SDag-Erling Smørgrav  * XOR Simple queue functions.
4574b17dab0SDag-Erling Smørgrav  */
4584b17dab0SDag-Erling Smørgrav #define	XSIMPLEQ_INIT(head) do {					\
4594b17dab0SDag-Erling Smørgrav 	arc4random_buf(&(head)->sqx_cookie, sizeof((head)->sqx_cookie)); \
4604b17dab0SDag-Erling Smørgrav 	(head)->sqx_first = XSIMPLEQ_XOR(head, NULL);			\
4614b17dab0SDag-Erling Smørgrav 	(head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first);	\
4624b17dab0SDag-Erling Smørgrav } while (0)
4634b17dab0SDag-Erling Smørgrav 
4644b17dab0SDag-Erling Smørgrav #define XSIMPLEQ_INSERT_HEAD(head, elm, field) do {			\
4654b17dab0SDag-Erling Smørgrav 	if (((elm)->field.sqx_next = (head)->sqx_first) ==		\
4664b17dab0SDag-Erling Smørgrav 	    XSIMPLEQ_XOR(head, NULL))					\
4674b17dab0SDag-Erling Smørgrav 		(head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
4684b17dab0SDag-Erling Smørgrav 	(head)->sqx_first = XSIMPLEQ_XOR(head, (elm));			\
4694b17dab0SDag-Erling Smørgrav } while (0)
4704b17dab0SDag-Erling Smørgrav 
4714b17dab0SDag-Erling Smørgrav #define XSIMPLEQ_INSERT_TAIL(head, elm, field) do {			\
4724b17dab0SDag-Erling Smørgrav 	(elm)->field.sqx_next = XSIMPLEQ_XOR(head, NULL);		\
4734b17dab0SDag-Erling Smørgrav 	*(XSIMPLEQ_XOR(head, (head)->sqx_last)) = XSIMPLEQ_XOR(head, (elm)); \
4744b17dab0SDag-Erling Smørgrav 	(head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next);	\
4754b17dab0SDag-Erling Smørgrav } while (0)
4764b17dab0SDag-Erling Smørgrav 
4774b17dab0SDag-Erling Smørgrav #define XSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
4784b17dab0SDag-Erling Smørgrav 	if (((elm)->field.sqx_next = (listelm)->field.sqx_next) ==	\
4794b17dab0SDag-Erling Smørgrav 	    XSIMPLEQ_XOR(head, NULL))					\
4804b17dab0SDag-Erling Smørgrav 		(head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
4814b17dab0SDag-Erling Smørgrav 	(listelm)->field.sqx_next = XSIMPLEQ_XOR(head, (elm));		\
4824b17dab0SDag-Erling Smørgrav } while (0)
4834b17dab0SDag-Erling Smørgrav 
4844b17dab0SDag-Erling Smørgrav #define XSIMPLEQ_REMOVE_HEAD(head, field) do {				\
4854b17dab0SDag-Erling Smørgrav 	if (((head)->sqx_first = XSIMPLEQ_XOR(head,			\
4864b17dab0SDag-Erling Smørgrav 	    (head)->sqx_first)->field.sqx_next) == XSIMPLEQ_XOR(head, NULL)) \
4874b17dab0SDag-Erling Smørgrav 		(head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \
4884b17dab0SDag-Erling Smørgrav } while (0)
4894b17dab0SDag-Erling Smørgrav 
4904b17dab0SDag-Erling Smørgrav #define XSIMPLEQ_REMOVE_AFTER(head, elm, field) do {			\
4914b17dab0SDag-Erling Smørgrav 	if (((elm)->field.sqx_next = XSIMPLEQ_XOR(head,			\
4924b17dab0SDag-Erling Smørgrav 	    (elm)->field.sqx_next)->field.sqx_next)			\
4934b17dab0SDag-Erling Smørgrav 	    == XSIMPLEQ_XOR(head, NULL))				\
4944b17dab0SDag-Erling Smørgrav 		(head)->sqx_last = 					\
4954b17dab0SDag-Erling Smørgrav 		    XSIMPLEQ_XOR(head, &(elm)->field.sqx_next);		\
4964b17dab0SDag-Erling Smørgrav } while (0)
4974b17dab0SDag-Erling Smørgrav 
4984b17dab0SDag-Erling Smørgrav 
4994b17dab0SDag-Erling Smørgrav /*
5004b17dab0SDag-Erling Smørgrav  * Tail queue definitions.
5014b17dab0SDag-Erling Smørgrav  */
5024b17dab0SDag-Erling Smørgrav #define TAILQ_HEAD(name, type)						\
5034b17dab0SDag-Erling Smørgrav struct name {								\
5044b17dab0SDag-Erling Smørgrav 	struct type *tqh_first;	/* first element */			\
5054b17dab0SDag-Erling Smørgrav 	struct type **tqh_last;	/* addr of last next element */		\
5064b17dab0SDag-Erling Smørgrav }
5074b17dab0SDag-Erling Smørgrav 
5084b17dab0SDag-Erling Smørgrav #define TAILQ_HEAD_INITIALIZER(head)					\
5094b17dab0SDag-Erling Smørgrav 	{ NULL, &(head).tqh_first }
5104b17dab0SDag-Erling Smørgrav 
5114b17dab0SDag-Erling Smørgrav #define TAILQ_ENTRY(type)						\
5124b17dab0SDag-Erling Smørgrav struct {								\
5134b17dab0SDag-Erling Smørgrav 	struct type *tqe_next;	/* next element */			\
5144b17dab0SDag-Erling Smørgrav 	struct type **tqe_prev;	/* address of previous next element */	\
5154b17dab0SDag-Erling Smørgrav }
5164b17dab0SDag-Erling Smørgrav 
5174b17dab0SDag-Erling Smørgrav /*
5184b17dab0SDag-Erling Smørgrav  * Tail queue access methods.
5194b17dab0SDag-Erling Smørgrav  */
5204b17dab0SDag-Erling Smørgrav #define	TAILQ_FIRST(head)		((head)->tqh_first)
5214b17dab0SDag-Erling Smørgrav #define	TAILQ_END(head)			NULL
5224b17dab0SDag-Erling Smørgrav #define	TAILQ_NEXT(elm, field)		((elm)->field.tqe_next)
5234b17dab0SDag-Erling Smørgrav #define TAILQ_LAST(head, headname)					\
5244b17dab0SDag-Erling Smørgrav 	(*(((struct headname *)((head)->tqh_last))->tqh_last))
5254b17dab0SDag-Erling Smørgrav /* XXX */
5264b17dab0SDag-Erling Smørgrav #define TAILQ_PREV(elm, headname, field)				\
5274b17dab0SDag-Erling Smørgrav 	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
5284b17dab0SDag-Erling Smørgrav #define	TAILQ_EMPTY(head)						\
5294b17dab0SDag-Erling Smørgrav 	(TAILQ_FIRST(head) == TAILQ_END(head))
5304b17dab0SDag-Erling Smørgrav 
5314b17dab0SDag-Erling Smørgrav #define TAILQ_FOREACH(var, head, field)					\
5324b17dab0SDag-Erling Smørgrav 	for((var) = TAILQ_FIRST(head);					\
5334b17dab0SDag-Erling Smørgrav 	    (var) != TAILQ_END(head);					\
5344b17dab0SDag-Erling Smørgrav 	    (var) = TAILQ_NEXT(var, field))
5354b17dab0SDag-Erling Smørgrav 
5364b17dab0SDag-Erling Smørgrav #define	TAILQ_FOREACH_SAFE(var, head, field, tvar)			\
5374b17dab0SDag-Erling Smørgrav 	for ((var) = TAILQ_FIRST(head);					\
5384b17dab0SDag-Erling Smørgrav 	    (var) != TAILQ_END(head) &&					\
5394b17dab0SDag-Erling Smørgrav 	    ((tvar) = TAILQ_NEXT(var, field), 1);			\
5404b17dab0SDag-Erling Smørgrav 	    (var) = (tvar))
5414b17dab0SDag-Erling Smørgrav 
5424b17dab0SDag-Erling Smørgrav 
5434b17dab0SDag-Erling Smørgrav #define TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
5444b17dab0SDag-Erling Smørgrav 	for((var) = TAILQ_LAST(head, headname);				\
5454b17dab0SDag-Erling Smørgrav 	    (var) != TAILQ_END(head);					\
5464b17dab0SDag-Erling Smørgrav 	    (var) = TAILQ_PREV(var, headname, field))
5474b17dab0SDag-Erling Smørgrav 
5484b17dab0SDag-Erling Smørgrav #define	TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar)	\
5494b17dab0SDag-Erling Smørgrav 	for ((var) = TAILQ_LAST(head, headname);			\
5504b17dab0SDag-Erling Smørgrav 	    (var) != TAILQ_END(head) &&					\
5514b17dab0SDag-Erling Smørgrav 	    ((tvar) = TAILQ_PREV(var, headname, field), 1);		\
5524b17dab0SDag-Erling Smørgrav 	    (var) = (tvar))
5534b17dab0SDag-Erling Smørgrav 
5544b17dab0SDag-Erling Smørgrav /*
5554b17dab0SDag-Erling Smørgrav  * Tail queue functions.
5564b17dab0SDag-Erling Smørgrav  */
5574b17dab0SDag-Erling Smørgrav #define	TAILQ_INIT(head) do {						\
5584b17dab0SDag-Erling Smørgrav 	(head)->tqh_first = NULL;					\
5594b17dab0SDag-Erling Smørgrav 	(head)->tqh_last = &(head)->tqh_first;				\
5604b17dab0SDag-Erling Smørgrav } while (0)
5614b17dab0SDag-Erling Smørgrav 
5624b17dab0SDag-Erling Smørgrav #define TAILQ_INSERT_HEAD(head, elm, field) do {			\
5634b17dab0SDag-Erling Smørgrav 	if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)	\
5644b17dab0SDag-Erling Smørgrav 		(head)->tqh_first->field.tqe_prev =			\
5654b17dab0SDag-Erling Smørgrav 		    &(elm)->field.tqe_next;				\
5664b17dab0SDag-Erling Smørgrav 	else								\
5674b17dab0SDag-Erling Smørgrav 		(head)->tqh_last = &(elm)->field.tqe_next;		\
5684b17dab0SDag-Erling Smørgrav 	(head)->tqh_first = (elm);					\
5694b17dab0SDag-Erling Smørgrav 	(elm)->field.tqe_prev = &(head)->tqh_first;			\
5704b17dab0SDag-Erling Smørgrav } while (0)
5714b17dab0SDag-Erling Smørgrav 
5724b17dab0SDag-Erling Smørgrav #define TAILQ_INSERT_TAIL(head, elm, field) do {			\
5734b17dab0SDag-Erling Smørgrav 	(elm)->field.tqe_next = NULL;					\
5744b17dab0SDag-Erling Smørgrav 	(elm)->field.tqe_prev = (head)->tqh_last;			\
5754b17dab0SDag-Erling Smørgrav 	*(head)->tqh_last = (elm);					\
5764b17dab0SDag-Erling Smørgrav 	(head)->tqh_last = &(elm)->field.tqe_next;			\
5774b17dab0SDag-Erling Smørgrav } while (0)
5784b17dab0SDag-Erling Smørgrav 
5794b17dab0SDag-Erling Smørgrav #define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
5804b17dab0SDag-Erling Smørgrav 	if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
5814b17dab0SDag-Erling Smørgrav 		(elm)->field.tqe_next->field.tqe_prev =			\
5824b17dab0SDag-Erling Smørgrav 		    &(elm)->field.tqe_next;				\
5834b17dab0SDag-Erling Smørgrav 	else								\
5844b17dab0SDag-Erling Smørgrav 		(head)->tqh_last = &(elm)->field.tqe_next;		\
5854b17dab0SDag-Erling Smørgrav 	(listelm)->field.tqe_next = (elm);				\
5864b17dab0SDag-Erling Smørgrav 	(elm)->field.tqe_prev = &(listelm)->field.tqe_next;		\
5874b17dab0SDag-Erling Smørgrav } while (0)
5884b17dab0SDag-Erling Smørgrav 
5894b17dab0SDag-Erling Smørgrav #define	TAILQ_INSERT_BEFORE(listelm, elm, field) do {			\
5904b17dab0SDag-Erling Smørgrav 	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
5914b17dab0SDag-Erling Smørgrav 	(elm)->field.tqe_next = (listelm);				\
5924b17dab0SDag-Erling Smørgrav 	*(listelm)->field.tqe_prev = (elm);				\
5934b17dab0SDag-Erling Smørgrav 	(listelm)->field.tqe_prev = &(elm)->field.tqe_next;		\
594 } while (0)
595 
596 #define TAILQ_REMOVE(head, elm, field) do {				\
597 	if (((elm)->field.tqe_next) != NULL)				\
598 		(elm)->field.tqe_next->field.tqe_prev =			\
599 		    (elm)->field.tqe_prev;				\
600 	else								\
601 		(head)->tqh_last = (elm)->field.tqe_prev;		\
602 	*(elm)->field.tqe_prev = (elm)->field.tqe_next;			\
603 	_Q_INVALIDATE((elm)->field.tqe_prev);				\
604 	_Q_INVALIDATE((elm)->field.tqe_next);				\
605 } while (0)
606 
607 #define TAILQ_REPLACE(head, elm, elm2, field) do {			\
608 	if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL)	\
609 		(elm2)->field.tqe_next->field.tqe_prev =		\
610 		    &(elm2)->field.tqe_next;				\
611 	else								\
612 		(head)->tqh_last = &(elm2)->field.tqe_next;		\
613 	(elm2)->field.tqe_prev = (elm)->field.tqe_prev;			\
614 	*(elm2)->field.tqe_prev = (elm2);				\
615 	_Q_INVALIDATE((elm)->field.tqe_prev);				\
616 	_Q_INVALIDATE((elm)->field.tqe_next);				\
617 } while (0)
618 
619 #define TAILQ_CONCAT(head1, head2, field) do {				\
620 	if (!TAILQ_EMPTY(head2)) {					\
621 		*(head1)->tqh_last = (head2)->tqh_first;		\
622 		(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last;	\
623 		(head1)->tqh_last = (head2)->tqh_last;			\
624 		TAILQ_INIT((head2));					\
625 	}								\
626 } while (0)
627 
628 #endif	/* !_SYS_QUEUE_H_ */
629