xref: /freebsd/crypto/krb5/src/include/k5-queue.h (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1*7f2fe78bSCy Schubert /*
2*7f2fe78bSCy Schubert  * This is a copy of NetBSD's sys/queue.h, edited to use a different symbol for
3*7f2fe78bSCy Schubert  * multiple inclusion protection and to suppress the include of <sys/null.h>.
4*7f2fe78bSCy Schubert  */
5*7f2fe78bSCy Schubert 
6*7f2fe78bSCy Schubert /*	$NetBSD: queue.h,v 1.53 2011/11/19 22:51:31 tls Exp $	*/
7*7f2fe78bSCy Schubert 
8*7f2fe78bSCy Schubert /*
9*7f2fe78bSCy Schubert  * Copyright (c) 1991, 1993
10*7f2fe78bSCy Schubert  *	The Regents of the University of California.  All rights reserved.
11*7f2fe78bSCy Schubert  *
12*7f2fe78bSCy Schubert  * Redistribution and use in source and binary forms, with or without
13*7f2fe78bSCy Schubert  * modification, are permitted provided that the following conditions
14*7f2fe78bSCy Schubert  * are met:
15*7f2fe78bSCy Schubert  * 1. Redistributions of source code must retain the above copyright
16*7f2fe78bSCy Schubert  *    notice, this list of conditions and the following disclaimer.
17*7f2fe78bSCy Schubert  * 2. Redistributions in binary form must reproduce the above copyright
18*7f2fe78bSCy Schubert  *    notice, this list of conditions and the following disclaimer in the
19*7f2fe78bSCy Schubert  *    documentation and/or other materials provided with the distribution.
20*7f2fe78bSCy Schubert  * 3. Neither the name of the University nor the names of its contributors
21*7f2fe78bSCy Schubert  *    may be used to endorse or promote products derived from this software
22*7f2fe78bSCy Schubert  *    without specific prior written permission.
23*7f2fe78bSCy Schubert  *
24*7f2fe78bSCy Schubert  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25*7f2fe78bSCy Schubert  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26*7f2fe78bSCy Schubert  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27*7f2fe78bSCy Schubert  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28*7f2fe78bSCy Schubert  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29*7f2fe78bSCy Schubert  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30*7f2fe78bSCy Schubert  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31*7f2fe78bSCy Schubert  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32*7f2fe78bSCy Schubert  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33*7f2fe78bSCy Schubert  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34*7f2fe78bSCy Schubert  * SUCH DAMAGE.
35*7f2fe78bSCy Schubert  *
36*7f2fe78bSCy Schubert  *	@(#)queue.h	8.5 (Berkeley) 8/20/94
37*7f2fe78bSCy Schubert  */
38*7f2fe78bSCy Schubert 
39*7f2fe78bSCy Schubert #ifndef	K5_QUEUE_H
40*7f2fe78bSCy Schubert #define	K5_QUEUE_H
41*7f2fe78bSCy Schubert 
42*7f2fe78bSCy Schubert /* #include <sys/null.h> */
43*7f2fe78bSCy Schubert 
44*7f2fe78bSCy Schubert /*
45*7f2fe78bSCy Schubert  * This file defines five types of data structures: singly-linked lists,
46*7f2fe78bSCy Schubert  * lists, simple queues, tail queues, and circular queues.
47*7f2fe78bSCy Schubert  *
48*7f2fe78bSCy Schubert  * A singly-linked list is headed by a single forward pointer. The
49*7f2fe78bSCy Schubert  * elements are singly linked for minimum space and pointer manipulation
50*7f2fe78bSCy Schubert  * overhead at the expense of O(n) removal for arbitrary elements. New
51*7f2fe78bSCy Schubert  * elements can be added to the list after an existing element or at the
52*7f2fe78bSCy Schubert  * head of the list.  Elements being removed from the head of the list
53*7f2fe78bSCy Schubert  * should use the explicit macro for this purpose for optimum
54*7f2fe78bSCy Schubert  * efficiency. A singly-linked list may only be traversed in the forward
55*7f2fe78bSCy Schubert  * direction.  Singly-linked lists are ideal for applications with large
56*7f2fe78bSCy Schubert  * datasets and few or no removals or for implementing a LIFO queue.
57*7f2fe78bSCy Schubert  *
58*7f2fe78bSCy Schubert  * A list is headed by a single forward pointer (or an array of forward
59*7f2fe78bSCy Schubert  * pointers for a hash table header). The elements are doubly linked
60*7f2fe78bSCy Schubert  * so that an arbitrary element can be removed without a need to
61*7f2fe78bSCy Schubert  * traverse the list. New elements can be added to the list before
62*7f2fe78bSCy Schubert  * or after an existing element or at the head of the list. A list
63*7f2fe78bSCy Schubert  * may only be traversed in the forward direction.
64*7f2fe78bSCy Schubert  *
65*7f2fe78bSCy Schubert  * A simple queue is headed by a pair of pointers, one the head of the
66*7f2fe78bSCy Schubert  * list and the other to the tail of the list. The elements are singly
67*7f2fe78bSCy Schubert  * linked to save space, so elements can only be removed from the
68*7f2fe78bSCy Schubert  * head of the list. New elements can be added to the list after
69*7f2fe78bSCy Schubert  * an existing element, at the head of the list, or at the end of the
70*7f2fe78bSCy Schubert  * list. A simple queue may only be traversed in the forward direction.
71*7f2fe78bSCy Schubert  *
72*7f2fe78bSCy Schubert  * A tail queue is headed by a pair of pointers, one to the head of the
73*7f2fe78bSCy Schubert  * list and the other to the tail of the list. The elements are doubly
74*7f2fe78bSCy Schubert  * linked so that an arbitrary element can be removed without a need to
75*7f2fe78bSCy Schubert  * traverse the list. New elements can be added to the list before or
76*7f2fe78bSCy Schubert  * after an existing element, at the head of the list, or at the end of
77*7f2fe78bSCy Schubert  * the list. A tail queue may be traversed in either direction.
78*7f2fe78bSCy Schubert  *
79*7f2fe78bSCy Schubert  * A circle queue is headed by a pair of pointers, one to the head of the
80*7f2fe78bSCy Schubert  * list and the other to the tail of the list. The elements are doubly
81*7f2fe78bSCy Schubert  * linked so that an arbitrary element can be removed without a need to
82*7f2fe78bSCy Schubert  * traverse the list. New elements can be added to the list before or after
83*7f2fe78bSCy Schubert  * an existing element, at the head of the list, or at the end of the list.
84*7f2fe78bSCy Schubert  * A circle queue may be traversed in either direction, but has a more
85*7f2fe78bSCy Schubert  * complex end of list detection.
86*7f2fe78bSCy Schubert  *
87*7f2fe78bSCy Schubert  * For details on the use of these macros, see the queue(3) manual page.
88*7f2fe78bSCy Schubert  */
89*7f2fe78bSCy Schubert 
90*7f2fe78bSCy Schubert /*
91*7f2fe78bSCy Schubert  * List definitions.
92*7f2fe78bSCy Schubert  */
93*7f2fe78bSCy Schubert #define	K5_LIST_HEAD(name, type)					\
94*7f2fe78bSCy Schubert struct name {								\
95*7f2fe78bSCy Schubert 	struct type *lh_first;	/* first element */			\
96*7f2fe78bSCy Schubert }
97*7f2fe78bSCy Schubert 
98*7f2fe78bSCy Schubert #define	K5_LIST_HEAD_INITIALIZER(head)					\
99*7f2fe78bSCy Schubert 	{ NULL }
100*7f2fe78bSCy Schubert 
101*7f2fe78bSCy Schubert #define	K5_LIST_ENTRY(type)						\
102*7f2fe78bSCy Schubert struct {								\
103*7f2fe78bSCy Schubert 	struct type *le_next;	/* next element */			\
104*7f2fe78bSCy Schubert 	struct type **le_prev;	/* address of previous next element */	\
105*7f2fe78bSCy Schubert }
106*7f2fe78bSCy Schubert 
107*7f2fe78bSCy Schubert /*
108*7f2fe78bSCy Schubert  * List functions.
109*7f2fe78bSCy Schubert  */
110*7f2fe78bSCy Schubert #define	K5_LIST_INIT(head) do {						\
111*7f2fe78bSCy Schubert 	(head)->lh_first = NULL;					\
112*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
113*7f2fe78bSCy Schubert 
114*7f2fe78bSCy Schubert #define	K5_LIST_INSERT_AFTER(listelm, elm, field) do {			\
115*7f2fe78bSCy Schubert 	if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)	\
116*7f2fe78bSCy Schubert 		(listelm)->field.le_next->field.le_prev =		\
117*7f2fe78bSCy Schubert 		    &(elm)->field.le_next;				\
118*7f2fe78bSCy Schubert 	(listelm)->field.le_next = (elm);				\
119*7f2fe78bSCy Schubert 	(elm)->field.le_prev = &(listelm)->field.le_next;		\
120*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
121*7f2fe78bSCy Schubert 
122*7f2fe78bSCy Schubert #define	K5_LIST_INSERT_BEFORE(listelm, elm, field) do {			\
123*7f2fe78bSCy Schubert 	(elm)->field.le_prev = (listelm)->field.le_prev;		\
124*7f2fe78bSCy Schubert 	(elm)->field.le_next = (listelm);				\
125*7f2fe78bSCy Schubert 	*(listelm)->field.le_prev = (elm);				\
126*7f2fe78bSCy Schubert 	(listelm)->field.le_prev = &(elm)->field.le_next;		\
127*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
128*7f2fe78bSCy Schubert 
129*7f2fe78bSCy Schubert #define	K5_LIST_INSERT_HEAD(head, elm, field) do {			\
130*7f2fe78bSCy Schubert 	if (((elm)->field.le_next = (head)->lh_first) != NULL)		\
131*7f2fe78bSCy Schubert 		(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
132*7f2fe78bSCy Schubert 	(head)->lh_first = (elm);					\
133*7f2fe78bSCy Schubert 	(elm)->field.le_prev = &(head)->lh_first;			\
134*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
135*7f2fe78bSCy Schubert 
136*7f2fe78bSCy Schubert #define	K5_LIST_REMOVE(elm, field) do {					\
137*7f2fe78bSCy Schubert 	if ((elm)->field.le_next != NULL)				\
138*7f2fe78bSCy Schubert 		(elm)->field.le_next->field.le_prev = 			\
139*7f2fe78bSCy Schubert 		    (elm)->field.le_prev;				\
140*7f2fe78bSCy Schubert 	*(elm)->field.le_prev = (elm)->field.le_next;			\
141*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
142*7f2fe78bSCy Schubert 
143*7f2fe78bSCy Schubert #define	K5_LIST_FOREACH(var, head, field)				\
144*7f2fe78bSCy Schubert 	for ((var) = ((head)->lh_first);				\
145*7f2fe78bSCy Schubert 		(var);							\
146*7f2fe78bSCy Schubert 		(var) = ((var)->field.le_next))
147*7f2fe78bSCy Schubert 
148*7f2fe78bSCy Schubert #define	K5_LIST_FOREACH_SAFE(var, head, field, tvar)			\
149*7f2fe78bSCy Schubert 	for ((var) = K5_LIST_FIRST((head));				\
150*7f2fe78bSCy Schubert 		(var) && ((tvar) = K5_LIST_NEXT((var), field), 1);	\
151*7f2fe78bSCy Schubert 		(var) = (tvar))
152*7f2fe78bSCy Schubert /*
153*7f2fe78bSCy Schubert  * List access methods.
154*7f2fe78bSCy Schubert  */
155*7f2fe78bSCy Schubert #define	K5_LIST_EMPTY(head)		((head)->lh_first == NULL)
156*7f2fe78bSCy Schubert #define	K5_LIST_FIRST(head)		((head)->lh_first)
157*7f2fe78bSCy Schubert #define	K5_LIST_NEXT(elm, field)	((elm)->field.le_next)
158*7f2fe78bSCy Schubert 
159*7f2fe78bSCy Schubert 
160*7f2fe78bSCy Schubert /*
161*7f2fe78bSCy Schubert  * Singly-linked List definitions.
162*7f2fe78bSCy Schubert  */
163*7f2fe78bSCy Schubert #define	K5_SLIST_HEAD(name, type)					\
164*7f2fe78bSCy Schubert struct name {								\
165*7f2fe78bSCy Schubert 	struct type *slh_first;	/* first element */			\
166*7f2fe78bSCy Schubert }
167*7f2fe78bSCy Schubert 
168*7f2fe78bSCy Schubert #define	K5_SLIST_HEAD_INITIALIZER(head)					\
169*7f2fe78bSCy Schubert 	{ NULL }
170*7f2fe78bSCy Schubert 
171*7f2fe78bSCy Schubert #define	K5_SLIST_ENTRY(type)						\
172*7f2fe78bSCy Schubert struct {								\
173*7f2fe78bSCy Schubert 	struct type *sle_next;	/* next element */			\
174*7f2fe78bSCy Schubert }
175*7f2fe78bSCy Schubert 
176*7f2fe78bSCy Schubert /*
177*7f2fe78bSCy Schubert  * Singly-linked List functions.
178*7f2fe78bSCy Schubert  */
179*7f2fe78bSCy Schubert #define	K5_SLIST_INIT(head) do {					\
180*7f2fe78bSCy Schubert 	(head)->slh_first = NULL;					\
181*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
182*7f2fe78bSCy Schubert 
183*7f2fe78bSCy Schubert #define	K5_SLIST_INSERT_AFTER(slistelm, elm, field) do {		\
184*7f2fe78bSCy Schubert 	(elm)->field.sle_next = (slistelm)->field.sle_next;		\
185*7f2fe78bSCy Schubert 	(slistelm)->field.sle_next = (elm);				\
186*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
187*7f2fe78bSCy Schubert 
188*7f2fe78bSCy Schubert #define	K5_SLIST_INSERT_HEAD(head, elm, field) do {			\
189*7f2fe78bSCy Schubert 	(elm)->field.sle_next = (head)->slh_first;			\
190*7f2fe78bSCy Schubert 	(head)->slh_first = (elm);					\
191*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
192*7f2fe78bSCy Schubert 
193*7f2fe78bSCy Schubert #define	K5_SLIST_REMOVE_HEAD(head, field) do {				\
194*7f2fe78bSCy Schubert 	(head)->slh_first = (head)->slh_first->field.sle_next;		\
195*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
196*7f2fe78bSCy Schubert 
197*7f2fe78bSCy Schubert #define	K5_SLIST_REMOVE(head, elm, type, field) do {			\
198*7f2fe78bSCy Schubert 	if ((head)->slh_first == (elm)) {				\
199*7f2fe78bSCy Schubert 		K5_SLIST_REMOVE_HEAD((head), field);			\
200*7f2fe78bSCy Schubert 	}								\
201*7f2fe78bSCy Schubert 	else {								\
202*7f2fe78bSCy Schubert 		struct type *curelm = (head)->slh_first;		\
203*7f2fe78bSCy Schubert 		while(curelm->field.sle_next != (elm))			\
204*7f2fe78bSCy Schubert 			curelm = curelm->field.sle_next;		\
205*7f2fe78bSCy Schubert 		curelm->field.sle_next =				\
206*7f2fe78bSCy Schubert 		    curelm->field.sle_next->field.sle_next;		\
207*7f2fe78bSCy Schubert 	}								\
208*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
209*7f2fe78bSCy Schubert 
210*7f2fe78bSCy Schubert #define	K5_SLIST_REMOVE_AFTER(slistelm, field) do {			\
211*7f2fe78bSCy Schubert 	(slistelm)->field.sle_next =					\
212*7f2fe78bSCy Schubert 	    K5_SLIST_NEXT(K5_SLIST_NEXT((slistelm), field), field);	\
213*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
214*7f2fe78bSCy Schubert 
215*7f2fe78bSCy Schubert #define	K5_SLIST_FOREACH(var, head, field)				\
216*7f2fe78bSCy Schubert 	for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
217*7f2fe78bSCy Schubert 
218*7f2fe78bSCy Schubert #define	K5_SLIST_FOREACH_SAFE(var, head, field, tvar)			\
219*7f2fe78bSCy Schubert 	for ((var) = K5_SLIST_FIRST((head));				\
220*7f2fe78bSCy Schubert 	    (var) && ((tvar) = K5_SLIST_NEXT((var), field), 1);		\
221*7f2fe78bSCy Schubert 	    (var) = (tvar))
222*7f2fe78bSCy Schubert 
223*7f2fe78bSCy Schubert /*
224*7f2fe78bSCy Schubert  * Singly-linked List access methods.
225*7f2fe78bSCy Schubert  */
226*7f2fe78bSCy Schubert #define	K5_SLIST_EMPTY(head)	((head)->slh_first == NULL)
227*7f2fe78bSCy Schubert #define	K5_SLIST_FIRST(head)	((head)->slh_first)
228*7f2fe78bSCy Schubert #define	K5_SLIST_NEXT(elm, field)	((elm)->field.sle_next)
229*7f2fe78bSCy Schubert 
230*7f2fe78bSCy Schubert 
231*7f2fe78bSCy Schubert /*
232*7f2fe78bSCy Schubert  * Singly-linked Tail queue declarations.
233*7f2fe78bSCy Schubert  */
234*7f2fe78bSCy Schubert #define	K5_STAILQ_HEAD(name, type)					\
235*7f2fe78bSCy Schubert struct name {								\
236*7f2fe78bSCy Schubert 	struct type *stqh_first;	/* first element */			\
237*7f2fe78bSCy Schubert 	struct type **stqh_last;	/* addr of last next element */		\
238*7f2fe78bSCy Schubert }
239*7f2fe78bSCy Schubert 
240*7f2fe78bSCy Schubert #define	K5_STAILQ_HEAD_INITIALIZER(head)				\
241*7f2fe78bSCy Schubert 	{ NULL, &(head).stqh_first }
242*7f2fe78bSCy Schubert 
243*7f2fe78bSCy Schubert #define	K5_STAILQ_ENTRY(type)						\
244*7f2fe78bSCy Schubert struct {								\
245*7f2fe78bSCy Schubert 	struct type *stqe_next;	/* next element */			\
246*7f2fe78bSCy Schubert }
247*7f2fe78bSCy Schubert 
248*7f2fe78bSCy Schubert /*
249*7f2fe78bSCy Schubert  * Singly-linked Tail queue functions.
250*7f2fe78bSCy Schubert  */
251*7f2fe78bSCy Schubert #define	K5_STAILQ_INIT(head) do {					\
252*7f2fe78bSCy Schubert 	(head)->stqh_first = NULL;					\
253*7f2fe78bSCy Schubert 	(head)->stqh_last = &(head)->stqh_first;				\
254*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
255*7f2fe78bSCy Schubert 
256*7f2fe78bSCy Schubert #define	K5_STAILQ_INSERT_HEAD(head, elm, field) do {			\
257*7f2fe78bSCy Schubert 	if (((elm)->field.stqe_next = (head)->stqh_first) == NULL)	\
258*7f2fe78bSCy Schubert 		(head)->stqh_last = &(elm)->field.stqe_next;		\
259*7f2fe78bSCy Schubert 	(head)->stqh_first = (elm);					\
260*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
261*7f2fe78bSCy Schubert 
262*7f2fe78bSCy Schubert #define	K5_STAILQ_INSERT_TAIL(head, elm, field) do {			\
263*7f2fe78bSCy Schubert 	(elm)->field.stqe_next = NULL;					\
264*7f2fe78bSCy Schubert 	*(head)->stqh_last = (elm);					\
265*7f2fe78bSCy Schubert 	(head)->stqh_last = &(elm)->field.stqe_next;			\
266*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
267*7f2fe78bSCy Schubert 
268*7f2fe78bSCy Schubert #define	K5_STAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
269*7f2fe78bSCy Schubert 	if (((elm)->field.stqe_next = (listelm)->field.stqe_next) == NULL)\
270*7f2fe78bSCy Schubert 		(head)->stqh_last = &(elm)->field.stqe_next;		\
271*7f2fe78bSCy Schubert 	(listelm)->field.stqe_next = (elm);				\
272*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
273*7f2fe78bSCy Schubert 
274*7f2fe78bSCy Schubert #define	K5_STAILQ_REMOVE_HEAD(head, field) do {				\
275*7f2fe78bSCy Schubert 	if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == NULL) \
276*7f2fe78bSCy Schubert 		(head)->stqh_last = &(head)->stqh_first;			\
277*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
278*7f2fe78bSCy Schubert 
279*7f2fe78bSCy Schubert #define	K5_STAILQ_REMOVE(head, elm, type, field) do {			\
280*7f2fe78bSCy Schubert 	if ((head)->stqh_first == (elm)) {				\
281*7f2fe78bSCy Schubert 		K5_STAILQ_REMOVE_HEAD((head), field);			\
282*7f2fe78bSCy Schubert 	} else {							\
283*7f2fe78bSCy Schubert 		struct type *curelm = (head)->stqh_first;		\
284*7f2fe78bSCy Schubert 		while (curelm->field.stqe_next != (elm))		\
285*7f2fe78bSCy Schubert 			curelm = curelm->field.stqe_next;		\
286*7f2fe78bSCy Schubert 		if ((curelm->field.stqe_next =				\
287*7f2fe78bSCy Schubert 			curelm->field.stqe_next->field.stqe_next) == NULL) \
288*7f2fe78bSCy Schubert 			    (head)->stqh_last = &(curelm)->field.stqe_next; \
289*7f2fe78bSCy Schubert 	}								\
290*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
291*7f2fe78bSCy Schubert 
292*7f2fe78bSCy Schubert #define	K5_STAILQ_FOREACH(var, head, field)				\
293*7f2fe78bSCy Schubert 	for ((var) = ((head)->stqh_first);				\
294*7f2fe78bSCy Schubert 		(var);							\
295*7f2fe78bSCy Schubert 		(var) = ((var)->field.stqe_next))
296*7f2fe78bSCy Schubert 
297*7f2fe78bSCy Schubert #define	K5_STAILQ_FOREACH_SAFE(var, head, field, tvar)			\
298*7f2fe78bSCy Schubert 	for ((var) = K5_STAILQ_FIRST((head));				\
299*7f2fe78bSCy Schubert 	    (var) && ((tvar) = K5_STAILQ_NEXT((var), field), 1);	\
300*7f2fe78bSCy Schubert 	    (var) = (tvar))
301*7f2fe78bSCy Schubert 
302*7f2fe78bSCy Schubert #define	K5_STAILQ_CONCAT(head1, head2) do {				\
303*7f2fe78bSCy Schubert 	if (!K5_STAILQ_EMPTY((head2))) {				\
304*7f2fe78bSCy Schubert 		*(head1)->stqh_last = (head2)->stqh_first;		\
305*7f2fe78bSCy Schubert 		(head1)->stqh_last = (head2)->stqh_last;		\
306*7f2fe78bSCy Schubert 		K5_STAILQ_INIT((head2));				\
307*7f2fe78bSCy Schubert 	}								\
308*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
309*7f2fe78bSCy Schubert 
310*7f2fe78bSCy Schubert #define	K5_STAILQ_LAST(head, type, field)				\
311*7f2fe78bSCy Schubert 	(K5_STAILQ_EMPTY((head)) ?					\
312*7f2fe78bSCy Schubert 		NULL :							\
313*7f2fe78bSCy Schubert 	        ((struct type *)(void *)				\
314*7f2fe78bSCy Schubert 		((char *)((head)->stqh_last) - offsetof(struct type, field))))
315*7f2fe78bSCy Schubert 
316*7f2fe78bSCy Schubert /*
317*7f2fe78bSCy Schubert  * Singly-linked Tail queue access methods.
318*7f2fe78bSCy Schubert  */
319*7f2fe78bSCy Schubert #define	K5_STAILQ_EMPTY(head)	((head)->stqh_first == NULL)
320*7f2fe78bSCy Schubert #define	K5_STAILQ_FIRST(head)	((head)->stqh_first)
321*7f2fe78bSCy Schubert #define	K5_STAILQ_NEXT(elm, field)	((elm)->field.stqe_next)
322*7f2fe78bSCy Schubert 
323*7f2fe78bSCy Schubert 
324*7f2fe78bSCy Schubert /*
325*7f2fe78bSCy Schubert  * Simple queue definitions.
326*7f2fe78bSCy Schubert  */
327*7f2fe78bSCy Schubert #define	K5_SIMPLEQ_HEAD(name, type)					\
328*7f2fe78bSCy Schubert struct name {								\
329*7f2fe78bSCy Schubert 	struct type *sqh_first;	/* first element */			\
330*7f2fe78bSCy Schubert 	struct type **sqh_last;	/* addr of last next element */		\
331*7f2fe78bSCy Schubert }
332*7f2fe78bSCy Schubert 
333*7f2fe78bSCy Schubert #define	K5_SIMPLEQ_HEAD_INITIALIZER(head)				\
334*7f2fe78bSCy Schubert 	{ NULL, &(head).sqh_first }
335*7f2fe78bSCy Schubert 
336*7f2fe78bSCy Schubert #define	K5_SIMPLEQ_ENTRY(type)						\
337*7f2fe78bSCy Schubert struct {								\
338*7f2fe78bSCy Schubert 	struct type *sqe_next;	/* next element */			\
339*7f2fe78bSCy Schubert }
340*7f2fe78bSCy Schubert 
341*7f2fe78bSCy Schubert /*
342*7f2fe78bSCy Schubert  * Simple queue functions.
343*7f2fe78bSCy Schubert  */
344*7f2fe78bSCy Schubert #define	K5_SIMPLEQ_INIT(head) do {					\
345*7f2fe78bSCy Schubert 	(head)->sqh_first = NULL;					\
346*7f2fe78bSCy Schubert 	(head)->sqh_last = &(head)->sqh_first;				\
347*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
348*7f2fe78bSCy Schubert 
349*7f2fe78bSCy Schubert #define	K5_SIMPLEQ_INSERT_HEAD(head, elm, field) do {			\
350*7f2fe78bSCy Schubert 	if (((elm)->field.sqe_next = (head)->sqh_first) == NULL)	\
351*7f2fe78bSCy Schubert 		(head)->sqh_last = &(elm)->field.sqe_next;		\
352*7f2fe78bSCy Schubert 	(head)->sqh_first = (elm);					\
353*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
354*7f2fe78bSCy Schubert 
355*7f2fe78bSCy Schubert #define	K5_SIMPLEQ_INSERT_TAIL(head, elm, field) do {			\
356*7f2fe78bSCy Schubert 	(elm)->field.sqe_next = NULL;					\
357*7f2fe78bSCy Schubert 	*(head)->sqh_last = (elm);					\
358*7f2fe78bSCy Schubert 	(head)->sqh_last = &(elm)->field.sqe_next;			\
359*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
360*7f2fe78bSCy Schubert 
361*7f2fe78bSCy Schubert #define	K5_SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
362*7f2fe78bSCy Schubert 	if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
363*7f2fe78bSCy Schubert 		(head)->sqh_last = &(elm)->field.sqe_next;		\
364*7f2fe78bSCy Schubert 	(listelm)->field.sqe_next = (elm);				\
365*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
366*7f2fe78bSCy Schubert 
367*7f2fe78bSCy Schubert #define	K5_SIMPLEQ_REMOVE_HEAD(head, field) do {			\
368*7f2fe78bSCy Schubert 	if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
369*7f2fe78bSCy Schubert 		(head)->sqh_last = &(head)->sqh_first;			\
370*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
371*7f2fe78bSCy Schubert 
372*7f2fe78bSCy Schubert #define	K5_SIMPLEQ_REMOVE(head, elm, type, field) do {			\
373*7f2fe78bSCy Schubert 	if ((head)->sqh_first == (elm)) {				\
374*7f2fe78bSCy Schubert 		K5_SIMPLEQ_REMOVE_HEAD((head), field);			\
375*7f2fe78bSCy Schubert 	} else {							\
376*7f2fe78bSCy Schubert 		struct type *curelm = (head)->sqh_first;		\
377*7f2fe78bSCy Schubert 		while (curelm->field.sqe_next != (elm))			\
378*7f2fe78bSCy Schubert 			curelm = curelm->field.sqe_next;		\
379*7f2fe78bSCy Schubert 		if ((curelm->field.sqe_next =				\
380*7f2fe78bSCy Schubert 			curelm->field.sqe_next->field.sqe_next) == NULL) \
381*7f2fe78bSCy Schubert 			    (head)->sqh_last = &(curelm)->field.sqe_next; \
382*7f2fe78bSCy Schubert 	}								\
383*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
384*7f2fe78bSCy Schubert 
385*7f2fe78bSCy Schubert #define	K5_SIMPLEQ_FOREACH(var, head, field)				\
386*7f2fe78bSCy Schubert 	for ((var) = ((head)->sqh_first);				\
387*7f2fe78bSCy Schubert 		(var);							\
388*7f2fe78bSCy Schubert 		(var) = ((var)->field.sqe_next))
389*7f2fe78bSCy Schubert 
390*7f2fe78bSCy Schubert #define	K5_SIMPLEQ_FOREACH_SAFE(var, head, field, next)			\
391*7f2fe78bSCy Schubert 	for ((var) = ((head)->sqh_first);				\
392*7f2fe78bSCy Schubert 		(var) && ((next = ((var)->field.sqe_next)), 1);		\
393*7f2fe78bSCy Schubert 		(var) = (next))
394*7f2fe78bSCy Schubert 
395*7f2fe78bSCy Schubert #define	K5_SIMPLEQ_CONCAT(head1, head2) do {				\
396*7f2fe78bSCy Schubert 	if (!K5_SIMPLEQ_EMPTY((head2))) {				\
397*7f2fe78bSCy Schubert 		*(head1)->sqh_last = (head2)->sqh_first;		\
398*7f2fe78bSCy Schubert 		(head1)->sqh_last = (head2)->sqh_last;		\
399*7f2fe78bSCy Schubert 		K5_SIMPLEQ_INIT((head2));				\
400*7f2fe78bSCy Schubert 	}								\
401*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
402*7f2fe78bSCy Schubert 
403*7f2fe78bSCy Schubert #define	K5_SIMPLEQ_LAST(head, type, field)				\
404*7f2fe78bSCy Schubert 	(K5_SIMPLEQ_EMPTY((head)) ?					\
405*7f2fe78bSCy Schubert 		NULL :							\
406*7f2fe78bSCy Schubert 	        ((struct type *)(void *)				\
407*7f2fe78bSCy Schubert 		((char *)((head)->sqh_last) - offsetof(struct type, field))))
408*7f2fe78bSCy Schubert 
409*7f2fe78bSCy Schubert /*
410*7f2fe78bSCy Schubert  * Simple queue access methods.
411*7f2fe78bSCy Schubert  */
412*7f2fe78bSCy Schubert #define	K5_SIMPLEQ_EMPTY(head)		((head)->sqh_first == NULL)
413*7f2fe78bSCy Schubert #define	K5_SIMPLEQ_FIRST(head)		((head)->sqh_first)
414*7f2fe78bSCy Schubert #define	K5_SIMPLEQ_NEXT(elm, field)	((elm)->field.sqe_next)
415*7f2fe78bSCy Schubert 
416*7f2fe78bSCy Schubert 
417*7f2fe78bSCy Schubert /*
418*7f2fe78bSCy Schubert  * Tail queue definitions.
419*7f2fe78bSCy Schubert  */
420*7f2fe78bSCy Schubert #define	_K5_TAILQ_HEAD(name, type, qual)				\
421*7f2fe78bSCy Schubert struct name {								\
422*7f2fe78bSCy Schubert 	qual type *tqh_first;		/* first element */		\
423*7f2fe78bSCy Schubert 	qual type *qual *tqh_last;	/* addr of last next element */	\
424*7f2fe78bSCy Schubert }
425*7f2fe78bSCy Schubert #define K5_TAILQ_HEAD(name, type)	_K5_TAILQ_HEAD(name, struct type,)
426*7f2fe78bSCy Schubert 
427*7f2fe78bSCy Schubert #define	K5_TAILQ_HEAD_INITIALIZER(head)					\
428*7f2fe78bSCy Schubert 	{ NULL, &(head).tqh_first }
429*7f2fe78bSCy Schubert 
430*7f2fe78bSCy Schubert #define	_K5_TAILQ_ENTRY(type, qual)					\
431*7f2fe78bSCy Schubert struct {								\
432*7f2fe78bSCy Schubert 	qual type *tqe_next;		/* next element */		\
433*7f2fe78bSCy Schubert 	qual type *qual *tqe_prev;	/* address of previous next element */\
434*7f2fe78bSCy Schubert }
435*7f2fe78bSCy Schubert #define K5_TAILQ_ENTRY(type)	_K5_TAILQ_ENTRY(struct type,)
436*7f2fe78bSCy Schubert 
437*7f2fe78bSCy Schubert /*
438*7f2fe78bSCy Schubert  * Tail queue functions.
439*7f2fe78bSCy Schubert  */
440*7f2fe78bSCy Schubert #define	K5_TAILQ_INIT(head) do {					\
441*7f2fe78bSCy Schubert 	(head)->tqh_first = NULL;					\
442*7f2fe78bSCy Schubert 	(head)->tqh_last = &(head)->tqh_first;				\
443*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
444*7f2fe78bSCy Schubert 
445*7f2fe78bSCy Schubert #define	K5_TAILQ_INSERT_HEAD(head, elm, field) do {			\
446*7f2fe78bSCy Schubert 	if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)	\
447*7f2fe78bSCy Schubert 		(head)->tqh_first->field.tqe_prev =			\
448*7f2fe78bSCy Schubert 		    &(elm)->field.tqe_next;				\
449*7f2fe78bSCy Schubert 	else								\
450*7f2fe78bSCy Schubert 		(head)->tqh_last = &(elm)->field.tqe_next;		\
451*7f2fe78bSCy Schubert 	(head)->tqh_first = (elm);					\
452*7f2fe78bSCy Schubert 	(elm)->field.tqe_prev = &(head)->tqh_first;			\
453*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
454*7f2fe78bSCy Schubert 
455*7f2fe78bSCy Schubert #define	K5_TAILQ_INSERT_TAIL(head, elm, field) do {			\
456*7f2fe78bSCy Schubert 	(elm)->field.tqe_next = NULL;					\
457*7f2fe78bSCy Schubert 	(elm)->field.tqe_prev = (head)->tqh_last;			\
458*7f2fe78bSCy Schubert 	*(head)->tqh_last = (elm);					\
459*7f2fe78bSCy Schubert 	(head)->tqh_last = &(elm)->field.tqe_next;			\
460*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
461*7f2fe78bSCy Schubert 
462*7f2fe78bSCy Schubert #define	K5_TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
463*7f2fe78bSCy Schubert 	if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
464*7f2fe78bSCy Schubert 		(elm)->field.tqe_next->field.tqe_prev = 		\
465*7f2fe78bSCy Schubert 		    &(elm)->field.tqe_next;				\
466*7f2fe78bSCy Schubert 	else								\
467*7f2fe78bSCy Schubert 		(head)->tqh_last = &(elm)->field.tqe_next;		\
468*7f2fe78bSCy Schubert 	(listelm)->field.tqe_next = (elm);				\
469*7f2fe78bSCy Schubert 	(elm)->field.tqe_prev = &(listelm)->field.tqe_next;		\
470*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
471*7f2fe78bSCy Schubert 
472*7f2fe78bSCy Schubert #define	K5_TAILQ_INSERT_BEFORE(listelm, elm, field) do {		\
473*7f2fe78bSCy Schubert 	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
474*7f2fe78bSCy Schubert 	(elm)->field.tqe_next = (listelm);				\
475*7f2fe78bSCy Schubert 	*(listelm)->field.tqe_prev = (elm);				\
476*7f2fe78bSCy Schubert 	(listelm)->field.tqe_prev = &(elm)->field.tqe_next;		\
477*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
478*7f2fe78bSCy Schubert 
479*7f2fe78bSCy Schubert #define	K5_TAILQ_REMOVE(head, elm, field) do {				\
480*7f2fe78bSCy Schubert 	if (((elm)->field.tqe_next) != NULL)				\
481*7f2fe78bSCy Schubert 		(elm)->field.tqe_next->field.tqe_prev = 		\
482*7f2fe78bSCy Schubert 		    (elm)->field.tqe_prev;				\
483*7f2fe78bSCy Schubert 	else								\
484*7f2fe78bSCy Schubert 		(head)->tqh_last = (elm)->field.tqe_prev;		\
485*7f2fe78bSCy Schubert 	*(elm)->field.tqe_prev = (elm)->field.tqe_next;			\
486*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
487*7f2fe78bSCy Schubert 
488*7f2fe78bSCy Schubert #define	K5_TAILQ_FOREACH(var, head, field)				\
489*7f2fe78bSCy Schubert 	for ((var) = ((head)->tqh_first);				\
490*7f2fe78bSCy Schubert 		(var);							\
491*7f2fe78bSCy Schubert 		(var) = ((var)->field.tqe_next))
492*7f2fe78bSCy Schubert 
493*7f2fe78bSCy Schubert #define	K5_TAILQ_FOREACH_SAFE(var, head, field, next)			\
494*7f2fe78bSCy Schubert 	for ((var) = ((head)->tqh_first);				\
495*7f2fe78bSCy Schubert 	        (var) != NULL && ((next) = K5_TAILQ_NEXT(var, field), 1);	\
496*7f2fe78bSCy Schubert 		(var) = (next))
497*7f2fe78bSCy Schubert 
498*7f2fe78bSCy Schubert #define	K5_TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
499*7f2fe78bSCy Schubert 	for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last));	\
500*7f2fe78bSCy Schubert 		(var);							\
501*7f2fe78bSCy Schubert 		(var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
502*7f2fe78bSCy Schubert 
503*7f2fe78bSCy Schubert #define	K5_TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, prev)	\
504*7f2fe78bSCy Schubert 	for ((var) = K5_TAILQ_LAST((head), headname);			\
505*7f2fe78bSCy Schubert 		(var) && ((prev) = K5_TAILQ_PREV((var), headname, field), 1);\
506*7f2fe78bSCy Schubert 		(var) = (prev))
507*7f2fe78bSCy Schubert 
508*7f2fe78bSCy Schubert #define	K5_TAILQ_CONCAT(head1, head2, field) do {			\
509*7f2fe78bSCy Schubert 	if (!K5_TAILQ_EMPTY(head2)) {					\
510*7f2fe78bSCy Schubert 		*(head1)->tqh_last = (head2)->tqh_first;		\
511*7f2fe78bSCy Schubert 		(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last;	\
512*7f2fe78bSCy Schubert 		(head1)->tqh_last = (head2)->tqh_last;			\
513*7f2fe78bSCy Schubert 		K5_TAILQ_INIT((head2));					\
514*7f2fe78bSCy Schubert 	}								\
515*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
516*7f2fe78bSCy Schubert 
517*7f2fe78bSCy Schubert /*
518*7f2fe78bSCy Schubert  * Tail queue access methods.
519*7f2fe78bSCy Schubert  */
520*7f2fe78bSCy Schubert #define	K5_TAILQ_EMPTY(head)		((head)->tqh_first == NULL)
521*7f2fe78bSCy Schubert #define	K5_TAILQ_FIRST(head)		((head)->tqh_first)
522*7f2fe78bSCy Schubert #define	K5_TAILQ_NEXT(elm, field)	((elm)->field.tqe_next)
523*7f2fe78bSCy Schubert 
524*7f2fe78bSCy Schubert #define	K5_TAILQ_LAST(head, headname) \
525*7f2fe78bSCy Schubert 	(*(((struct headname *)((head)->tqh_last))->tqh_last))
526*7f2fe78bSCy Schubert #define	K5_TAILQ_PREV(elm, headname, field) \
527*7f2fe78bSCy Schubert 	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
528*7f2fe78bSCy Schubert 
529*7f2fe78bSCy Schubert 
530*7f2fe78bSCy Schubert /*
531*7f2fe78bSCy Schubert  * Circular queue definitions.
532*7f2fe78bSCy Schubert  */
533*7f2fe78bSCy Schubert #define	K5_CIRCLEQ_HEAD(name, type)					\
534*7f2fe78bSCy Schubert struct name {								\
535*7f2fe78bSCy Schubert 	struct type *cqh_first;		/* first element */		\
536*7f2fe78bSCy Schubert 	struct type *cqh_last;		/* last element */		\
537*7f2fe78bSCy Schubert }
538*7f2fe78bSCy Schubert 
539*7f2fe78bSCy Schubert #define	K5_CIRCLEQ_HEAD_INITIALIZER(head)				\
540*7f2fe78bSCy Schubert 	{ (void *)&head, (void *)&head }
541*7f2fe78bSCy Schubert 
542*7f2fe78bSCy Schubert #define	K5_CIRCLEQ_ENTRY(type)						\
543*7f2fe78bSCy Schubert struct {								\
544*7f2fe78bSCy Schubert 	struct type *cqe_next;		/* next element */		\
545*7f2fe78bSCy Schubert 	struct type *cqe_prev;		/* previous element */		\
546*7f2fe78bSCy Schubert }
547*7f2fe78bSCy Schubert 
548*7f2fe78bSCy Schubert /*
549*7f2fe78bSCy Schubert  * Circular queue functions.
550*7f2fe78bSCy Schubert  */
551*7f2fe78bSCy Schubert #define	K5_CIRCLEQ_INIT(head) do {					\
552*7f2fe78bSCy Schubert 	(head)->cqh_first = (void *)(head);				\
553*7f2fe78bSCy Schubert 	(head)->cqh_last = (void *)(head);				\
554*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
555*7f2fe78bSCy Schubert 
556*7f2fe78bSCy Schubert #define	K5_CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
557*7f2fe78bSCy Schubert 	(elm)->field.cqe_next = (listelm)->field.cqe_next;		\
558*7f2fe78bSCy Schubert 	(elm)->field.cqe_prev = (listelm);				\
559*7f2fe78bSCy Schubert 	if ((listelm)->field.cqe_next == (void *)(head))		\
560*7f2fe78bSCy Schubert 		(head)->cqh_last = (elm);				\
561*7f2fe78bSCy Schubert 	else								\
562*7f2fe78bSCy Schubert 		(listelm)->field.cqe_next->field.cqe_prev = (elm);	\
563*7f2fe78bSCy Schubert 	(listelm)->field.cqe_next = (elm);				\
564*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
565*7f2fe78bSCy Schubert 
566*7f2fe78bSCy Schubert #define	K5_CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {	\
567*7f2fe78bSCy Schubert 	(elm)->field.cqe_next = (listelm);				\
568*7f2fe78bSCy Schubert 	(elm)->field.cqe_prev = (listelm)->field.cqe_prev;		\
569*7f2fe78bSCy Schubert 	if ((listelm)->field.cqe_prev == (void *)(head))		\
570*7f2fe78bSCy Schubert 		(head)->cqh_first = (elm);				\
571*7f2fe78bSCy Schubert 	else								\
572*7f2fe78bSCy Schubert 		(listelm)->field.cqe_prev->field.cqe_next = (elm);	\
573*7f2fe78bSCy Schubert 	(listelm)->field.cqe_prev = (elm);				\
574*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
575*7f2fe78bSCy Schubert 
576*7f2fe78bSCy Schubert #define	K5_CIRCLEQ_INSERT_HEAD(head, elm, field) do {			\
577*7f2fe78bSCy Schubert 	(elm)->field.cqe_next = (head)->cqh_first;			\
578*7f2fe78bSCy Schubert 	(elm)->field.cqe_prev = (void *)(head);				\
579*7f2fe78bSCy Schubert 	if ((head)->cqh_last == (void *)(head))				\
580*7f2fe78bSCy Schubert 		(head)->cqh_last = (elm);				\
581*7f2fe78bSCy Schubert 	else								\
582*7f2fe78bSCy Schubert 		(head)->cqh_first->field.cqe_prev = (elm);		\
583*7f2fe78bSCy Schubert 	(head)->cqh_first = (elm);					\
584*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
585*7f2fe78bSCy Schubert 
586*7f2fe78bSCy Schubert #define	K5_CIRCLEQ_INSERT_TAIL(head, elm, field) do {			\
587*7f2fe78bSCy Schubert 	(elm)->field.cqe_next = (void *)(head);				\
588*7f2fe78bSCy Schubert 	(elm)->field.cqe_prev = (head)->cqh_last;			\
589*7f2fe78bSCy Schubert 	if ((head)->cqh_first == (void *)(head))			\
590*7f2fe78bSCy Schubert 		(head)->cqh_first = (elm);				\
591*7f2fe78bSCy Schubert 	else								\
592*7f2fe78bSCy Schubert 		(head)->cqh_last->field.cqe_next = (elm);		\
593*7f2fe78bSCy Schubert 	(head)->cqh_last = (elm);					\
594*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
595*7f2fe78bSCy Schubert 
596*7f2fe78bSCy Schubert #define	K5_CIRCLEQ_REMOVE(head, elm, field) do {			\
597*7f2fe78bSCy Schubert 	if ((elm)->field.cqe_next == (void *)(head))			\
598*7f2fe78bSCy Schubert 		(head)->cqh_last = (elm)->field.cqe_prev;		\
599*7f2fe78bSCy Schubert 	else								\
600*7f2fe78bSCy Schubert 		(elm)->field.cqe_next->field.cqe_prev =			\
601*7f2fe78bSCy Schubert 		    (elm)->field.cqe_prev;				\
602*7f2fe78bSCy Schubert 	if ((elm)->field.cqe_prev == (void *)(head))			\
603*7f2fe78bSCy Schubert 		(head)->cqh_first = (elm)->field.cqe_next;		\
604*7f2fe78bSCy Schubert 	else								\
605*7f2fe78bSCy Schubert 		(elm)->field.cqe_prev->field.cqe_next =			\
606*7f2fe78bSCy Schubert 		    (elm)->field.cqe_next;				\
607*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0)
608*7f2fe78bSCy Schubert 
609*7f2fe78bSCy Schubert #define	K5_CIRCLEQ_FOREACH(var, head, field)				\
610*7f2fe78bSCy Schubert 	for ((var) = ((head)->cqh_first);				\
611*7f2fe78bSCy Schubert 		(var) != (const void *)(head);				\
612*7f2fe78bSCy Schubert 		(var) = ((var)->field.cqe_next))
613*7f2fe78bSCy Schubert 
614*7f2fe78bSCy Schubert #define	K5_CIRCLEQ_FOREACH_REVERSE(var, head, field)			\
615*7f2fe78bSCy Schubert 	for ((var) = ((head)->cqh_last);				\
616*7f2fe78bSCy Schubert 		(var) != (const void *)(head);				\
617*7f2fe78bSCy Schubert 		(var) = ((var)->field.cqe_prev))
618*7f2fe78bSCy Schubert 
619*7f2fe78bSCy Schubert /*
620*7f2fe78bSCy Schubert  * Circular queue access methods.
621*7f2fe78bSCy Schubert  */
622*7f2fe78bSCy Schubert #define	K5_CIRCLEQ_EMPTY(head)		((head)->cqh_first == (void *)(head))
623*7f2fe78bSCy Schubert #define	K5_CIRCLEQ_FIRST(head)		((head)->cqh_first)
624*7f2fe78bSCy Schubert #define	K5_CIRCLEQ_LAST(head)		((head)->cqh_last)
625*7f2fe78bSCy Schubert #define	K5_CIRCLEQ_NEXT(elm, field)	((elm)->field.cqe_next)
626*7f2fe78bSCy Schubert #define	K5_CIRCLEQ_PREV(elm, field)	((elm)->field.cqe_prev)
627*7f2fe78bSCy Schubert 
628*7f2fe78bSCy Schubert #define K5_CIRCLEQ_LOOP_NEXT(head, elm, field)				\
629*7f2fe78bSCy Schubert 	(((elm)->field.cqe_next == (void *)(head))			\
630*7f2fe78bSCy Schubert 	    ? ((head)->cqh_first)					\
631*7f2fe78bSCy Schubert 	    : (elm->field.cqe_next))
632*7f2fe78bSCy Schubert #define K5_CIRCLEQ_LOOP_PREV(head, elm, field)				\
633*7f2fe78bSCy Schubert 	(((elm)->field.cqe_prev == (void *)(head))			\
634*7f2fe78bSCy Schubert 	    ? ((head)->cqh_last)					\
635*7f2fe78bSCy Schubert 	    : (elm->field.cqe_prev))
636*7f2fe78bSCy Schubert 
637*7f2fe78bSCy Schubert #endif	/* !K5_QUEUE_H */
638