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