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