xref: /titanic_44/usr/src/uts/common/sys/queue.h (revision 710f7c23e0f1abee9935d4db2d0a90ca0ddee3db)
1381a2a9aSdr146992 /*	$NetBSD: queue.h,v 1.42 2005/07/13 15:08:24 wiz Exp $	*/
2381a2a9aSdr146992 
3381a2a9aSdr146992 /*
4381a2a9aSdr146992  * Copyright (c) 1991, 1993
5381a2a9aSdr146992  *	The Regents of the University of California.  All rights reserved.
6381a2a9aSdr146992  *
7381a2a9aSdr146992  * Redistribution and use in source and binary forms, with or without
8381a2a9aSdr146992  * modification, are permitted provided that the following conditions
9381a2a9aSdr146992  * are met:
10381a2a9aSdr146992  * 1. Redistributions of source code must retain the above copyright
11381a2a9aSdr146992  *    notice, this list of conditions and the following disclaimer.
12381a2a9aSdr146992  * 2. Redistributions in binary form must reproduce the above copyright
13381a2a9aSdr146992  *    notice, this list of conditions and the following disclaimer in the
14381a2a9aSdr146992  *    documentation and/or other materials provided with the distribution.
15381a2a9aSdr146992  * 3. Neither the name of the University nor the names of its contributors
16381a2a9aSdr146992  *    may be used to endorse or promote products derived from this software
17381a2a9aSdr146992  *    without specific prior written permission.
18381a2a9aSdr146992  *
19381a2a9aSdr146992  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20381a2a9aSdr146992  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21381a2a9aSdr146992  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22381a2a9aSdr146992  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23381a2a9aSdr146992  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24381a2a9aSdr146992  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25381a2a9aSdr146992  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26381a2a9aSdr146992  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27381a2a9aSdr146992  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28381a2a9aSdr146992  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29381a2a9aSdr146992  * SUCH DAMAGE.
30381a2a9aSdr146992  *
31381a2a9aSdr146992  *	@(#)queue.h	8.5 (Berkeley) 8/20/94
32381a2a9aSdr146992  */
33381a2a9aSdr146992 /*
34c1374a13SSurya Prakki  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
35381a2a9aSdr146992  * Use is subject to license terms.
36381a2a9aSdr146992  */
37381a2a9aSdr146992 
38381a2a9aSdr146992 #ifndef	_SYS_QUEUE_H
39381a2a9aSdr146992 #define	_SYS_QUEUE_H
40381a2a9aSdr146992 
41381a2a9aSdr146992 #include <sys/note.h>
42381a2a9aSdr146992 
43381a2a9aSdr146992 #ifdef	__cplusplus
44381a2a9aSdr146992 extern "C" {
45381a2a9aSdr146992 #endif
46381a2a9aSdr146992 
47381a2a9aSdr146992 /*
48381a2a9aSdr146992  * This file defines five types of data structures: singly-linked lists,
49381a2a9aSdr146992  * lists, simple queues, tail queues, and circular queues.
50381a2a9aSdr146992  *
51381a2a9aSdr146992  * A singly-linked list is headed by a single forward pointer. The
52381a2a9aSdr146992  * elements are singly linked for minimum space and pointer manipulation
53381a2a9aSdr146992  * overhead at the expense of O(n) removal for arbitrary elements. New
54381a2a9aSdr146992  * elements can be added to the list after an existing element or at the
55381a2a9aSdr146992  * head of the list.  Elements being removed from the head of the list
56381a2a9aSdr146992  * should use the explicit macro for this purpose for optimum
57381a2a9aSdr146992  * efficiency. A singly-linked list may only be traversed in the forward
58381a2a9aSdr146992  * direction.  Singly-linked lists are ideal for applications with large
59381a2a9aSdr146992  * datasets and few or no removals or for implementing a LIFO queue.
60381a2a9aSdr146992  *
61381a2a9aSdr146992  * A list is headed by a single forward pointer (or an array of forward
62381a2a9aSdr146992  * pointers for a hash table header). The elements are doubly linked
63381a2a9aSdr146992  * so that an arbitrary element can be removed without a need to
64381a2a9aSdr146992  * traverse the list. New elements can be added to the list before
65381a2a9aSdr146992  * or after an existing element or at the head of the list. A list
66381a2a9aSdr146992  * may only be traversed in the forward direction.
67381a2a9aSdr146992  *
68381a2a9aSdr146992  * A simple queue is headed by a pair of pointers, one the head of the
69381a2a9aSdr146992  * list and the other to the tail of the list. The elements are singly
70381a2a9aSdr146992  * linked to save space, so elements can only be removed from the
71381a2a9aSdr146992  * head of the list. New elements can be added to the list after
72381a2a9aSdr146992  * an existing element, at the head of the list, or at the end of the
73381a2a9aSdr146992  * list. A simple queue may only be traversed in the forward direction.
74381a2a9aSdr146992  *
75381a2a9aSdr146992  * A tail queue is headed by a pair of pointers, one to the head of the
76381a2a9aSdr146992  * list and the other to the tail of the list. The elements are doubly
77381a2a9aSdr146992  * linked so that an arbitrary element can be removed without a need to
78381a2a9aSdr146992  * traverse the list. New elements can be added to the list before or
79381a2a9aSdr146992  * after an existing element, at the head of the list, or at the end of
80381a2a9aSdr146992  * the list. A tail queue may be traversed in either direction.
81381a2a9aSdr146992  *
82381a2a9aSdr146992  * A circle queue is headed by a pair of pointers, one to the head of the
83381a2a9aSdr146992  * list and the other to the tail of the list. The elements are doubly
84381a2a9aSdr146992  * linked so that an arbitrary element can be removed without a need to
85381a2a9aSdr146992  * traverse the list. New elements can be added to the list before or after
86381a2a9aSdr146992  * an existing element, at the head of the list, or at the end of the list.
87381a2a9aSdr146992  * A circle queue may be traversed in either direction, but has a more
88381a2a9aSdr146992  * complex end of list detection.
89381a2a9aSdr146992  *
90381a2a9aSdr146992  * For details on the use of these macros, see the queue(3) manual page.
91381a2a9aSdr146992  */
92381a2a9aSdr146992 
93381a2a9aSdr146992 /*
94381a2a9aSdr146992  * List definitions.
95381a2a9aSdr146992  */
96381a2a9aSdr146992 #define	LIST_HEAD(name, type)						\
97381a2a9aSdr146992 struct name {								\
98381a2a9aSdr146992 	struct type *lh_first;	/* first element */			\
99381a2a9aSdr146992 }
100381a2a9aSdr146992 
101381a2a9aSdr146992 #define	LIST_HEAD_INITIALIZER(head)					\
102381a2a9aSdr146992 	{ NULL }
103381a2a9aSdr146992 
104381a2a9aSdr146992 #define	LIST_ENTRY(type)						\
105381a2a9aSdr146992 struct {								\
106381a2a9aSdr146992 	struct type *le_next;	/* next element */			\
107381a2a9aSdr146992 	struct type **le_prev;	/* address of previous next element */	\
108381a2a9aSdr146992 }
109381a2a9aSdr146992 
110381a2a9aSdr146992 /*
111381a2a9aSdr146992  * List functions.
112381a2a9aSdr146992  */
113381a2a9aSdr146992 #if defined(_KERNEL) && defined(QUEUEDEBUG)
114381a2a9aSdr146992 #define	QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field)			\
115381a2a9aSdr146992 	if ((head)->lh_first &&						\
116381a2a9aSdr146992 	    (head)->lh_first->field.le_prev != &(head)->lh_first)	\
117381a2a9aSdr146992 		panic("LIST_INSERT_HEAD %p %s:%d", (head), __FILE__, __LINE__);
118381a2a9aSdr146992 #define	QUEUEDEBUG_LIST_OP(elm, field)					\
119381a2a9aSdr146992 	if ((elm)->field.le_next &&					\
120381a2a9aSdr146992 	    (elm)->field.le_next->field.le_prev !=			\
121381a2a9aSdr146992 	    &(elm)->field.le_next)					\
122381a2a9aSdr146992 		panic("LIST_* forw %p %s:%d", (elm), __FILE__, __LINE__);\
123381a2a9aSdr146992 	if (*(elm)->field.le_prev != (elm))				\
124381a2a9aSdr146992 		panic("LIST_* back %p %s:%d", (elm), __FILE__, __LINE__);
125381a2a9aSdr146992 #define	QUEUEDEBUG_LIST_POSTREMOVE(elm, field)				\
126381a2a9aSdr146992 	(elm)->field.le_next = (void *)1L;				\
127381a2a9aSdr146992 	(elm)->field.le_prev = (void *)1L;
128381a2a9aSdr146992 #else
129381a2a9aSdr146992 #define	QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field)
130381a2a9aSdr146992 #define	QUEUEDEBUG_LIST_OP(elm, field)
131381a2a9aSdr146992 #define	QUEUEDEBUG_LIST_POSTREMOVE(elm, field)
132381a2a9aSdr146992 #endif
133381a2a9aSdr146992 
134381a2a9aSdr146992 #define	LIST_INIT(head) do {						\
135381a2a9aSdr146992 	(head)->lh_first = NULL;					\
136381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
137381a2a9aSdr146992 } while (0)
138381a2a9aSdr146992 
139381a2a9aSdr146992 #define	LIST_INSERT_AFTER(listelm, elm, field) do {			\
140381a2a9aSdr146992 	QUEUEDEBUG_LIST_OP((listelm), field)				\
141381a2a9aSdr146992 	if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)	\
142381a2a9aSdr146992 		(listelm)->field.le_next->field.le_prev =		\
143381a2a9aSdr146992 		    &(elm)->field.le_next;				\
144381a2a9aSdr146992 	(listelm)->field.le_next = (elm);				\
145381a2a9aSdr146992 	(elm)->field.le_prev = &(listelm)->field.le_next;		\
146381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
147381a2a9aSdr146992 } while (0)
148381a2a9aSdr146992 
149381a2a9aSdr146992 #define	LIST_INSERT_BEFORE(listelm, elm, field) do {			\
150381a2a9aSdr146992 	QUEUEDEBUG_LIST_OP((listelm), field)				\
151381a2a9aSdr146992 	(elm)->field.le_prev = (listelm)->field.le_prev;		\
152381a2a9aSdr146992 	(elm)->field.le_next = (listelm);				\
153381a2a9aSdr146992 	*(listelm)->field.le_prev = (elm);				\
154381a2a9aSdr146992 	(listelm)->field.le_prev = &(elm)->field.le_next;		\
155381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
156381a2a9aSdr146992 } while (0)
157381a2a9aSdr146992 
158381a2a9aSdr146992 #define	LIST_INSERT_HEAD(head, elm, field) do {				\
159381a2a9aSdr146992 	QUEUEDEBUG_LIST_INSERT_HEAD((head), (elm), field)		\
160381a2a9aSdr146992 	if (((elm)->field.le_next = (head)->lh_first) != NULL)		\
161381a2a9aSdr146992 		(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
162381a2a9aSdr146992 	(head)->lh_first = (elm);					\
163381a2a9aSdr146992 	(elm)->field.le_prev = &(head)->lh_first;			\
164381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
165381a2a9aSdr146992 } while (0)
166381a2a9aSdr146992 
167381a2a9aSdr146992 #define	LIST_REMOVE(elm, field) do {					\
168381a2a9aSdr146992 	QUEUEDEBUG_LIST_OP((elm), field)				\
169381a2a9aSdr146992 	if ((elm)->field.le_next != NULL)				\
170381a2a9aSdr146992 		(elm)->field.le_next->field.le_prev = 			\
171381a2a9aSdr146992 		    (elm)->field.le_prev;				\
172381a2a9aSdr146992 	*(elm)->field.le_prev = (elm)->field.le_next;			\
173381a2a9aSdr146992 	QUEUEDEBUG_LIST_POSTREMOVE((elm), field)			\
174381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
175381a2a9aSdr146992 } while (0)
176381a2a9aSdr146992 
177381a2a9aSdr146992 #define	LIST_FOREACH(var, head, field)					\
178381a2a9aSdr146992 	for ((var) = ((head)->lh_first);				\
179381a2a9aSdr146992 		(var);							\
180381a2a9aSdr146992 		(var) = ((var)->field.le_next))
181381a2a9aSdr146992 
182381a2a9aSdr146992 /*
183381a2a9aSdr146992  * List access methods.
184381a2a9aSdr146992  */
185381a2a9aSdr146992 #define	LIST_EMPTY(head)		((head)->lh_first == NULL)
186381a2a9aSdr146992 #define	LIST_FIRST(head)		((head)->lh_first)
187381a2a9aSdr146992 #define	LIST_NEXT(elm, field)		((elm)->field.le_next)
188381a2a9aSdr146992 
189381a2a9aSdr146992 
190381a2a9aSdr146992 /*
191381a2a9aSdr146992  * Singly-linked List definitions.
192381a2a9aSdr146992  */
193381a2a9aSdr146992 #define	SLIST_HEAD(name, type)						\
194381a2a9aSdr146992 struct name {								\
195381a2a9aSdr146992 	struct type *slh_first;	/* first element */			\
196381a2a9aSdr146992 }
197381a2a9aSdr146992 
198381a2a9aSdr146992 #define	SLIST_HEAD_INITIALIZER(head)					\
199381a2a9aSdr146992 	{ NULL }
200381a2a9aSdr146992 
201381a2a9aSdr146992 #define	SLIST_ENTRY(type)						\
202381a2a9aSdr146992 struct {								\
203381a2a9aSdr146992 	struct type *sle_next;	/* next element */			\
204381a2a9aSdr146992 }
205381a2a9aSdr146992 
206381a2a9aSdr146992 /*
207381a2a9aSdr146992  * Singly-linked List functions.
208381a2a9aSdr146992  */
209381a2a9aSdr146992 #define	SLIST_INIT(head) do {						\
210381a2a9aSdr146992 	(head)->slh_first = NULL;					\
211381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
212381a2a9aSdr146992 } while (0)
213381a2a9aSdr146992 
214381a2a9aSdr146992 #define	SLIST_INSERT_AFTER(slistelm, elm, field) do {			\
215381a2a9aSdr146992 	(elm)->field.sle_next = (slistelm)->field.sle_next;		\
216381a2a9aSdr146992 	(slistelm)->field.sle_next = (elm);				\
217381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
218381a2a9aSdr146992 } while (0)
219381a2a9aSdr146992 
220381a2a9aSdr146992 #define	SLIST_INSERT_HEAD(head, elm, field) do {			\
221381a2a9aSdr146992 	(elm)->field.sle_next = (head)->slh_first;			\
222381a2a9aSdr146992 	(head)->slh_first = (elm);					\
223381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
224381a2a9aSdr146992 } while (0)
225381a2a9aSdr146992 
226381a2a9aSdr146992 #define	SLIST_REMOVE_HEAD(head, field) do {				\
227381a2a9aSdr146992 	(head)->slh_first = (head)->slh_first->field.sle_next;		\
228381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
229381a2a9aSdr146992 } while (0)
230381a2a9aSdr146992 
231381a2a9aSdr146992 #define	SLIST_REMOVE(head, elm, type, field) do {			\
232381a2a9aSdr146992 	if ((head)->slh_first == (elm)) {				\
233381a2a9aSdr146992 		SLIST_REMOVE_HEAD((head), field);			\
234381a2a9aSdr146992 	}								\
235381a2a9aSdr146992 	else {								\
236381a2a9aSdr146992 		struct type *curelm = (head)->slh_first;		\
237381a2a9aSdr146992 		while (curelm->field.sle_next != (elm))			\
238381a2a9aSdr146992 			curelm = curelm->field.sle_next;		\
239381a2a9aSdr146992 		curelm->field.sle_next =				\
240381a2a9aSdr146992 		    curelm->field.sle_next->field.sle_next;		\
241381a2a9aSdr146992 	}								\
242381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
243381a2a9aSdr146992 } while (0)
244381a2a9aSdr146992 
245381a2a9aSdr146992 #define	SLIST_FOREACH(var, head, field)					\
246381a2a9aSdr146992 	for ((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
247381a2a9aSdr146992 
248381a2a9aSdr146992 /*
249381a2a9aSdr146992  * Singly-linked List access methods.
250381a2a9aSdr146992  */
251381a2a9aSdr146992 #define	SLIST_EMPTY(head)	((head)->slh_first == NULL)
252381a2a9aSdr146992 #define	SLIST_FIRST(head)	((head)->slh_first)
253381a2a9aSdr146992 #define	SLIST_NEXT(elm, field)	((elm)->field.sle_next)
254381a2a9aSdr146992 
255381a2a9aSdr146992 
256381a2a9aSdr146992 /*
257381a2a9aSdr146992  * Singly-linked Tail queue declarations.
258381a2a9aSdr146992  */
259381a2a9aSdr146992 #define	STAILQ_HEAD(name, type)						\
260381a2a9aSdr146992 struct name {								\
261381a2a9aSdr146992 	struct type *stqh_first;	/* first element */		\
262381a2a9aSdr146992 	struct type **stqh_last;	/* addr of last next element */	\
263381a2a9aSdr146992 }
264381a2a9aSdr146992 
265381a2a9aSdr146992 #define	STAILQ_HEAD_INITIALIZER(head)					\
266381a2a9aSdr146992 	{ NULL, &(head).stqh_first }
267381a2a9aSdr146992 
268381a2a9aSdr146992 #define	STAILQ_ENTRY(type)						\
269381a2a9aSdr146992 struct {								\
270381a2a9aSdr146992 	struct type *stqe_next;	/* next element */		\
271381a2a9aSdr146992 }
272381a2a9aSdr146992 
273381a2a9aSdr146992 /*
274381a2a9aSdr146992  * Singly-linked Tail queue functions.
275381a2a9aSdr146992  */
276381a2a9aSdr146992 #define	STAILQ_INIT(head) do {						\
277381a2a9aSdr146992 	(head)->stqh_first = NULL;					\
278381a2a9aSdr146992 	(head)->stqh_last = &(head)->stqh_first;			\
279381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
280381a2a9aSdr146992 } while (0)
281381a2a9aSdr146992 
282381a2a9aSdr146992 #define	STAILQ_INSERT_HEAD(head, elm, field) do {			\
283381a2a9aSdr146992 	if (((elm)->field.stqe_next = (head)->stqh_first) == NULL)	\
284381a2a9aSdr146992 		(head)->stqh_last = &(elm)->field.stqe_next;		\
285381a2a9aSdr146992 	(head)->stqh_first = (elm);					\
286381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
287381a2a9aSdr146992 } while (0)
288381a2a9aSdr146992 
289381a2a9aSdr146992 #define	STAILQ_INSERT_TAIL(head, elm, field) do {			\
290381a2a9aSdr146992 	(elm)->field.stqe_next = NULL;					\
291381a2a9aSdr146992 	*(head)->stqh_last = (elm);					\
292381a2a9aSdr146992 	(head)->stqh_last = &(elm)->field.stqe_next;			\
293381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
294381a2a9aSdr146992 } while (0)
295381a2a9aSdr146992 
296381a2a9aSdr146992 #define	STAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
297381a2a9aSdr146992 	if (((elm)->field.stqe_next = (listelm)->field.stqe_next)	\
298381a2a9aSdr146992 	    == NULL)							\
299381a2a9aSdr146992 		(head)->stqh_last = &(elm)->field.stqe_next;		\
300381a2a9aSdr146992 	(listelm)->field.stqe_next = (elm);				\
301381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
302381a2a9aSdr146992 } while (0)
303381a2a9aSdr146992 
304381a2a9aSdr146992 #define	STAILQ_REMOVE_HEAD(head, field) do {				\
305381a2a9aSdr146992 	if (((head)->stqh_first = (head)->stqh_first->field.stqe_next)	\
306381a2a9aSdr146992 	    == NULL) 							\
307381a2a9aSdr146992 		(head)->stqh_last = &(head)->stqh_first;		\
308381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
309381a2a9aSdr146992 } while (0)
310381a2a9aSdr146992 
311381a2a9aSdr146992 #define	STAILQ_REMOVE(head, elm, type, field) do {			\
312381a2a9aSdr146992 	if ((head)->stqh_first == (elm)) {				\
313381a2a9aSdr146992 		STAILQ_REMOVE_HEAD((head), field);			\
314381a2a9aSdr146992 	} else {							\
315381a2a9aSdr146992 		struct type *curelm = (head)->stqh_first;		\
316381a2a9aSdr146992 		while (curelm->field.stqe_next != (elm))		\
317381a2a9aSdr146992 			curelm = curelm->field.stqe_next;		\
318381a2a9aSdr146992 		if ((curelm->field.stqe_next =				\
319381a2a9aSdr146992 			curelm->field.stqe_next->field.stqe_next) == NULL) \
320381a2a9aSdr146992 			    (head)->stqh_last = &(curelm)->field.stqe_next; \
321381a2a9aSdr146992 	}								\
322381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
323381a2a9aSdr146992 } while (0)
324381a2a9aSdr146992 
325381a2a9aSdr146992 #define	STAILQ_FOREACH(var, head, field)				\
326381a2a9aSdr146992 	for ((var) = ((head)->stqh_first);				\
327381a2a9aSdr146992 		(var);							\
328381a2a9aSdr146992 		(var) = ((var)->field.stqe_next))
329381a2a9aSdr146992 
330381a2a9aSdr146992 /*
331381a2a9aSdr146992  * Singly-linked Tail queue access methods.
332381a2a9aSdr146992  */
333381a2a9aSdr146992 #define	STAILQ_EMPTY(head)	((head)->stqh_first == NULL)
334381a2a9aSdr146992 #define	STAILQ_FIRST(head)	((head)->stqh_first)
335381a2a9aSdr146992 #define	STAILQ_NEXT(elm, field)	((elm)->field.stqe_next)
336381a2a9aSdr146992 
337381a2a9aSdr146992 
338381a2a9aSdr146992 /*
339381a2a9aSdr146992  * Simple queue definitions.
340381a2a9aSdr146992  */
341381a2a9aSdr146992 #define	SIMPLEQ_HEAD(name, type)					\
342381a2a9aSdr146992 struct name {								\
343381a2a9aSdr146992 	struct type *sqh_first;	/* first element */		\
344381a2a9aSdr146992 	struct type **sqh_last;	/* addr of last next element */	\
345381a2a9aSdr146992 }
346381a2a9aSdr146992 
347381a2a9aSdr146992 #define	SIMPLEQ_HEAD_INITIALIZER(head)					\
348381a2a9aSdr146992 	{ NULL, &(head).sqh_first }
349381a2a9aSdr146992 
350381a2a9aSdr146992 #define	SIMPLEQ_ENTRY(type)						\
351381a2a9aSdr146992 struct {								\
352381a2a9aSdr146992 	struct type *sqe_next;	/* next element */			\
353381a2a9aSdr146992 }
354381a2a9aSdr146992 
355381a2a9aSdr146992 /*
356381a2a9aSdr146992  * Simple queue functions.
357381a2a9aSdr146992  */
358381a2a9aSdr146992 #define	SIMPLEQ_INIT(head) do {						\
359381a2a9aSdr146992 	(head)->sqh_first = NULL;					\
360381a2a9aSdr146992 	(head)->sqh_last = &(head)->sqh_first;				\
361381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
362381a2a9aSdr146992 } while (0)
363381a2a9aSdr146992 
364381a2a9aSdr146992 #define	SIMPLEQ_INSERT_HEAD(head, elm, field) do {			\
365381a2a9aSdr146992 	if (((elm)->field.sqe_next = (head)->sqh_first) == NULL)	\
366381a2a9aSdr146992 		(head)->sqh_last = &(elm)->field.sqe_next;		\
367381a2a9aSdr146992 	(head)->sqh_first = (elm);					\
368381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
369381a2a9aSdr146992 } while (0)
370381a2a9aSdr146992 
371381a2a9aSdr146992 #define	SIMPLEQ_INSERT_TAIL(head, elm, field) do {			\
372381a2a9aSdr146992 	(elm)->field.sqe_next = NULL;					\
373381a2a9aSdr146992 	*(head)->sqh_last = (elm);					\
374381a2a9aSdr146992 	(head)->sqh_last = &(elm)->field.sqe_next;			\
375381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
376381a2a9aSdr146992 } while (0)
377381a2a9aSdr146992 
378381a2a9aSdr146992 #define	SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
379381a2a9aSdr146992 	if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
380381a2a9aSdr146992 		(head)->sqh_last = &(elm)->field.sqe_next;		\
381381a2a9aSdr146992 	(listelm)->field.sqe_next = (elm);				\
382381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
383381a2a9aSdr146992 } while (0)
384381a2a9aSdr146992 
385381a2a9aSdr146992 #define	SIMPLEQ_REMOVE_HEAD(head, field) do {				\
386381a2a9aSdr146992 	if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
387381a2a9aSdr146992 		(head)->sqh_last = &(head)->sqh_first;			\
388381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
389381a2a9aSdr146992 } while (0)
390381a2a9aSdr146992 
391381a2a9aSdr146992 #define	SIMPLEQ_REMOVE(head, elm, type, field) do {			\
392381a2a9aSdr146992 	if ((head)->sqh_first == (elm)) {				\
393381a2a9aSdr146992 		SIMPLEQ_REMOVE_HEAD((head), field);			\
394381a2a9aSdr146992 	} else {							\
395381a2a9aSdr146992 		struct type *curelm = (head)->sqh_first;		\
396381a2a9aSdr146992 		while (curelm->field.sqe_next != (elm))			\
397381a2a9aSdr146992 			curelm = curelm->field.sqe_next;		\
398381a2a9aSdr146992 		if ((curelm->field.sqe_next =				\
399381a2a9aSdr146992 			curelm->field.sqe_next->field.sqe_next) == NULL) \
400381a2a9aSdr146992 			    (head)->sqh_last = &(curelm)->field.sqe_next; \
401381a2a9aSdr146992 	}								\
402381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
403381a2a9aSdr146992 } while (0)
404381a2a9aSdr146992 
405381a2a9aSdr146992 #define	SIMPLEQ_FOREACH(var, head, field)				\
406381a2a9aSdr146992 	for ((var) = ((head)->sqh_first);				\
407381a2a9aSdr146992 		(var);							\
408381a2a9aSdr146992 		(var) = ((var)->field.sqe_next))
409381a2a9aSdr146992 
410381a2a9aSdr146992 /*
411381a2a9aSdr146992  * Simple queue access methods.
412381a2a9aSdr146992  */
413381a2a9aSdr146992 #define	SIMPLEQ_EMPTY(head)		((head)->sqh_first == NULL)
414381a2a9aSdr146992 #define	SIMPLEQ_FIRST(head)		((head)->sqh_first)
415381a2a9aSdr146992 #define	SIMPLEQ_NEXT(elm, field)	((elm)->field.sqe_next)
416381a2a9aSdr146992 
417381a2a9aSdr146992 
418381a2a9aSdr146992 /*
419381a2a9aSdr146992  * Tail queue definitions.
420381a2a9aSdr146992  */
421381a2a9aSdr146992 #define	_TAILQ_HEAD(name, type)						\
422381a2a9aSdr146992 struct name {								\
423381a2a9aSdr146992 	type *tqh_first;		/* first element */		\
424381a2a9aSdr146992 	type **tqh_last;	/* addr of last next element */		\
425381a2a9aSdr146992 }
426381a2a9aSdr146992 #define	TAILQ_HEAD(name, type)	_TAILQ_HEAD(name, struct type)
427381a2a9aSdr146992 
428381a2a9aSdr146992 #define	TAILQ_HEAD_INITIALIZER(head)					\
429381a2a9aSdr146992 	{ NULL, &(head).tqh_first }
430381a2a9aSdr146992 
431381a2a9aSdr146992 #define	_TAILQ_ENTRY(type)						\
432381a2a9aSdr146992 struct {								\
433381a2a9aSdr146992 	type *tqe_next;		/* next element */			\
434381a2a9aSdr146992 	type **tqe_prev;	/* address of previous next element */\
435381a2a9aSdr146992 }
436381a2a9aSdr146992 #define	TAILQ_ENTRY(type)	_TAILQ_ENTRY(struct type)
437381a2a9aSdr146992 
438381a2a9aSdr146992 /*
439381a2a9aSdr146992  * Tail queue functions.
440381a2a9aSdr146992  */
441381a2a9aSdr146992 #if defined(_KERNEL) && defined(QUEUEDEBUG)
442381a2a9aSdr146992 #define	QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field)			\
443381a2a9aSdr146992 	if ((head)->tqh_first &&					\
444381a2a9aSdr146992 	    (head)->tqh_first->field.tqe_prev != &(head)->tqh_first)	\
445c1374a13SSurya Prakki 		panic("TAILQ_INSERT_HEAD %p %s:%d", (void *)(head),	\
446c1374a13SSurya Prakki 		    __FILE__, __LINE__);
447381a2a9aSdr146992 #define	QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field)			\
448381a2a9aSdr146992 	if (*(head)->tqh_last != NULL)					\
449c1374a13SSurya Prakki 		panic("TAILQ_INSERT_TAIL %p %s:%d", (void *)(head),	\
450c1374a13SSurya Prakki 		    __FILE__, __LINE__);
451381a2a9aSdr146992 #define	QUEUEDEBUG_TAILQ_OP(elm, field)					\
452381a2a9aSdr146992 	if ((elm)->field.tqe_next &&					\
453381a2a9aSdr146992 	    (elm)->field.tqe_next->field.tqe_prev !=			\
454381a2a9aSdr146992 	    &(elm)->field.tqe_next)					\
455c1374a13SSurya Prakki 		panic("TAILQ_* forw %p %s:%d", (void *)(elm),		\
456c1374a13SSurya Prakki 		    __FILE__, __LINE__);\
457381a2a9aSdr146992 	if (*(elm)->field.tqe_prev != (elm))				\
458c1374a13SSurya Prakki 		panic("TAILQ_* back %p %s:%d", (void *)(elm),		\
459c1374a13SSurya Prakki 		    __FILE__, __LINE__);
460381a2a9aSdr146992 #define	QUEUEDEBUG_TAILQ_PREREMOVE(head, elm, field)			\
461381a2a9aSdr146992 	if ((elm)->field.tqe_next == NULL &&				\
462381a2a9aSdr146992 	    (head)->tqh_last != &(elm)->field.tqe_next)			\
463381a2a9aSdr146992 		panic("TAILQ_PREREMOVE head %p elm %p %s:%d",		\
464c1374a13SSurya Prakki 		    (void *)(head), (void *)(elm), __FILE__, __LINE__);
465381a2a9aSdr146992 #define	QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field)				\
466381a2a9aSdr146992 	(elm)->field.tqe_next = (void *)1L;				\
467381a2a9aSdr146992 	(elm)->field.tqe_prev = (void *)1L;
468381a2a9aSdr146992 #else
469381a2a9aSdr146992 #define	QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field)
470381a2a9aSdr146992 #define	QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field)
471381a2a9aSdr146992 #define	QUEUEDEBUG_TAILQ_OP(elm, field)
472381a2a9aSdr146992 #define	QUEUEDEBUG_TAILQ_PREREMOVE(head, elm, field)
473381a2a9aSdr146992 #define	QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field)
474381a2a9aSdr146992 #endif
475381a2a9aSdr146992 
476381a2a9aSdr146992 #define	TAILQ_INIT(head) do {						\
477381a2a9aSdr146992 	(head)->tqh_first = NULL;					\
478381a2a9aSdr146992 	(head)->tqh_last = &(head)->tqh_first;				\
479381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
480381a2a9aSdr146992 } while (0)
481381a2a9aSdr146992 
482381a2a9aSdr146992 #define	TAILQ_INSERT_HEAD(head, elm, field) do {			\
483381a2a9aSdr146992 	QUEUEDEBUG_TAILQ_INSERT_HEAD((head), (elm), field)		\
484381a2a9aSdr146992 	if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)	\
485381a2a9aSdr146992 		(head)->tqh_first->field.tqe_prev =			\
486381a2a9aSdr146992 		    &(elm)->field.tqe_next;				\
487381a2a9aSdr146992 	else								\
488381a2a9aSdr146992 		(head)->tqh_last = &(elm)->field.tqe_next;		\
489381a2a9aSdr146992 	(head)->tqh_first = (elm);					\
490381a2a9aSdr146992 	(elm)->field.tqe_prev = &(head)->tqh_first;			\
491381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
492381a2a9aSdr146992 } while (0)
493381a2a9aSdr146992 
494381a2a9aSdr146992 #define	TAILQ_INSERT_TAIL(head, elm, field) do {			\
495381a2a9aSdr146992 	QUEUEDEBUG_TAILQ_INSERT_TAIL((head), (elm), field)		\
496381a2a9aSdr146992 	(elm)->field.tqe_next = NULL;					\
497381a2a9aSdr146992 	(elm)->field.tqe_prev = (head)->tqh_last;			\
498381a2a9aSdr146992 	*(head)->tqh_last = (elm);					\
499381a2a9aSdr146992 	(head)->tqh_last = &(elm)->field.tqe_next;			\
500381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
501381a2a9aSdr146992 } while (0)
502381a2a9aSdr146992 
503381a2a9aSdr146992 #define	TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
504381a2a9aSdr146992 	QUEUEDEBUG_TAILQ_OP((listelm), field)				\
505381a2a9aSdr146992 	if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
506381a2a9aSdr146992 		(elm)->field.tqe_next->field.tqe_prev = 		\
507381a2a9aSdr146992 		    &(elm)->field.tqe_next;				\
508381a2a9aSdr146992 	else								\
509381a2a9aSdr146992 		(head)->tqh_last = &(elm)->field.tqe_next;		\
510381a2a9aSdr146992 	(listelm)->field.tqe_next = (elm);				\
511381a2a9aSdr146992 	(elm)->field.tqe_prev = &(listelm)->field.tqe_next;		\
512381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
513381a2a9aSdr146992 } while (0)
514381a2a9aSdr146992 
515381a2a9aSdr146992 #define	TAILQ_INSERT_BEFORE(listelm, elm, field) do {			\
516381a2a9aSdr146992 	QUEUEDEBUG_TAILQ_OP((listelm), field)				\
517381a2a9aSdr146992 	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
518381a2a9aSdr146992 	(elm)->field.tqe_next = (listelm);				\
519381a2a9aSdr146992 	*(listelm)->field.tqe_prev = (elm);				\
520381a2a9aSdr146992 	(listelm)->field.tqe_prev = &(elm)->field.tqe_next;		\
521381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
522381a2a9aSdr146992 } while (0)
523381a2a9aSdr146992 
524381a2a9aSdr146992 #define	TAILQ_REMOVE(head, elm, field) do {				\
525381a2a9aSdr146992 	QUEUEDEBUG_TAILQ_PREREMOVE((head), (elm), field)		\
526381a2a9aSdr146992 	QUEUEDEBUG_TAILQ_OP((elm), field)				\
527381a2a9aSdr146992 	if (((elm)->field.tqe_next) != NULL)				\
528381a2a9aSdr146992 		(elm)->field.tqe_next->field.tqe_prev = 		\
529381a2a9aSdr146992 		    (elm)->field.tqe_prev;				\
530381a2a9aSdr146992 	else								\
531381a2a9aSdr146992 		(head)->tqh_last = (elm)->field.tqe_prev;		\
532381a2a9aSdr146992 	*(elm)->field.tqe_prev = (elm)->field.tqe_next;			\
533381a2a9aSdr146992 	QUEUEDEBUG_TAILQ_POSTREMOVE((elm), field);			\
534381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
535381a2a9aSdr146992 } while (0)
536381a2a9aSdr146992 
537381a2a9aSdr146992 #define	TAILQ_FOREACH(var, head, field)					\
538381a2a9aSdr146992 	for ((var) = ((head)->tqh_first);				\
539381a2a9aSdr146992 		(var);							\
540381a2a9aSdr146992 		(var) = ((var)->field.tqe_next))
541381a2a9aSdr146992 
542381a2a9aSdr146992 #define	TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
543381a2a9aSdr146992 	for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last));\
544381a2a9aSdr146992 		(var);							\
545381a2a9aSdr146992 		(var) = 						\
546381a2a9aSdr146992 		    (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
547381a2a9aSdr146992 
548381a2a9aSdr146992 /*
549381a2a9aSdr146992  * Tail queue access methods.
550381a2a9aSdr146992  */
551381a2a9aSdr146992 #define	TAILQ_EMPTY(head)		((head)->tqh_first == NULL)
552381a2a9aSdr146992 #define	TAILQ_FIRST(head)		((head)->tqh_first)
553381a2a9aSdr146992 #define	TAILQ_NEXT(elm, field)		((elm)->field.tqe_next)
554381a2a9aSdr146992 
555381a2a9aSdr146992 #define	TAILQ_LAST(head, headname) \
556381a2a9aSdr146992 	(*(((struct headname *)((head)->tqh_last))->tqh_last))
557381a2a9aSdr146992 #define	TAILQ_PREV(elm, headname, field) \
558381a2a9aSdr146992 	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
559381a2a9aSdr146992 
560381a2a9aSdr146992 
561381a2a9aSdr146992 /*
562381a2a9aSdr146992  * Circular queue definitions.
563381a2a9aSdr146992  */
564381a2a9aSdr146992 #define	CIRCLEQ_HEAD(name, type)					\
565381a2a9aSdr146992 struct name {								\
566381a2a9aSdr146992 	struct type *cqh_first;		/* first element */	\
567381a2a9aSdr146992 	struct type *cqh_last;		/* last element */		\
568381a2a9aSdr146992 }
569381a2a9aSdr146992 
570381a2a9aSdr146992 #define	CIRCLEQ_HEAD_INITIALIZER(head)					\
571381a2a9aSdr146992 	{ (void *)&head, (void *)&head }
572381a2a9aSdr146992 
573381a2a9aSdr146992 #define	CIRCLEQ_ENTRY(type)						\
574381a2a9aSdr146992 struct {								\
575381a2a9aSdr146992 	struct type *cqe_next;		/* next element */		\
576381a2a9aSdr146992 	struct type *cqe_prev;		/* previous element */		\
577381a2a9aSdr146992 }
578381a2a9aSdr146992 
579381a2a9aSdr146992 /*
580381a2a9aSdr146992  * Circular queue functions.
581381a2a9aSdr146992  */
582381a2a9aSdr146992 #define	CIRCLEQ_INIT(head) do {						\
583381a2a9aSdr146992 	(head)->cqh_first = (void *)(head);				\
584381a2a9aSdr146992 	(head)->cqh_last = (void *)(head);				\
585381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
586381a2a9aSdr146992 } while (0)
587381a2a9aSdr146992 
588381a2a9aSdr146992 #define	CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
589381a2a9aSdr146992 	(elm)->field.cqe_next = (listelm)->field.cqe_next;		\
590381a2a9aSdr146992 	(elm)->field.cqe_prev = (listelm);				\
591381a2a9aSdr146992 	if ((listelm)->field.cqe_next == (void *)(head))		\
592381a2a9aSdr146992 		(head)->cqh_last = (elm);				\
593381a2a9aSdr146992 	else								\
594381a2a9aSdr146992 		(listelm)->field.cqe_next->field.cqe_prev = (elm);	\
595381a2a9aSdr146992 	(listelm)->field.cqe_next = (elm);				\
596381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
597381a2a9aSdr146992 } while (0)
598381a2a9aSdr146992 
599381a2a9aSdr146992 #define	CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {		\
600381a2a9aSdr146992 	(elm)->field.cqe_next = (listelm);				\
601381a2a9aSdr146992 	(elm)->field.cqe_prev = (listelm)->field.cqe_prev;		\
602381a2a9aSdr146992 	if ((listelm)->field.cqe_prev == (void *)(head))		\
603381a2a9aSdr146992 		(head)->cqh_first = (elm);				\
604381a2a9aSdr146992 	else								\
605381a2a9aSdr146992 		(listelm)->field.cqe_prev->field.cqe_next = (elm);	\
606381a2a9aSdr146992 	(listelm)->field.cqe_prev = (elm);				\
607381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
608381a2a9aSdr146992 } while (0)
609381a2a9aSdr146992 
610381a2a9aSdr146992 #define	CIRCLEQ_INSERT_HEAD(head, elm, field) do {			\
611381a2a9aSdr146992 	(elm)->field.cqe_next = (head)->cqh_first;			\
612381a2a9aSdr146992 	(elm)->field.cqe_prev = (void *)(head);				\
613381a2a9aSdr146992 	if ((head)->cqh_last == (void *)(head))			\
614381a2a9aSdr146992 		(head)->cqh_last = (elm);				\
615381a2a9aSdr146992 	else								\
616381a2a9aSdr146992 		(head)->cqh_first->field.cqe_prev = (elm);		\
617381a2a9aSdr146992 	(head)->cqh_first = (elm);					\
618381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
619381a2a9aSdr146992 } while (0)
620381a2a9aSdr146992 
621381a2a9aSdr146992 #define	CIRCLEQ_INSERT_TAIL(head, elm, field) do {			\
622381a2a9aSdr146992 	(elm)->field.cqe_next = (void *)(head);				\
623381a2a9aSdr146992 	(elm)->field.cqe_prev = (head)->cqh_last;			\
624381a2a9aSdr146992 	if ((head)->cqh_first == (void *)(head))			\
625381a2a9aSdr146992 		(head)->cqh_first = (elm);				\
626381a2a9aSdr146992 	else								\
627381a2a9aSdr146992 		(head)->cqh_last->field.cqe_next = (elm);		\
628381a2a9aSdr146992 	(head)->cqh_last = (elm);					\
629381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
630381a2a9aSdr146992 } while (0)
631381a2a9aSdr146992 
632381a2a9aSdr146992 #define	CIRCLEQ_REMOVE(head, elm, field) do {				\
633381a2a9aSdr146992 	if ((elm)->field.cqe_next == (void *)(head))			\
634381a2a9aSdr146992 		(head)->cqh_last = (elm)->field.cqe_prev;		\
635381a2a9aSdr146992 	else								\
636381a2a9aSdr146992 		(elm)->field.cqe_next->field.cqe_prev =			\
637381a2a9aSdr146992 		    (elm)->field.cqe_prev;				\
638381a2a9aSdr146992 	if ((elm)->field.cqe_prev == (void *)(head))			\
639381a2a9aSdr146992 		(head)->cqh_first = (elm)->field.cqe_next;		\
640381a2a9aSdr146992 	else								\
641381a2a9aSdr146992 		(elm)->field.cqe_prev->field.cqe_next =			\
642381a2a9aSdr146992 		    (elm)->field.cqe_next;				\
643381a2a9aSdr146992 	_NOTE(CONSTCOND)						\
644381a2a9aSdr146992 } while (0)
645381a2a9aSdr146992 
646381a2a9aSdr146992 #define	CIRCLEQ_FOREACH(var, head, field)				\
647381a2a9aSdr146992 	for ((var) = ((head)->cqh_first);				\
648381a2a9aSdr146992 		(var) != (void *)(head);				\
649381a2a9aSdr146992 		(var) = ((var)->field.cqe_next))
650381a2a9aSdr146992 
651381a2a9aSdr146992 #define	CIRCLEQ_FOREACH_REVERSE(var, head, field)			\
652381a2a9aSdr146992 	for ((var) = ((head)->cqh_last);				\
653381a2a9aSdr146992 		(var) != (void *)(head);				\
654381a2a9aSdr146992 		(var) = ((var)->field.cqe_prev))
655381a2a9aSdr146992 
656381a2a9aSdr146992 /*
657381a2a9aSdr146992  * Circular queue access methods.
658381a2a9aSdr146992  */
659381a2a9aSdr146992 #define	CIRCLEQ_EMPTY(head)		((head)->cqh_first == (void *)(head))
660381a2a9aSdr146992 #define	CIRCLEQ_FIRST(head)		((head)->cqh_first)
661381a2a9aSdr146992 #define	CIRCLEQ_LAST(head)		((head)->cqh_last)
662381a2a9aSdr146992 #define	CIRCLEQ_NEXT(elm, field)	((elm)->field.cqe_next)
663381a2a9aSdr146992 #define	CIRCLEQ_PREV(elm, field)	((elm)->field.cqe_prev)
664381a2a9aSdr146992 
665*710f7c23SDarren Reed #define	CIRCLEQ_LOOP_NEXT(head, elm, field)				\
666*710f7c23SDarren Reed 	(((elm)->field.cqe_next == (void *)(head))			\
667*710f7c23SDarren Reed 	    ? ((head)->cqh_first)					\
668*710f7c23SDarren Reed 	    : (elm->field.cqe_next))
669*710f7c23SDarren Reed #define	CIRCLEQ_LOOP_PREV(head, elm, field)				\
670*710f7c23SDarren Reed 	(((elm)->field.cqe_prev == (void *)(head))			\
671*710f7c23SDarren Reed 	    ? ((head)->cqh_last)					\
672*710f7c23SDarren Reed 	    : (elm->field.cqe_prev))
673*710f7c23SDarren Reed 
674381a2a9aSdr146992 #ifdef	__cplusplus
675381a2a9aSdr146992 }
676381a2a9aSdr146992 #endif
677381a2a9aSdr146992 
678381a2a9aSdr146992 #endif	/* !_SYS_QUEUE_H */
679