1c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*	$OpenBSD: queue.h,v 1.16 2000/09/07 19:47:59 art Exp $	*/
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*	$NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $	*/
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Copyright (c) 1991, 1993
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *	The Regents of the University of California.  All rights reserved.
7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *
8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Redistribution and use in source and binary forms, with or without
9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * modification, are permitted provided that the following conditions
10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * are met:
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * 1. Redistributions of source code must retain the above copyright
12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *    notice, this list of conditions and the following disclaimer.
13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * 2. Redistributions in binary form must reproduce the above copyright
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *    notice, this list of conditions and the following disclaimer in the
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *    documentation and/or other materials provided with the distribution.
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * 3. Neither the name of the University nor the names of its contributors
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *    may be used to endorse or promote products derived from this software
18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *    without specific prior written permission.
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * SUCH DAMAGE.
31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *
32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *	@(#)queue.h	8.5 (Berkeley) 8/20/94
33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef	_SYS_QUEUE_H_
36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	_SYS_QUEUE_H_
37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*
39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * This file defines five types of data structures: singly-linked lists,
40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * lists, simple queues, tail queues, and circular queues.
41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *
42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *
43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * A singly-linked list is headed by a single forward pointer. The elements
44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * are singly linked for minimum space and pointer manipulation overhead at
45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * the expense of O(n) removal for arbitrary elements. New elements can be
46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * added to the list after an existing element or at the head of the list.
47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Elements being removed from the head of the list should use the explicit
48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * macro for this purpose for optimum efficiency. A singly-linked list may
49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * only be traversed in the forward direction.  Singly-linked lists are ideal
50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * for applications with large datasets and few or no removals or for
51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * implementing a LIFO queue.
52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *
53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * A list is headed by a single forward pointer (or an array of forward
54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * pointers for a hash table header). The elements are doubly linked
55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * so that an arbitrary element can be removed without a need to
56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * traverse the list. New elements can be added to the list before
57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * or after an existing element or at the head of the list. A list
58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * may only be traversed in the forward direction.
59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *
60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * A simple queue is headed by a pair of pointers, one the head of the
61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * list and the other to the tail of the list. The elements are singly
62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * linked to save space, so elements can only be removed from the
63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * head of the list. New elements can be added to the list before or after
64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * an existing element, at the head of the list, or at the end of the
65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * list. A simple queue may only be traversed in the forward direction.
66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *
67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * A tail queue is headed by a pair of pointers, one to the head of the
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * list and the other to the tail of the list. The elements are doubly
69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * linked so that an arbitrary element can be removed without a need to
70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * traverse the list. New elements can be added to the list before or
71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * after an existing element, at the head of the list, or at the end of
72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * the list. A tail queue may be traversed in either direction.
73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *
74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * A circle queue is headed by a pair of pointers, one to the head of the
75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * list and the other to the tail of the list. The elements are doubly
76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * linked so that an arbitrary element can be removed without a need to
77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * traverse the list. New elements can be added to the list before or after
78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * an existing element, at the head of the list, or at the end of the list.
79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * A circle queue may be traversed in either direction, but has a more
80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * complex end of list detection.
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *
82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * For details on the use of these macros, see the queue(3) manual page.
83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */
84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Singly-linked List definitions.
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */
88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define SLIST_HEAD(name, type)						\
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct name {								\
90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct type *slh_first;	/* first element */			\
91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	SLIST_HEAD_INITIALIZER(head)					\
94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	{ NULL }
95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef WIN32
97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define SLIST_ENTRY(type)						\
98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct {								\
99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct type *sle_next;	/* next element */			\
100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*
104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Singly-linked List access methods.
105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */
106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	SLIST_FIRST(head)	((head)->slh_first)
107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	SLIST_END(head)		NULL
108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	SLIST_EMPTY(head)	(SLIST_FIRST(head) == SLIST_END(head))
109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	SLIST_NEXT(elm, field)	((elm)->field.sle_next)
110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	SLIST_FOREACH(var, head, field)					\
112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	for((var) = SLIST_FIRST(head);					\
113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	    (var) != SLIST_END(head);					\
114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	    (var) = SLIST_NEXT(var, field))
115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*
117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Singly-linked List functions.
118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */
119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	SLIST_INIT(head) {						\
120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	SLIST_FIRST(head) = SLIST_END(head);				\
121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	SLIST_INSERT_AFTER(slistelm, elm, field) do {			\
124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(elm)->field.sle_next = (slistelm)->field.sle_next;		\
125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(slistelm)->field.sle_next = (elm);				\
126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} while (0)
127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	SLIST_INSERT_HEAD(head, elm, field) do {			\
129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(elm)->field.sle_next = (head)->slh_first;			\
130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(head)->slh_first = (elm);					\
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} while (0)
132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	SLIST_REMOVE_HEAD(head, field) do {				\
134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(head)->slh_first = (head)->slh_first->field.sle_next;		\
135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} while (0)
136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*
138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * List definitions.
139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */
140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define LIST_HEAD(name, type)						\
141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct name {								\
142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct type *lh_first;	/* first element */			\
143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define LIST_HEAD_INITIALIZER(head)					\
146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	{ NULL }
147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define LIST_ENTRY(type)						\
149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct {								\
150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct type *le_next;	/* next element */			\
151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct type **le_prev;	/* address of previous next element */	\
152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*
155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * List access methods
156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */
157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	LIST_FIRST(head)		((head)->lh_first)
158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	LIST_END(head)			NULL
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	LIST_EMPTY(head)		(LIST_FIRST(head) == LIST_END(head))
160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	LIST_NEXT(elm, field)		((elm)->field.le_next)
161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define LIST_FOREACH(var, head, field)					\
163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	for((var) = LIST_FIRST(head);					\
164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	    (var)!= LIST_END(head);					\
165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	    (var) = LIST_NEXT(var, field))
166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*
168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * List functions.
169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */
170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	LIST_INIT(head) do {						\
171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	LIST_FIRST(head) = LIST_END(head);				\
172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} while (0)
173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define LIST_INSERT_AFTER(listelm, elm, field) do {			\
175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)	\
176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(listelm)->field.le_next->field.le_prev =		\
177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		    &(elm)->field.le_next;				\
178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(listelm)->field.le_next = (elm);				\
179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(elm)->field.le_prev = &(listelm)->field.le_next;		\
180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} while (0)
181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	LIST_INSERT_BEFORE(listelm, elm, field) do {			\
183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(elm)->field.le_prev = (listelm)->field.le_prev;		\
184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(elm)->field.le_next = (listelm);				\
185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	*(listelm)->field.le_prev = (elm);				\
186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(listelm)->field.le_prev = &(elm)->field.le_next;		\
187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} while (0)
188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define LIST_INSERT_HEAD(head, elm, field) do {				\
190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (((elm)->field.le_next = (head)->lh_first) != NULL)		\
191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(head)->lh_first = (elm);					\
193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(elm)->field.le_prev = &(head)->lh_first;			\
194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} while (0)
195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define LIST_REMOVE(elm, field) do {					\
197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if ((elm)->field.le_next != NULL)				\
198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(elm)->field.le_next->field.le_prev =			\
199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		    (elm)->field.le_prev;				\
200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	*(elm)->field.le_prev = (elm)->field.le_next;			\
201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} while (0)
202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define LIST_REPLACE(elm, elm2, field) do {				\
204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (((elm2)->field.le_next = (elm)->field.le_next) != NULL)	\
205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(elm2)->field.le_next->field.le_prev =			\
206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		    &(elm2)->field.le_next;				\
207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(elm2)->field.le_prev = (elm)->field.le_prev;			\
208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	*(elm2)->field.le_prev = (elm2);				\
209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} while (0)
210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*
212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Simple queue definitions.
213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */
214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define SIMPLEQ_HEAD(name, type)					\
215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct name {								\
216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct type *sqh_first;	/* first element */			\
217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct type **sqh_last;	/* addr of last next element */		\
218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define SIMPLEQ_HEAD_INITIALIZER(head)					\
221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	{ NULL, &(head).sqh_first }
222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define SIMPLEQ_ENTRY(type)						\
224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct {								\
225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct type *sqe_next;	/* next element */			\
226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*
229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Simple queue access methods.
230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */
231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	SIMPLEQ_FIRST(head)	    ((head)->sqh_first)
232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	SIMPLEQ_END(head)	    NULL
233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	SIMPLEQ_EMPTY(head)	    (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	SIMPLEQ_NEXT(elm, field)    ((elm)->field.sqe_next)
235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define SIMPLEQ_FOREACH(var, head, field)				\
237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	for((var) = SIMPLEQ_FIRST(head);				\
238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	    (var) != SIMPLEQ_END(head);					\
239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	    (var) = SIMPLEQ_NEXT(var, field))
240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*
242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Simple queue functions.
243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */
244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	SIMPLEQ_INIT(head) do {						\
245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(head)->sqh_first = NULL;					\
246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(head)->sqh_last = &(head)->sqh_first;				\
247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} while (0)
248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define SIMPLEQ_INSERT_HEAD(head, elm, field) do {			\
250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (((elm)->field.sqe_next = (head)->sqh_first) == NULL)	\
251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(head)->sqh_last = &(elm)->field.sqe_next;		\
252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(head)->sqh_first = (elm);					\
253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} while (0)
254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define SIMPLEQ_INSERT_TAIL(head, elm, field) do {			\
256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(elm)->field.sqe_next = NULL;					\
257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	*(head)->sqh_last = (elm);					\
258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(head)->sqh_last = &(elm)->field.sqe_next;			\
259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} while (0)
260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(head)->sqh_last = &(elm)->field.sqe_next;		\
264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(listelm)->field.sqe_next = (elm);				\
265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} while (0)
266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define SIMPLEQ_REMOVE_HEAD(head, elm, field) do {			\
268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (((head)->sqh_first = (elm)->field.sqe_next) == NULL)	\
269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(head)->sqh_last = &(head)->sqh_first;			\
270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} while (0)
271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*
273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Tail queue definitions.
274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */
275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define TAILQ_HEAD(name, type)						\
276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct name {								\
277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct type *tqh_first;	/* first element */			\
278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct type **tqh_last;	/* addr of last next element */		\
279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define TAILQ_HEAD_INITIALIZER(head)					\
282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	{ NULL, &(head).tqh_first }
283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define TAILQ_ENTRY(type)						\
285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct {								\
286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct type *tqe_next;	/* next element */			\
287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct type **tqe_prev;	/* address of previous next element */	\
288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*
291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * tail queue access methods
292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */
293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	TAILQ_FIRST(head)		((head)->tqh_first)
294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	TAILQ_END(head)			NULL
295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	TAILQ_NEXT(elm, field)		((elm)->field.tqe_next)
296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define TAILQ_LAST(head, headname)					\
297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(*(((struct headname *)((head)->tqh_last))->tqh_last))
298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* XXX */
299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define TAILQ_PREV(elm, headname, field)				\
300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	TAILQ_EMPTY(head)						\
302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(TAILQ_FIRST(head) == TAILQ_END(head))
303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define TAILQ_FOREACH(var, head, field)					\
305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	for((var) = TAILQ_FIRST(head);					\
306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	    (var) != TAILQ_END(head);					\
307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	    (var) = TAILQ_NEXT(var, field))
308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define TAILQ_FOREACH_REVERSE(var, head, field, headname)		\
310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	for((var) = TAILQ_LAST(head, headname);				\
311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	    (var) != TAILQ_END(head);					\
312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	    (var) = TAILQ_PREV(var, headname, field))
313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*
315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Tail queue functions.
316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */
317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	TAILQ_INIT(head) do {						\
318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(head)->tqh_first = NULL;					\
319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(head)->tqh_last = &(head)->tqh_first;				\
320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} while (0)
321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define TAILQ_INSERT_HEAD(head, elm, field) do {			\
323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)	\
324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(head)->tqh_first->field.tqe_prev =			\
325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		    &(elm)->field.tqe_next;				\
326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	else								\
327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(head)->tqh_last = &(elm)->field.tqe_next;		\
328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(head)->tqh_first = (elm);					\
329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(elm)->field.tqe_prev = &(head)->tqh_first;			\
330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} while (0)
331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define TAILQ_INSERT_TAIL(head, elm, field) do {			\
333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(elm)->field.tqe_next = NULL;					\
334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(elm)->field.tqe_prev = (head)->tqh_last;			\
335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	*(head)->tqh_last = (elm);					\
336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(head)->tqh_last = &(elm)->field.tqe_next;			\
337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} while (0)
338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(elm)->field.tqe_next->field.tqe_prev =			\
342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		    &(elm)->field.tqe_next;				\
343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	else								\
344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(head)->tqh_last = &(elm)->field.tqe_next;		\
345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(listelm)->field.tqe_next = (elm);				\
346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(elm)->field.tqe_prev = &(listelm)->field.tqe_next;		\
347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} while (0)
348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	TAILQ_INSERT_BEFORE(listelm, elm, field) do {			\
350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(elm)->field.tqe_next = (listelm);				\
352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	*(listelm)->field.tqe_prev = (elm);				\
353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(listelm)->field.tqe_prev = &(elm)->field.tqe_next;		\
354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} while (0)
355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define TAILQ_REMOVE(head, elm, field) do {				\
357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (((elm)->field.tqe_next) != NULL)				\
358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(elm)->field.tqe_next->field.tqe_prev =			\
359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		    (elm)->field.tqe_prev;				\
360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	else								\
361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(head)->tqh_last = (elm)->field.tqe_prev;		\
362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	*(elm)->field.tqe_prev = (elm)->field.tqe_next;			\
363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} while (0)
364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define TAILQ_REPLACE(head, elm, elm2, field) do {			\
366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL)	\
367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(elm2)->field.tqe_next->field.tqe_prev =		\
368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		    &(elm2)->field.tqe_next;				\
369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	else								\
370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(head)->tqh_last = &(elm2)->field.tqe_next;		\
371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(elm2)->field.tqe_prev = (elm)->field.tqe_prev;			\
372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	*(elm2)->field.tqe_prev = (elm2);				\
373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} while (0)
374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*
376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Circular queue definitions.
377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */
378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define CIRCLEQ_HEAD(name, type)					\
379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct name {								\
380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct type *cqh_first;		/* first element */		\
381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct type *cqh_last;		/* last element */		\
382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define CIRCLEQ_HEAD_INITIALIZER(head)					\
385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	{ CIRCLEQ_END(&head), CIRCLEQ_END(&head) }
386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define CIRCLEQ_ENTRY(type)						\
388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct {								\
389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct type *cqe_next;		/* next element */		\
390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	struct type *cqe_prev;		/* previous element */		\
391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*
394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Circular queue access methods
395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */
396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	CIRCLEQ_FIRST(head)		((head)->cqh_first)
397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	CIRCLEQ_LAST(head)		((head)->cqh_last)
398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	CIRCLEQ_END(head)		((void *)(head))
399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	CIRCLEQ_NEXT(elm, field)	((elm)->field.cqe_next)
400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	CIRCLEQ_PREV(elm, field)	((elm)->field.cqe_prev)
401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	CIRCLEQ_EMPTY(head)						\
402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(CIRCLEQ_FIRST(head) == CIRCLEQ_END(head))
403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define CIRCLEQ_FOREACH(var, head, field)				\
405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	for((var) = CIRCLEQ_FIRST(head);				\
406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	    (var) != CIRCLEQ_END(head);					\
407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	    (var) = CIRCLEQ_NEXT(var, field))
408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define CIRCLEQ_FOREACH_REVERSE(var, head, field)			\
410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	for((var) = CIRCLEQ_LAST(head);					\
411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	    (var) != CIRCLEQ_END(head);					\
412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	    (var) = CIRCLEQ_PREV(var, field))
413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*
415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Circular queue functions.
416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */
417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	CIRCLEQ_INIT(head) do {						\
418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(head)->cqh_first = CIRCLEQ_END(head);				\
419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(head)->cqh_last = CIRCLEQ_END(head);				\
420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} while (0)
421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(elm)->field.cqe_next = (listelm)->field.cqe_next;		\
424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(elm)->field.cqe_prev = (listelm);				\
425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if ((listelm)->field.cqe_next == CIRCLEQ_END(head))		\
426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(head)->cqh_last = (elm);				\
427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	else								\
428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(listelm)->field.cqe_next->field.cqe_prev = (elm);	\
429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(listelm)->field.cqe_next = (elm);				\
430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} while (0)
431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {		\
433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(elm)->field.cqe_next = (listelm);				\
434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(elm)->field.cqe_prev = (listelm)->field.cqe_prev;		\
435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if ((listelm)->field.cqe_prev == CIRCLEQ_END(head))		\
436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(head)->cqh_first = (elm);				\
437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	else								\
438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(listelm)->field.cqe_prev->field.cqe_next = (elm);	\
439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(listelm)->field.cqe_prev = (elm);				\
440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} while (0)
441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define CIRCLEQ_INSERT_HEAD(head, elm, field) do {			\
443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(elm)->field.cqe_next = (head)->cqh_first;			\
444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(elm)->field.cqe_prev = CIRCLEQ_END(head);			\
445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if ((head)->cqh_last == CIRCLEQ_END(head))			\
446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(head)->cqh_last = (elm);				\
447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	else								\
448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(head)->cqh_first->field.cqe_prev = (elm);		\
449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(head)->cqh_first = (elm);					\
450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} while (0)
451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define CIRCLEQ_INSERT_TAIL(head, elm, field) do {			\
453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(elm)->field.cqe_next = CIRCLEQ_END(head);			\
454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(elm)->field.cqe_prev = (head)->cqh_last;			\
455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if ((head)->cqh_first == CIRCLEQ_END(head))			\
456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(head)->cqh_first = (elm);				\
457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	else								\
458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(head)->cqh_last->field.cqe_next = (elm);		\
459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	(head)->cqh_last = (elm);					\
460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} while (0)
461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define	CIRCLEQ_REMOVE(head, elm, field) do {				\
463c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if ((elm)->field.cqe_next == CIRCLEQ_END(head))			\
464c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(head)->cqh_last = (elm)->field.cqe_prev;		\
465c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	else								\
466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(elm)->field.cqe_next->field.cqe_prev =			\
467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		    (elm)->field.cqe_prev;				\
468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if ((elm)->field.cqe_prev == CIRCLEQ_END(head))			\
469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(head)->cqh_first = (elm)->field.cqe_next;		\
470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	else								\
471c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(elm)->field.cqe_prev->field.cqe_next =			\
472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		    (elm)->field.cqe_next;				\
473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} while (0)
474c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
475c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define CIRCLEQ_REPLACE(head, elm, elm2, field) do {			\
476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (((elm2)->field.cqe_next = (elm)->field.cqe_next) ==		\
477c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	    CIRCLEQ_END(head))						\
478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(head).cqh_last = (elm2);				\
479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	else								\
480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(elm2)->field.cqe_next->field.cqe_prev = (elm2);	\
481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) ==		\
482c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	    CIRCLEQ_END(head))						\
483c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(head).cqh_first = (elm2);				\
484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	else								\
485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		(elm2)->field.cqe_prev->field.cqe_next = (elm2);	\
486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} while (0)
487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif	/* !_SYS_QUEUE_H_ */
489