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