1/*-
  2 * SPDX-License-Identifier: BSD-3-Clause
  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#include <sys/cdefs.h>
 38
 39/*
 40 * This file defines four types of data structures: singly-linked lists,
 41 * singly-linked tail queues, lists and tail queues.
 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 singly-linked tail queue is headed by a pair of pointers, one to the
 54 * head of the list and the other to the tail of the list. The elements are
 55 * singly linked for minimum space and pointer manipulation overhead at the
 56 * expense of O(n) removal for arbitrary elements. New elements can be added
 57 * to the list after an existing element, at the head of the list, or at the
 58 * end of the list. Elements being removed from the head of the tail queue
 59 * should use the explicit macro for this purpose for optimum efficiency.
 60 * A singly-linked tail queue may only be traversed in the forward direction.
 61 * Singly-linked tail queues are ideal for applications with large datasets
 62 * and few or no removals or for implementing a FIFO queue.
 63 *
 64 * A list is headed by a single forward pointer (or an array of forward
 65 * pointers for a hash table header). The elements are doubly linked
 66 * so that an arbitrary element can be removed without a need to
 67 * traverse the list. New elements can be added to the list before
 68 * or after an existing element or at the head of the list. A list
 69 * may be traversed in either direction.
 70 *
 71 * A tail queue is headed by a pair of pointers, one to the head of the
 72 * list and the other to the tail of the list. The elements are doubly
 73 * linked so that an arbitrary element can be removed without a need to
 74 * traverse the list. New elements can be added to the list before or
 75 * after an existing element, at the head of the list, or at the end of
 76 * the list. A tail queue may be traversed in either direction.
 77 *
 78 * For details on the use of these macros, see the queue(3) manual page.
 79 *
 80 * Below is a summary of implemented functions where:
 81 *  +  means the macro is available
 82 *  -  means the macro is not available
 83 *  s  means the macro is available but is slow (runs in O(n) time)
 84 *
 85 *				SLIST	LIST	STAILQ	TAILQ
 86 * _HEAD			+	+	+	+
 87 * _CLASS_HEAD			+	+	+	+
 88 * _HEAD_INITIALIZER		+	+	+	+
 89 * _ENTRY			+	+	+	+
 90 * _CLASS_ENTRY			+	+	+	+
 91 * _INIT			+	+	+	+
 92 * _EMPTY			+	+	+	+
 93 * _END				+	+	+	+
 94 * _FIRST			+	+	+	+
 95 * _NEXT			+	+	+	+
 96 * _PREV			-	+	-	+
 97 * _LAST			-	-	+	+
 98 * _LAST_FAST			-	-	-	+
 99 * _FOREACH			+	+	+	+
100 * _FOREACH_FROM		+	+	+	+
101 * _FOREACH_SAFE		+	+	+	+
102 * _FOREACH_FROM_SAFE		+	+	+	+
103 * _FOREACH_REVERSE		-	-	-	+
104 * _FOREACH_REVERSE_FROM	-	-	-	+
105 * _FOREACH_REVERSE_SAFE	-	-	-	+
106 * _FOREACH_REVERSE_FROM_SAFE	-	-	-	+
107 * _INSERT_HEAD			+	+	+	+
108 * _INSERT_BEFORE		-	+	-	+
109 * _INSERT_AFTER		+	+	+	+
110 * _INSERT_TAIL			-	-	+	+
111 * _CONCAT			s	s	+	+
112 * _REMOVE_AFTER		+	-	+	-
113 * _REMOVE_HEAD			+	+	+	+
114 * _REMOVE			s	+	s	+
115 * _REPLACE			-	+	-	+
116 * _SWAP			+	+	+	+
117 *
118 */
119#ifdef QUEUE_MACRO_DEBUG
120#warn Use QUEUE_MACRO_DEBUG_TRACE and/or QUEUE_MACRO_DEBUG_TRASH
121#define	QUEUE_MACRO_DEBUG_TRACE
122#define	QUEUE_MACRO_DEBUG_TRASH
123#endif
124
125#ifdef QUEUE_MACRO_DEBUG_TRACE
126/* Store the last 2 places the queue element or head was altered */
127struct qm_trace {
128	unsigned long	 lastline;
129	unsigned long	 prevline;
130	const char	*lastfile;
131	const char	*prevfile;
132};
133
134#define	TRACEBUF	struct qm_trace trace;
135#define	TRACEBUF_INITIALIZER	{ __LINE__, 0, __FILE__, NULL } ,
136
137#define	QMD_TRACE_HEAD(head) do {					\
138	(head)->trace.prevline = (head)->trace.lastline;		\
139	(head)->trace.prevfile = (head)->trace.lastfile;		\
140	(head)->trace.lastline = __LINE__;				\
141	(head)->trace.lastfile = __FILE__;				\
142} while (0)
143
144#define	QMD_TRACE_ELEM(elem) do {					\
145	(elem)->trace.prevline = (elem)->trace.lastline;		\
146	(elem)->trace.prevfile = (elem)->trace.lastfile;		\
147	(elem)->trace.lastline = __LINE__;				\
148	(elem)->trace.lastfile = __FILE__;				\
149} while (0)
150
151#else	/* !QUEUE_MACRO_DEBUG_TRACE */
152#define	QMD_TRACE_ELEM(elem)
153#define	QMD_TRACE_HEAD(head)
154#define	TRACEBUF
155#define	TRACEBUF_INITIALIZER
156#endif	/* QUEUE_MACRO_DEBUG_TRACE */
157
158#ifdef QUEUE_MACRO_DEBUG_TRASH
159#define	QMD_SAVELINK(name, link)	void **name = (void *)&(link)
160#define	TRASHIT(x)		do {(x) = (void *)-1;} while (0)
161#define	QMD_IS_TRASHED(x)	((x) == (void *)(intptr_t)-1)
162#else	/* !QUEUE_MACRO_DEBUG_TRASH */
163#define	QMD_SAVELINK(name, link)
164#define	TRASHIT(x)
165#define	QMD_IS_TRASHED(x)	0
166#endif	/* QUEUE_MACRO_DEBUG_TRASH */
167
168#ifdef __cplusplus
169/*
170 * In C++ there can be structure lists and class lists:
171 */
172#define	QUEUE_TYPEOF(type) type
173#else
174#define	QUEUE_TYPEOF(type) struct type
175#endif
176
177/*
178 * Singly-linked List declarations.
179 */
180#define	SLIST_HEAD(name, type)						\
181struct name {								\
182	struct type *slh_first;	/* first element */			\
183}
184
185#define	SLIST_CLASS_HEAD(name, type)					\
186struct name {								\
187	class type *slh_first;	/* first element */			\
188}
189
190#define	SLIST_HEAD_INITIALIZER(head)					\
191	{ NULL }
192
193#define	SLIST_ENTRY(type)						\
194struct {								\
195	struct type *sle_next;	/* next element */			\
196}
197
198#define	SLIST_CLASS_ENTRY(type)						\
199struct {								\
200	class type *sle_next;		/* next element */		\
201}
202
203/*
204 * Singly-linked List functions.
205 */
206#if (defined(_KERNEL) && defined(INVARIANTS))
207#define	QMD_SLIST_CHECK_PREVPTR(prevp, elm) do {			\
208	if (*(prevp) != (elm))						\
209		panic("Bad prevptr *(%p) == %p != %p",			\
210		    (prevp), *(prevp), (elm));				\
211} while (0)
212#else
213#define	QMD_SLIST_CHECK_PREVPTR(prevp, elm)
214#endif
215
216#define SLIST_CONCAT(head1, head2, type, field) do {			\
217	QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head1);		\
218	if (curelm == NULL) {						\
219		if ((SLIST_FIRST(head1) = SLIST_FIRST(head2)) != NULL)	\
220			SLIST_INIT(head2);				\
221	} else if (SLIST_FIRST(head2) != NULL) {			\
222		while (SLIST_NEXT(curelm, field) != NULL)		\
223			curelm = SLIST_NEXT(curelm, field);		\
224		SLIST_NEXT(curelm, field) = SLIST_FIRST(head2);		\
225		SLIST_INIT(head2);					\
226	}								\
227} while (0)
228
229#define	SLIST_EMPTY(head)	((head)->slh_first == NULL)
230
231#define	SLIST_FIRST(head)	((head)->slh_first)
232
233#define	SLIST_FOREACH(var, head, field)					\
234	for ((var) = SLIST_FIRST((head));				\
235	    (var);							\
236	    (var) = SLIST_NEXT((var), field))
237
238#define	SLIST_FOREACH_FROM(var, head, field)				\
239	for ((var) = ((var) ? (var) : SLIST_FIRST((head)));		\
240	    (var);							\
241	    (var) = SLIST_NEXT((var), field))
242
243#define	SLIST_FOREACH_SAFE(var, head, field, tvar)			\
244	for ((var) = SLIST_FIRST((head));				\
245	    (var) && ((tvar) = SLIST_NEXT((var), field), 1);		\
246	    (var) = (tvar))
247
248#define	SLIST_FOREACH_FROM_SAFE(var, head, field, tvar)			\
249	for ((var) = ((var) ? (var) : SLIST_FIRST((head)));		\
250	    (var) && ((tvar) = SLIST_NEXT((var), field), 1);		\
251	    (var) = (tvar))
252
253#define	SLIST_FOREACH_PREVPTR(var, varp, head, field)			\
254	for ((varp) = &SLIST_FIRST((head));				\
255	    ((var) = *(varp)) != NULL;					\
256	    (varp) = &SLIST_NEXT((var), field))
257
258#define	SLIST_INIT(head) do {						\
259	SLIST_FIRST((head)) = NULL;					\
260} while (0)
261
262#define	SLIST_INSERT_AFTER(slistelm, elm, field) do {			\
263	SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field);	\
264	SLIST_NEXT((slistelm), field) = (elm);				\
265} while (0)
266
267#define	SLIST_INSERT_HEAD(head, elm, field) do {			\
268	SLIST_NEXT((elm), field) = SLIST_FIRST((head));			\
269	SLIST_FIRST((head)) = (elm);					\
270} while (0)
271
272#define	SLIST_NEXT(elm, field)	((elm)->field.sle_next)
273
274#define	SLIST_REMOVE(head, elm, type, field) do {			\
275	if (SLIST_FIRST((head)) == (elm)) {				\
276		SLIST_REMOVE_HEAD((head), field);			\
277	}								\
278	else {								\
279		QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head);		\
280		while (SLIST_NEXT(curelm, field) != (elm))		\
281			curelm = SLIST_NEXT(curelm, field);		\
282		SLIST_REMOVE_AFTER(curelm, field);			\
283	}								\
284} while (0)
285
286#define SLIST_REMOVE_AFTER(elm, field) do {				\
287	QMD_SAVELINK(oldnext, SLIST_NEXT(elm, field)->field.sle_next);	\
288	SLIST_NEXT(elm, field) =					\
289	    SLIST_NEXT(SLIST_NEXT(elm, field), field);			\
290	TRASHIT(*oldnext);						\
291} while (0)
292
293#define	SLIST_REMOVE_HEAD(head, field) do {				\
294	QMD_SAVELINK(oldnext, SLIST_FIRST(head)->field.sle_next);	\
295	SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field);	\
296	TRASHIT(*oldnext);						\
297} while (0)
298
299#define	SLIST_REMOVE_PREVPTR(prevp, elm, field) do {			\
300	QMD_SLIST_CHECK_PREVPTR(prevp, elm);				\
301	*(prevp) = SLIST_NEXT(elm, field);				\
302	TRASHIT((elm)->field.sle_next);					\
303} while (0)
304
305#define SLIST_SWAP(head1, head2, type) do {				\
306	QUEUE_TYPEOF(type) *swap_first = SLIST_FIRST(head1);		\
307	SLIST_FIRST(head1) = SLIST_FIRST(head2);			\
308	SLIST_FIRST(head2) = swap_first;				\
309} while (0)
310
311#define	SLIST_END(head)		NULL
312
313/*
314 * Singly-linked Tail queue declarations.
315 */
316#define	STAILQ_HEAD(name, type)						\
317struct name {								\
318	struct type *stqh_first;/* first element */			\
319	struct type **stqh_last;/* addr of last next element */		\
320}
321
322#define	STAILQ_CLASS_HEAD(name, type)					\
323struct name {								\
324	class type *stqh_first;	/* first element */			\
325	class type **stqh_last;	/* addr of last next element */		\
326}
327
328#define	STAILQ_HEAD_INITIALIZER(head)					\
329	{ NULL, &(head).stqh_first }
330
331#define	STAILQ_ENTRY(type)						\
332struct {								\
333	struct type *stqe_next;	/* next element */			\
334}
335
336#define	STAILQ_CLASS_ENTRY(type)					\
337struct {								\
338	class type *stqe_next;	/* next element */			\
339}
340
341/*
342 * Singly-linked Tail queue functions.
343 */
344#define	STAILQ_CONCAT(head1, head2) do {				\
345	if (!STAILQ_EMPTY((head2))) {					\
346		*(head1)->stqh_last = (head2)->stqh_first;		\
347		(head1)->stqh_last = (head2)->stqh_last;		\
348		STAILQ_INIT((head2));					\
349	}								\
350} while (0)
351
352#define	STAILQ_EMPTY(head)	((head)->stqh_first == NULL)
353
354#define	STAILQ_FIRST(head)	((head)->stqh_first)
355
356#define	STAILQ_FOREACH(var, head, field)				\
357	for((var) = STAILQ_FIRST((head));				\
358	   (var);							\
359	   (var) = STAILQ_NEXT((var), field))
360
361#define	STAILQ_FOREACH_FROM(var, head, field)				\
362	for ((var) = ((var) ? (var) : STAILQ_FIRST((head)));		\
363	   (var);							\
364	   (var) = STAILQ_NEXT((var), field))
365
366#define	STAILQ_FOREACH_SAFE(var, head, field, tvar)			\
367	for ((var) = STAILQ_FIRST((head));				\
368	    (var) && ((tvar) = STAILQ_NEXT((var), field), 1);		\
369	    (var) = (tvar))
370
371#define	STAILQ_FOREACH_FROM_SAFE(var, head, field, tvar)		\
372	for ((var) = ((var) ? (var) : STAILQ_FIRST((head)));		\
373	    (var) && ((tvar) = STAILQ_NEXT((var), field), 1);		\
374	    (var) = (tvar))
375
376#define	STAILQ_INIT(head) do {						\
377	STAILQ_FIRST((head)) = NULL;					\
378	(head)->stqh_last = &STAILQ_FIRST((head));			\
379} while (0)
380
381#define	STAILQ_INSERT_AFTER(head, tqelm, elm, field) do {		\
382	if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
383		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
384	STAILQ_NEXT((tqelm), field) = (elm);				\
385} while (0)
386
387#define	STAILQ_INSERT_HEAD(head, elm, field) do {			\
388	if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL)	\
389		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
390	STAILQ_FIRST((head)) = (elm);					\
391} while (0)
392
393#define	STAILQ_INSERT_TAIL(head, elm, field) do {			\
394	STAILQ_NEXT((elm), field) = NULL;				\
395	*(head)->stqh_last = (elm);					\
396	(head)->stqh_last = &STAILQ_NEXT((elm), field);			\
397} while (0)
398
399#define	STAILQ_LAST(head, type, field)					\
400	(STAILQ_EMPTY((head)) ? NULL :					\
401	    __containerof((head)->stqh_last,				\
402	    QUEUE_TYPEOF(type), field.stqe_next))
403
404#define	STAILQ_NEXT(elm, field)	((elm)->field.stqe_next)
405
406#define	STAILQ_REMOVE(head, elm, type, field) do {			\
407	QMD_SAVELINK(oldnext, (elm)->field.stqe_next);			\
408	if (STAILQ_FIRST((head)) == (elm)) {				\
409		STAILQ_REMOVE_HEAD((head), field);			\
410	}								\
411	else {								\
412		QUEUE_TYPEOF(type) *curelm = STAILQ_FIRST(head);	\
413		while (STAILQ_NEXT(curelm, field) != (elm))		\
414			curelm = STAILQ_NEXT(curelm, field);		\
415		STAILQ_REMOVE_AFTER(head, curelm, field);		\
416	}								\
417	TRASHIT(*oldnext);						\
418} while (0)
419
420#define STAILQ_REMOVE_AFTER(head, elm, field) do {			\
421	if ((STAILQ_NEXT(elm, field) =					\
422	     STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL)	\
423		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
424} while (0)
425
426#define	STAILQ_REMOVE_HEAD(head, field) do {				\
427	if ((STAILQ_FIRST((head)) =					\
428	     STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL)		\
429		(head)->stqh_last = &STAILQ_FIRST((head));		\
430} while (0)
431
432#define STAILQ_SWAP(head1, head2, type) do {				\
433	QUEUE_TYPEOF(type) *swap_first = STAILQ_FIRST(head1);		\
434	QUEUE_TYPEOF(type) **swap_last = (head1)->stqh_last;		\
435	STAILQ_FIRST(head1) = STAILQ_FIRST(head2);			\
436	(head1)->stqh_last = (head2)->stqh_last;			\
437	STAILQ_FIRST(head2) = swap_first;				\
438	(head2)->stqh_last = swap_last;					\
439	if (STAILQ_EMPTY(head1))					\
440		(head1)->stqh_last = &STAILQ_FIRST(head1);		\
441	if (STAILQ_EMPTY(head2))					\
442		(head2)->stqh_last = &STAILQ_FIRST(head2);		\
443} while (0)
444
445#define	STAILQ_END(head)	NULL
446
447
448/*
449 * List declarations.
450 */
451#define	LIST_HEAD(name, type)						\
452struct name {								\
453	struct type *lh_first;	/* first element */			\
454}
455
456#define	LIST_CLASS_HEAD(name, type)					\
457struct name {								\
458	class type *lh_first;	/* first element */			\
459}
460
461#define	LIST_HEAD_INITIALIZER(head)					\
462	{ NULL }
463
464#define	LIST_ENTRY(type)						\
465struct {								\
466	struct type *le_next;	/* next element */			\
467	struct type **le_prev;	/* address of previous next element */	\
468}
469
470#define	LIST_CLASS_ENTRY(type)						\
471struct {								\
472	class type *le_next;	/* next element */			\
473	class type **le_prev;	/* address of previous next element */	\
474}
475
476/*
477 * List functions.
478 */
479
480#if (defined(_KERNEL) && defined(INVARIANTS))
481/*
482 * QMD_LIST_CHECK_HEAD(LIST_HEAD *head, LIST_ENTRY NAME)
483 *
484 * If the list is non-empty, validates that the first element of the list
485 * points back at 'head.'
486 */
487#define	QMD_LIST_CHECK_HEAD(head, field) do {				\
488	if (LIST_FIRST((head)) != NULL &&				\
489	    LIST_FIRST((head))->field.le_prev !=			\
490	     &LIST_FIRST((head)))					\
491		panic("Bad list head %p first->prev != head", (head));	\
492} while (0)
493
494/*
495 * QMD_LIST_CHECK_NEXT(TYPE *elm, LIST_ENTRY NAME)
496 *
497 * If an element follows 'elm' in the list, validates that the next element
498 * points back at 'elm.'
499 */
500#define	QMD_LIST_CHECK_NEXT(elm, field) do {				\
501	if (LIST_NEXT((elm), field) != NULL &&				\
502	    LIST_NEXT((elm), field)->field.le_prev !=			\
503	     &((elm)->field.le_next))					\
504		panic("Bad link elm %p next->prev != elm", (elm));	\
505} while (0)
506
507/*
508 * QMD_LIST_CHECK_PREV(TYPE *elm, LIST_ENTRY NAME)
509 *
510 * Validates that the previous element (or head of the list) points to 'elm.'
511 */
512#define	QMD_LIST_CHECK_PREV(elm, field) do {				\
513	if (*(elm)->field.le_prev != (elm))				\
514		panic("Bad link elm %p prev->next != elm", (elm));	\
515} while (0)
516#else
517#define	QMD_LIST_CHECK_HEAD(head, field)
518#define	QMD_LIST_CHECK_NEXT(elm, field)
519#define	QMD_LIST_CHECK_PREV(elm, field)
520#endif /* (_KERNEL && INVARIANTS) */
521
522#define LIST_CONCAT(head1, head2, type, field) do {			\
523	QUEUE_TYPEOF(type) *curelm = LIST_FIRST(head1);			\
524	if (curelm == NULL) {						\
525		if ((LIST_FIRST(head1) = LIST_FIRST(head2)) != NULL) {	\
526			LIST_FIRST(head2)->field.le_prev =		\
527			    &LIST_FIRST((head1));			\
528			LIST_INIT(head2);				\
529		}							\
530	} else if (LIST_FIRST(head2) != NULL) {				\
531		while (LIST_NEXT(curelm, field) != NULL)		\
532			curelm = LIST_NEXT(curelm, field);		\
533		LIST_NEXT(curelm, field) = LIST_FIRST(head2);		\
534		LIST_FIRST(head2)->field.le_prev = &LIST_NEXT(curelm, field);\
535		LIST_INIT(head2);					\
536	}								\
537} while (0)
538
539#define	LIST_EMPTY(head)	((head)->lh_first == NULL)
540
541#define	LIST_FIRST(head)	((head)->lh_first)
542
543#define	LIST_FOREACH(var, head, field)					\
544	for ((var) = LIST_FIRST((head));				\
545	    (var);							\
546	    (var) = LIST_NEXT((var), field))
547
548#define	LIST_FOREACH_FROM(var, head, field)				\
549	for ((var) = ((var) ? (var) : LIST_FIRST((head)));		\
550	    (var);							\
551	    (var) = LIST_NEXT((var), field))
552
553#define	LIST_FOREACH_SAFE(var, head, field, tvar)			\
554	for ((var) = LIST_FIRST((head));				\
555	    (var) && ((tvar) = LIST_NEXT((var), field), 1);		\
556	    (var) = (tvar))
557
558#define	LIST_FOREACH_FROM_SAFE(var, head, field, tvar)			\
559	for ((var) = ((var) ? (var) : LIST_FIRST((head)));		\
560	    (var) && ((tvar) = LIST_NEXT((var), field), 1);		\
561	    (var) = (tvar))
562
563#define	LIST_INIT(head) do {						\
564	LIST_FIRST((head)) = NULL;					\
565} while (0)
566
567#define	LIST_INSERT_AFTER(listelm, elm, field) do {			\
568	QMD_LIST_CHECK_NEXT(listelm, field);				\
569	if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
570		LIST_NEXT((listelm), field)->field.le_prev =		\
571		    &LIST_NEXT((elm), field);				\
572	LIST_NEXT((listelm), field) = (elm);				\
573	(elm)->field.le_prev = &LIST_NEXT((listelm), field);		\
574} while (0)
575
576#define	LIST_INSERT_BEFORE(listelm, elm, field) do {			\
577	QMD_LIST_CHECK_PREV(listelm, field);				\
578	(elm)->field.le_prev = (listelm)->field.le_prev;		\
579	LIST_NEXT((elm), field) = (listelm);				\
580	*(listelm)->field.le_prev = (elm);				\
581	(listelm)->field.le_prev = &LIST_NEXT((elm), field);		\
582} while (0)
583
584#define	LIST_INSERT_HEAD(head, elm, field) do {				\
585	QMD_LIST_CHECK_HEAD((head), field);				\
586	if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL)	\
587		LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
588	LIST_FIRST((head)) = (elm);					\
589	(elm)->field.le_prev = &LIST_FIRST((head));			\
590} while (0)
591
592#define	LIST_NEXT(elm, field)	((elm)->field.le_next)
593
594#define	LIST_PREV(elm, head, type, field)				\
595	((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL :		\
596	    __containerof((elm)->field.le_prev,				\
597	    QUEUE_TYPEOF(type), field.le_next))
598
599#define LIST_REMOVE_HEAD(head, field)					\
600	LIST_REMOVE(LIST_FIRST(head), field)
601
602#define	LIST_REMOVE(elm, field) do {					\
603	QMD_SAVELINK(oldnext, (elm)->field.le_next);			\
604	QMD_SAVELINK(oldprev, (elm)->field.le_prev);			\
605	QMD_LIST_CHECK_NEXT(elm, field);				\
606	QMD_LIST_CHECK_PREV(elm, field);				\
607	if (LIST_NEXT((elm), field) != NULL)				\
608		LIST_NEXT((elm), field)->field.le_prev =		\
609		    (elm)->field.le_prev;				\
610	*(elm)->field.le_prev = LIST_NEXT((elm), field);		\
611	TRASHIT(*oldnext);						\
612	TRASHIT(*oldprev);						\
613} while (0)
614
615#define LIST_REPLACE(elm, elm2, field) do {				\
616	QMD_SAVELINK(oldnext, (elm)->field.le_next);			\
617	QMD_SAVELINK(oldprev, (elm)->field.le_prev);			\
618	QMD_LIST_CHECK_NEXT(elm, field);				\
619	QMD_LIST_CHECK_PREV(elm, field);				\
620	LIST_NEXT((elm2), field) = LIST_NEXT((elm), field);		\
621	if (LIST_NEXT((elm2), field) != NULL)				\
622		LIST_NEXT((elm2), field)->field.le_prev =		\
623		    &(elm2)->field.le_next;				\
624	(elm2)->field.le_prev = (elm)->field.le_prev;			\
625	*(elm2)->field.le_prev = (elm2);				\
626	TRASHIT(*oldnext);						\
627	TRASHIT(*oldprev);						\
628} while (0)
629
630#define LIST_SWAP(head1, head2, type, field) do {			\
631	QUEUE_TYPEOF(type) *swap_tmp = LIST_FIRST(head1);		\
632	LIST_FIRST((head1)) = LIST_FIRST((head2));			\
633	LIST_FIRST((head2)) = swap_tmp;					\
634	if ((swap_tmp = LIST_FIRST((head1))) != NULL)			\
635		swap_tmp->field.le_prev = &LIST_FIRST((head1));		\
636	if ((swap_tmp = LIST_FIRST((head2))) != NULL)			\
637		swap_tmp->field.le_prev = &LIST_FIRST((head2));		\
638} while (0)
639
640#define	LIST_END(head)	NULL
641
642/*
643 * Tail queue declarations.
644 */
645#define	TAILQ_HEAD(name, type)						\
646struct name {								\
647	struct type *tqh_first;	/* first element */			\
648	struct type **tqh_last;	/* addr of last next element */		\
649	TRACEBUF							\
650}
651
652#define	TAILQ_CLASS_HEAD(name, type)					\
653struct name {								\
654	class type *tqh_first;	/* first element */			\
655	class type **tqh_last;	/* addr of last next element */		\
656	TRACEBUF							\
657}
658
659#define	TAILQ_HEAD_INITIALIZER(head)					\
660	{ NULL, &(head).tqh_first, TRACEBUF_INITIALIZER }
661
662#define	TAILQ_ENTRY(type)						\
663struct {								\
664	struct type *tqe_next;	/* next element */			\
665	struct type **tqe_prev;	/* address of previous next element */	\
666	TRACEBUF							\
667}
668
669#define	TAILQ_CLASS_ENTRY(type)						\
670struct {								\
671	class type *tqe_next;	/* next element */			\
672	class type **tqe_prev;	/* address of previous next element */	\
673	TRACEBUF							\
674}
675
676/*
677 * Tail queue functions.
678 */
679#if (defined(_KERNEL) && defined(INVARIANTS))
680/*
681 * QMD_TAILQ_CHECK_HEAD(TAILQ_HEAD *head, TAILQ_ENTRY NAME)
682 *
683 * If the tailq is non-empty, validates that the first element of the tailq
684 * points back at 'head.'
685 */
686#define	QMD_TAILQ_CHECK_HEAD(head, field) do {				\
687	if (!TAILQ_EMPTY(head) &&					\
688	    TAILQ_FIRST((head))->field.tqe_prev !=			\
689	     &TAILQ_FIRST((head)))					\
690		panic("Bad tailq head %p first->prev != head", (head));	\
691} while (0)
692
693/*
694 * QMD_TAILQ_CHECK_TAIL(TAILQ_HEAD *head, TAILQ_ENTRY NAME)
695 *
696 * Validates that the tail of the tailq is a pointer to pointer to NULL.
697 */
698#define	QMD_TAILQ_CHECK_TAIL(head, field) do {				\
699	if (*(head)->tqh_last != NULL)					\
700		panic("Bad tailq NEXT(%p->tqh_last) != NULL", (head));	\
701} while (0)
702
703/*
704 * QMD_TAILQ_CHECK_NEXT(TYPE *elm, TAILQ_ENTRY NAME)
705 *
706 * If an element follows 'elm' in the tailq, validates that the next element
707 * points back at 'elm.'
708 */
709#define	QMD_TAILQ_CHECK_NEXT(elm, field) do {				\
710	if (TAILQ_NEXT((elm), field) != NULL &&				\
711	    TAILQ_NEXT((elm), field)->field.tqe_prev !=			\
712	     &((elm)->field.tqe_next))					\
713		panic("Bad link elm %p next->prev != elm", (elm));	\
714} while (0)
715
716/*
717 * QMD_TAILQ_CHECK_PREV(TYPE *elm, TAILQ_ENTRY NAME)
718 *
719 * Validates that the previous element (or head of the tailq) points to 'elm.'
720 */
721#define	QMD_TAILQ_CHECK_PREV(elm, field) do {				\
722	if (*(elm)->field.tqe_prev != (elm))				\
723		panic("Bad link elm %p prev->next != elm", (elm));	\
724} while (0)
725#else
726#define	QMD_TAILQ_CHECK_HEAD(head, field)
727#define	QMD_TAILQ_CHECK_TAIL(head, headname)
728#define	QMD_TAILQ_CHECK_NEXT(elm, field)
729#define	QMD_TAILQ_CHECK_PREV(elm, field)
730#endif /* (_KERNEL && INVARIANTS) */
731
732#define	TAILQ_CONCAT(head1, head2, field) do {				\
733	if (!TAILQ_EMPTY(head2)) {					\
734		*(head1)->tqh_last = (head2)->tqh_first;		\
735		(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last;	\
736		(head1)->tqh_last = (head2)->tqh_last;			\
737		TAILQ_INIT((head2));					\
738		QMD_TRACE_HEAD(head1);					\
739		QMD_TRACE_HEAD(head2);					\
740	}								\
741} while (0)
742
743#define	TAILQ_EMPTY(head)	((head)->tqh_first == NULL)
744
745#define	TAILQ_FIRST(head)	((head)->tqh_first)
746
747#define	TAILQ_FOREACH(var, head, field)					\
748	for ((var) = TAILQ_FIRST((head));				\
749	    (var);							\
750	    (var) = TAILQ_NEXT((var), field))
751
752#define	TAILQ_FOREACH_FROM(var, head, field)				\
753	for ((var) = ((var) ? (var) : TAILQ_FIRST((head)));		\
754	    (var);							\
755	    (var) = TAILQ_NEXT((var), field))
756
757#define	TAILQ_FOREACH_SAFE(var, head, field, tvar)			\
758	for ((var) = TAILQ_FIRST((head));				\
759	    (var) && ((tvar) = TAILQ_NEXT((var), field), 1);		\
760	    (var) = (tvar))
761
762#define	TAILQ_FOREACH_FROM_SAFE(var, head, field, tvar)			\
763	for ((var) = ((var) ? (var) : TAILQ_FIRST((head)));		\
764	    (var) && ((tvar) = TAILQ_NEXT((var), field), 1);		\
765	    (var) = (tvar))
766
767#define	TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
768	for ((var) = TAILQ_LAST((head), headname);			\
769	    (var);							\
770	    (var) = TAILQ_PREV((var), headname, field))
771
772#define	TAILQ_FOREACH_REVERSE_FROM(var, head, headname, field)		\
773	for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname));	\
774	    (var);							\
775	    (var) = TAILQ_PREV((var), headname, field))
776
777#define	TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar)	\
778	for ((var) = TAILQ_LAST((head), headname);			\
779	    (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1);	\
780	    (var) = (tvar))
781
782#define	TAILQ_FOREACH_REVERSE_FROM_SAFE(var, head, headname, field, tvar)\
783	for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname));	\
784	    (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1);	\
785	    (var) = (tvar))
786
787#define	TAILQ_INIT(head) do {						\
788	TAILQ_FIRST((head)) = NULL;					\
789	(head)->tqh_last = &TAILQ_FIRST((head));			\
790	QMD_TRACE_HEAD(head);						\
791} while (0)
792
793#define	TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
794	QMD_TAILQ_CHECK_NEXT(listelm, field);				\
795	if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
796		TAILQ_NEXT((elm), field)->field.tqe_prev =		\
797		    &TAILQ_NEXT((elm), field);				\
798	else {								\
799		(head)->tqh_last = &TAILQ_NEXT((elm), field);		\
800		QMD_TRACE_HEAD(head);					\
801	}								\
802	TAILQ_NEXT((listelm), field) = (elm);				\
803	(elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field);		\
804	QMD_TRACE_ELEM(&(elm)->field);					\
805	QMD_TRACE_ELEM(&(listelm)->field);				\
806} while (0)
807
808#define	TAILQ_INSERT_BEFORE(listelm, elm, field) do {			\
809	QMD_TAILQ_CHECK_PREV(listelm, field);				\
810	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
811	TAILQ_NEXT((elm), field) = (listelm);				\
812	*(listelm)->field.tqe_prev = (elm);				\
813	(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field);		\
814	QMD_TRACE_ELEM(&(elm)->field);					\
815	QMD_TRACE_ELEM(&(listelm)->field);				\
816} while (0)
817
818#define	TAILQ_INSERT_HEAD(head, elm, field) do {			\
819	QMD_TAILQ_CHECK_HEAD(head, field);				\
820	if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL)	\
821		TAILQ_FIRST((head))->field.tqe_prev =			\
822		    &TAILQ_NEXT((elm), field);				\
823	else								\
824		(head)->tqh_last = &TAILQ_NEXT((elm), field);		\
825	TAILQ_FIRST((head)) = (elm);					\
826	(elm)->field.tqe_prev = &TAILQ_FIRST((head));			\
827	QMD_TRACE_HEAD(head);						\
828	QMD_TRACE_ELEM(&(elm)->field);					\
829} while (0)
830
831#define	TAILQ_INSERT_TAIL(head, elm, field) do {			\
832	QMD_TAILQ_CHECK_TAIL(head, field);				\
833	TAILQ_NEXT((elm), field) = NULL;				\
834	(elm)->field.tqe_prev = (head)->tqh_last;			\
835	*(head)->tqh_last = (elm);					\
836	(head)->tqh_last = &TAILQ_NEXT((elm), field);			\
837	QMD_TRACE_HEAD(head);						\
838	QMD_TRACE_ELEM(&(elm)->field);					\
839} while (0)
840
841#define	TAILQ_LAST(head, headname)					\
842	(*(((struct headname *)((head)->tqh_last))->tqh_last))
843
844/*
845 * The FAST function is fast in that it causes no data access other
846 * then the access to the head. The standard LAST function above
847 * will cause a data access of both the element you want and
848 * the previous element. FAST is very useful for instances when
849 * you may want to prefetch the last data element.
850 */
851#define	TAILQ_LAST_FAST(head, type, field)				\
852    (TAILQ_EMPTY(head) ? NULL : __containerof((head)->tqh_last, QUEUE_TYPEOF(type), field.tqe_next))
853
854#define	TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
855
856#define	TAILQ_PREV(elm, headname, field)				\
857	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
858
859#define	TAILQ_PREV_FAST(elm, head, type, field)				\
860    ((elm)->field.tqe_prev == &(head)->tqh_first ? NULL :		\
861     __containerof((elm)->field.tqe_prev, QUEUE_TYPEOF(type), field.tqe_next))
862
863#define TAILQ_REMOVE_HEAD(head, field)					\
864	TAILQ_REMOVE(head, TAILQ_FIRST(head), field)
865
866#define	TAILQ_REMOVE(head, elm, field) do {				\
867	QMD_SAVELINK(oldnext, (elm)->field.tqe_next);			\
868	QMD_SAVELINK(oldprev, (elm)->field.tqe_prev);			\
869	QMD_TAILQ_CHECK_NEXT(elm, field);				\
870	QMD_TAILQ_CHECK_PREV(elm, field);				\
871	if ((TAILQ_NEXT((elm), field)) != NULL)				\
872		TAILQ_NEXT((elm), field)->field.tqe_prev =		\
873		    (elm)->field.tqe_prev;				\
874	else {								\
875		(head)->tqh_last = (elm)->field.tqe_prev;		\
876		QMD_TRACE_HEAD(head);					\
877	}								\
878	*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field);		\
879	TRASHIT(*oldnext);						\
880	TRASHIT(*oldprev);						\
881	QMD_TRACE_ELEM(&(elm)->field);					\
882} while (0)
883
884#define TAILQ_REPLACE(head, elm, elm2, field) do {			\
885	QMD_SAVELINK(oldnext, (elm)->field.tqe_next);			\
886	QMD_SAVELINK(oldprev, (elm)->field.tqe_prev);			\
887	QMD_TAILQ_CHECK_NEXT(elm, field);				\
888	QMD_TAILQ_CHECK_PREV(elm, field);				\
889	TAILQ_NEXT((elm2), field) = TAILQ_NEXT((elm), field);		\
890	if (TAILQ_NEXT((elm2), field) != TAILQ_END(head))		\
891                TAILQ_NEXT((elm2), field)->field.tqe_prev =		\
892                    &(elm2)->field.tqe_next;				\
893        else								\
894                (head)->tqh_last = &(elm2)->field.tqe_next;		\
895        (elm2)->field.tqe_prev = (elm)->field.tqe_prev;			\
896        *(elm2)->field.tqe_prev = (elm2);				\
897	TRASHIT(*oldnext);						\
898	TRASHIT(*oldprev);						\
899	QMD_TRACE_ELEM(&(elm)->field);					\
900} while (0)
901
902#define TAILQ_SWAP(head1, head2, type, field) do {			\
903	QUEUE_TYPEOF(type) *swap_first = (head1)->tqh_first;		\
904	QUEUE_TYPEOF(type) **swap_last = (head1)->tqh_last;		\
905	(head1)->tqh_first = (head2)->tqh_first;			\
906	(head1)->tqh_last = (head2)->tqh_last;				\
907	(head2)->tqh_first = swap_first;				\
908	(head2)->tqh_last = swap_last;					\
909	if ((swap_first = (head1)->tqh_first) != NULL)			\
910		swap_first->field.tqe_prev = &(head1)->tqh_first;	\
911	else								\
912		(head1)->tqh_last = &(head1)->tqh_first;		\
913	if ((swap_first = (head2)->tqh_first) != NULL)			\
914		swap_first->field.tqe_prev = &(head2)->tqh_first;	\
915	else								\
916		(head2)->tqh_last = &(head2)->tqh_first;		\
917} while (0)
918
919#define	TAILQ_END(head)		NULL
920
921#endif /* !_SYS_QUEUE_H_ */