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