queue.h revision 51955
18876Srgrimes/*
21541Srgrimes * Copyright (c) 1991, 1993
31541Srgrimes *	The Regents of the University of California.  All rights reserved.
41541Srgrimes *
51541Srgrimes * Redistribution and use in source and binary forms, with or without
61541Srgrimes * modification, are permitted provided that the following conditions
71541Srgrimes * are met:
81541Srgrimes * 1. Redistributions of source code must retain the above copyright
91541Srgrimes *    notice, this list of conditions and the following disclaimer.
101541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111541Srgrimes *    notice, this list of conditions and the following disclaimer in the
121541Srgrimes *    documentation and/or other materials provided with the distribution.
131541Srgrimes * 3. All advertising materials mentioning features or use of this software
141541Srgrimes *    must display the following acknowledgement:
151541Srgrimes *	This product includes software developed by the University of
161541Srgrimes *	California, Berkeley and its contributors.
171541Srgrimes * 4. Neither the name of the University nor the names of its contributors
181541Srgrimes *    may be used to endorse or promote products derived from this software
191541Srgrimes *    without specific prior written permission.
201541Srgrimes *
211541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
221541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241541Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
251541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
261541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
271541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
281541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
291541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
301541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
311541Srgrimes * SUCH DAMAGE.
321541Srgrimes *
3314492Shsu *	@(#)queue.h	8.5 (Berkeley) 8/20/94
3450477Speter * $FreeBSD: head/sys/sys/queue.h 51955 1999-10-05 20:35:32Z n_hibma $
351541Srgrimes */
361541Srgrimes
3712592Sbde#ifndef _SYS_QUEUE_H_
381541Srgrimes#define	_SYS_QUEUE_H_
391541Srgrimes
401541Srgrimes/*
4114940Sgibbs * This file defines five types of data structures: singly-linked lists,
4214940Sgibbs * slingly-linked tail queues, lists, tail queues, and circular queues.
431541Srgrimes *
4414940Sgibbs * A singly-linked list is headed by a single forward pointer. The elements
4514940Sgibbs * are singly linked for minimum space and pointer manipulation overhead at
4614940Sgibbs * the expense of O(n) removal for arbitrary elements. New elements can be
4714940Sgibbs * added to the list after an existing element or at the head of the list.
4814940Sgibbs * Elements being removed from the head of the list should use the explicit
4914940Sgibbs * macro for this purpose for optimum efficiency. A singly-linked list may
5014940Sgibbs * only be traversed in the forward direction.  Singly-linked lists are ideal
5114940Sgibbs * for applications with large datasets and few or no removals or for
5214940Sgibbs * implementing a LIFO queue.
5314940Sgibbs *
5414940Sgibbs * A singly-linked tail queue is headed by a pair of pointers, one to the
5514940Sgibbs * head of the list and the other to the tail of the list. The elements are
5614940Sgibbs * singly linked for minimum space and pointer manipulation overhead at the
5714940Sgibbs * expense of O(n) removal for arbitrary elements. New elements can be added
5814940Sgibbs * to the list after an existing element, at the head of the list, or at the
5914940Sgibbs * end of the list. Elements being removed from the head of the tail queue
6014940Sgibbs * should use the explicit macro for this purpose for optimum efficiency.
6114940Sgibbs * A singly-linked tail queue may only be traversed in the forward direction.
6214940Sgibbs * Singly-linked tail queues are ideal for applications with large datasets
6314940Sgibbs * and few or no removals or for implementing a FIFO queue.
6414940Sgibbs *
651541Srgrimes * A list is headed by a single forward pointer (or an array of forward
661541Srgrimes * pointers for a hash table header). The elements are doubly linked
671541Srgrimes * so that an arbitrary element can be removed without a need to
6814492Shsu * traverse the list. New elements can be added to the list before
6914492Shsu * or after an existing element or at the head of the list. A list
7014492Shsu * may only be traversed in the forward direction.
711541Srgrimes *
721541Srgrimes * A tail queue is headed by a pair of pointers, one to the head of the
731541Srgrimes * list and the other to the tail of the list. The elements are doubly
741541Srgrimes * linked so that an arbitrary element can be removed without a need to
7514492Shsu * traverse the list. New elements can be added to the list before or
7614492Shsu * after an existing element, at the head of the list, or at the end of
7714492Shsu * the list. A tail queue may only be traversed in the forward direction.
781541Srgrimes *
791541Srgrimes * A circle queue is headed by a pair of pointers, one to the head of the
801541Srgrimes * list and the other to the tail of the list. The elements are doubly
811541Srgrimes * linked so that an arbitrary element can be removed without a need to
821541Srgrimes * traverse the list. New elements can be added to the list before or after
831541Srgrimes * an existing element, at the head of the list, or at the end of the list.
841541Srgrimes * A circle queue may be traversed in either direction, but has a more
851541Srgrimes * complex end of list detection.
861541Srgrimes *
871541Srgrimes * For details on the use of these macros, see the queue(3) manual page.
8825188Sphk *
8925188Sphk *
9025188Sphk *			SLIST	LIST	STAILQ	TAILQ	CIRCLEQ
9125188Sphk * _HEAD		+	+	+	+	+
9225188Sphk * _ENTRY		+	+	+	+	+
9325188Sphk * _INIT		+	+	+	+	+
9425188Sphk * _EMPTY		+	+	+	+	+
9537143Sphk * _FIRST		+	+	+	+	+
9637143Sphk * _NEXT		+	+	+	+	+
9725188Sphk * _PREV		-	-	-	+	+
9837143Sphk * _LAST		-	-	+	+	+
9950604Sjdp * _FOREACH		+	+	+	+	+
10025188Sphk * _INSERT_HEAD		+	+	+	+	+
10125188Sphk * _INSERT_BEFORE	-	+	-	+	+
10225188Sphk * _INSERT_AFTER	+	+	+	+	+
10325188Sphk * _INSERT_TAIL		-	-	+	+	+
10425188Sphk * _REMOVE_HEAD		+	-	+	-	-
10525188Sphk * _REMOVE		+	+	+	+	+
10625188Sphk *
1071541Srgrimes */
1081541Srgrimes
1091541Srgrimes/*
11014940Sgibbs * Singly-linked List definitions.
11114940Sgibbs */
11214940Sgibbs#define SLIST_HEAD(name, type)						\
11314940Sgibbsstruct name {								\
11414940Sgibbs	struct type *slh_first;	/* first element */			\
11514940Sgibbs}
11651955Sn_hibma
11751955Sn_hibma#define SLIST_HEAD_INITIALIZER(head)					\
11851955Sn_hibma	{ NULL }
11914940Sgibbs
12014940Sgibbs#define SLIST_ENTRY(type)						\
12114940Sgibbsstruct {								\
12214940Sgibbs	struct type *sle_next;	/* next element */			\
12314940Sgibbs}
12414940Sgibbs
12514940Sgibbs/*
12614940Sgibbs * Singly-linked List functions.
12714940Sgibbs */
12821029Sphk#define	SLIST_EMPTY(head)	((head)->slh_first == NULL)
12921029Sphk
13021029Sphk#define	SLIST_FIRST(head)	((head)->slh_first)
13121029Sphk
13228730Sphk#define SLIST_FOREACH(var, head, field)					\
13328730Sphk	for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
13428730Sphk
13514940Sgibbs#define SLIST_INIT(head) {						\
13614940Sgibbs	(head)->slh_first = NULL;					\
13714940Sgibbs}
13814940Sgibbs
13942359Sn_hibma#define SLIST_INSERT_AFTER(slistelm, elm, field) do {			\
14014940Sgibbs	(elm)->field.sle_next = (slistelm)->field.sle_next;		\
14114940Sgibbs	(slistelm)->field.sle_next = (elm);				\
14233793Sjulian} while (0)
14314940Sgibbs
14433793Sjulian#define SLIST_INSERT_HEAD(head, elm, field) do {			\
14514940Sgibbs	(elm)->field.sle_next = (head)->slh_first;			\
14614940Sgibbs	(head)->slh_first = (elm);					\
14733793Sjulian} while (0)
14814940Sgibbs
14921029Sphk#define SLIST_NEXT(elm, field)	((elm)->field.sle_next)
15021029Sphk
15133793Sjulian#define SLIST_REMOVE_HEAD(head, field) do {				\
15214940Sgibbs	(head)->slh_first = (head)->slh_first->field.sle_next;		\
15333793Sjulian} while (0)
15414940Sgibbs
15533793Sjulian#define SLIST_REMOVE(head, elm, type, field) do {			\
15614940Sgibbs	if ((head)->slh_first == (elm)) {				\
15714940Sgibbs		SLIST_REMOVE_HEAD((head), field);			\
15814940Sgibbs	}								\
15914940Sgibbs	else {								\
16014940Sgibbs		struct type *curelm = (head)->slh_first;		\
16114940Sgibbs		while( curelm->field.sle_next != (elm) )		\
16214940Sgibbs			curelm = curelm->field.sle_next;		\
16314940Sgibbs		curelm->field.sle_next =				\
16414940Sgibbs		    curelm->field.sle_next->field.sle_next;		\
16514940Sgibbs	}								\
16633793Sjulian} while (0)
16714940Sgibbs
16814940Sgibbs/*
16914940Sgibbs * Singly-linked Tail queue definitions.
17014940Sgibbs */
17114940Sgibbs#define STAILQ_HEAD(name, type)						\
17214940Sgibbsstruct name {								\
17314940Sgibbs	struct type *stqh_first;/* first element */			\
17414940Sgibbs	struct type **stqh_last;/* addr of last next element */		\
17514940Sgibbs}
17614940Sgibbs
17742359Sn_hibma#define STAILQ_HEAD_INITIALIZER(head)					\
17842359Sn_hibma	{ NULL, &(head).stqh_first }
17942359Sn_hibma
18014940Sgibbs#define STAILQ_ENTRY(type)						\
18114940Sgibbsstruct {								\
18214940Sgibbs	struct type *stqe_next;	/* next element */			\
18314940Sgibbs}
18414940Sgibbs
18514940Sgibbs/*
18614940Sgibbs * Singly-linked Tail queue functions.
18714940Sgibbs */
18825188Sphk#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
18925188Sphk
19033793Sjulian#define	STAILQ_INIT(head) do {						\
19114940Sgibbs	(head)->stqh_first = NULL;					\
19214940Sgibbs	(head)->stqh_last = &(head)->stqh_first;			\
19333793Sjulian} while (0)
19414940Sgibbs
19525536Sdfr#define STAILQ_FIRST(head)	((head)->stqh_first)
19625536Sdfr#define STAILQ_LAST(head)	(*(head)->stqh_last)
19725536Sdfr
19850604Sjdp#define STAILQ_FOREACH(var, head, field)				\
19950604Sjdp	for((var) = (head)->stqh_first; (var); (var) = (var)->field.stqe_next)
20050604Sjdp
20133793Sjulian#define STAILQ_INSERT_HEAD(head, elm, field) do {			\
20214940Sgibbs	if (((elm)->field.stqe_next = (head)->stqh_first) == NULL)	\
20314940Sgibbs		(head)->stqh_last = &(elm)->field.stqe_next;		\
20414940Sgibbs	(head)->stqh_first = (elm);					\
20533793Sjulian} while (0)
20614940Sgibbs
20733793Sjulian#define STAILQ_INSERT_TAIL(head, elm, field) do {			\
20814940Sgibbs	(elm)->field.stqe_next = NULL;					\
20914940Sgibbs	*(head)->stqh_last = (elm);					\
21014940Sgibbs	(head)->stqh_last = &(elm)->field.stqe_next;			\
21133793Sjulian} while (0)
21214940Sgibbs
21333793Sjulian#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do {		\
21414940Sgibbs	if (((elm)->field.stqe_next = (tqelm)->field.stqe_next) == NULL)\
21514940Sgibbs		(head)->stqh_last = &(elm)->field.stqe_next;		\
21614940Sgibbs	(tqelm)->field.stqe_next = (elm);				\
21733793Sjulian} while (0)
21814940Sgibbs
21925536Sdfr#define STAILQ_NEXT(elm, field)	((elm)->field.stqe_next)
22025536Sdfr
22133793Sjulian#define STAILQ_REMOVE_HEAD(head, field) do {				\
22214940Sgibbs	if (((head)->stqh_first =					\
22314940Sgibbs	     (head)->stqh_first->field.stqe_next) == NULL)		\
22414940Sgibbs		(head)->stqh_last = &(head)->stqh_first;		\
22533793Sjulian} while (0)
22614940Sgibbs
22742359Sn_hibma
22833793Sjulian#define STAILQ_REMOVE(head, elm, type, field) do {			\
22914940Sgibbs	if ((head)->stqh_first == (elm)) {				\
23014940Sgibbs		STAILQ_REMOVE_HEAD(head, field);			\
23114940Sgibbs	}								\
23214940Sgibbs	else {								\
23314940Sgibbs		struct type *curelm = (head)->stqh_first;		\
23414940Sgibbs		while( curelm->field.stqe_next != (elm) )		\
23514940Sgibbs			curelm = curelm->field.stqe_next;		\
23614940Sgibbs		if((curelm->field.stqe_next =				\
23714940Sgibbs		    curelm->field.stqe_next->field.stqe_next) == NULL)	\
23814940Sgibbs			(head)->stqh_last = &(curelm)->field.stqe_next;	\
23914940Sgibbs	}								\
24033793Sjulian} while (0)
24114940Sgibbs
24214940Sgibbs/*
2431541Srgrimes * List definitions.
2441541Srgrimes */
2451541Srgrimes#define LIST_HEAD(name, type)						\
2461541Srgrimesstruct name {								\
2471541Srgrimes	struct type *lh_first;	/* first element */			\
2481541Srgrimes}
2491541Srgrimes
25048641Sn_hibma#define LIST_HEAD_INITIALIZER(head)					\
25142359Sn_hibma	{ NULL }
25242359Sn_hibma
2531541Srgrimes#define LIST_ENTRY(type)						\
2541541Srgrimesstruct {								\
2551541Srgrimes	struct type *le_next;	/* next element */			\
2561541Srgrimes	struct type **le_prev;	/* address of previous next element */	\
2571541Srgrimes}
2581541Srgrimes
2591541Srgrimes/*
2601541Srgrimes * List functions.
2611541Srgrimes */
26225188Sphk
26325188Sphk#define	LIST_EMPTY(head) ((head)->lh_first == NULL)
26425188Sphk
26524935Sphk#define LIST_FIRST(head)	((head)->lh_first)
26624935Sphk
26724935Sphk#define LIST_FOREACH(var, head, field)					\
26824935Sphk	for((var) = (head)->lh_first; (var); (var) = (var)->field.le_next)
26924935Sphk
27033793Sjulian#define	LIST_INIT(head) do {						\
2711541Srgrimes	(head)->lh_first = NULL;					\
27233793Sjulian} while (0)
2731541Srgrimes
27433793Sjulian#define LIST_INSERT_AFTER(listelm, elm, field) do {			\
2751541Srgrimes	if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)	\
2761541Srgrimes		(listelm)->field.le_next->field.le_prev =		\
2771541Srgrimes		    &(elm)->field.le_next;				\
2781541Srgrimes	(listelm)->field.le_next = (elm);				\
2791541Srgrimes	(elm)->field.le_prev = &(listelm)->field.le_next;		\
28033793Sjulian} while (0)
2811541Srgrimes
28233793Sjulian#define LIST_INSERT_BEFORE(listelm, elm, field) do {			\
28313697Sgibbs	(elm)->field.le_prev = (listelm)->field.le_prev;		\
28413697Sgibbs	(elm)->field.le_next = (listelm);				\
28513697Sgibbs	*(listelm)->field.le_prev = (elm);				\
28613697Sgibbs	(listelm)->field.le_prev = &(elm)->field.le_next;		\
28733793Sjulian} while (0)
28813697Sgibbs
28933793Sjulian#define LIST_INSERT_HEAD(head, elm, field) do {				\
2901541Srgrimes	if (((elm)->field.le_next = (head)->lh_first) != NULL)		\
2911541Srgrimes		(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
2921541Srgrimes	(head)->lh_first = (elm);					\
2931541Srgrimes	(elm)->field.le_prev = &(head)->lh_first;			\
29433793Sjulian} while (0)
2951541Srgrimes
29624935Sphk#define LIST_NEXT(elm, field)	((elm)->field.le_next)
29724935Sphk
29833793Sjulian#define LIST_REMOVE(elm, field) do {					\
2991541Srgrimes	if ((elm)->field.le_next != NULL)				\
3001541Srgrimes		(elm)->field.le_next->field.le_prev = 			\
3011541Srgrimes		    (elm)->field.le_prev;				\
3021541Srgrimes	*(elm)->field.le_prev = (elm)->field.le_next;			\
30333793Sjulian} while (0)
3041541Srgrimes
3051541Srgrimes/*
3061541Srgrimes * Tail queue definitions.
3071541Srgrimes */
3081541Srgrimes#define TAILQ_HEAD(name, type)						\
3091541Srgrimesstruct name {								\
3101541Srgrimes	struct type *tqh_first;	/* first element */			\
3111541Srgrimes	struct type **tqh_last;	/* addr of last next element */		\
3121541Srgrimes}
3131541Srgrimes
31429683Sgibbs#define TAILQ_HEAD_INITIALIZER(head)					\
31529683Sgibbs	{ NULL, &(head).tqh_first }
31629683Sgibbs
3171541Srgrimes#define TAILQ_ENTRY(type)						\
3181541Srgrimesstruct {								\
3191541Srgrimes	struct type *tqe_next;	/* next element */			\
3201541Srgrimes	struct type **tqe_prev;	/* address of previous next element */	\
3211541Srgrimes}
3221541Srgrimes
3231541Srgrimes/*
3241541Srgrimes * Tail queue functions.
3251541Srgrimes */
32615138Sphk#define	TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
32715138Sphk
32825188Sphk#define TAILQ_FOREACH(var, head, field)					\
32925188Sphk	for (var = TAILQ_FIRST(head); var; var = TAILQ_NEXT(var, field))
33025188Sphk
33115138Sphk#define	TAILQ_FIRST(head) ((head)->tqh_first)
33215138Sphk
33333793Sjulian#define	TAILQ_LAST(head, headname) \
33433793Sjulian	(*(((struct headname *)((head)->tqh_last))->tqh_last))
33515138Sphk
33615809Sdyson#define	TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
33715138Sphk
33833793Sjulian#define TAILQ_PREV(elm, headname, field) \
33933793Sjulian	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
34015809Sdyson
34133793Sjulian#define	TAILQ_INIT(head) do {						\
3421541Srgrimes	(head)->tqh_first = NULL;					\
3431541Srgrimes	(head)->tqh_last = &(head)->tqh_first;				\
34433793Sjulian} while (0)
3451541Srgrimes
34633793Sjulian#define TAILQ_INSERT_HEAD(head, elm, field) do {			\
3471541Srgrimes	if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)	\
34814492Shsu		(head)->tqh_first->field.tqe_prev =			\
3491541Srgrimes		    &(elm)->field.tqe_next;				\
3501541Srgrimes	else								\
3511541Srgrimes		(head)->tqh_last = &(elm)->field.tqe_next;		\
3521541Srgrimes	(head)->tqh_first = (elm);					\
3531541Srgrimes	(elm)->field.tqe_prev = &(head)->tqh_first;			\
35433793Sjulian} while (0)
3551541Srgrimes
35633793Sjulian#define TAILQ_INSERT_TAIL(head, elm, field) do {			\
3571541Srgrimes	(elm)->field.tqe_next = NULL;					\
3581541Srgrimes	(elm)->field.tqe_prev = (head)->tqh_last;			\
3591541Srgrimes	*(head)->tqh_last = (elm);					\
3601541Srgrimes	(head)->tqh_last = &(elm)->field.tqe_next;			\
36133793Sjulian} while (0)
3621541Srgrimes
36333793Sjulian#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
3641541Srgrimes	if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
3651541Srgrimes		(elm)->field.tqe_next->field.tqe_prev = 		\
3661541Srgrimes		    &(elm)->field.tqe_next;				\
3671541Srgrimes	else								\
3681541Srgrimes		(head)->tqh_last = &(elm)->field.tqe_next;		\
3691541Srgrimes	(listelm)->field.tqe_next = (elm);				\
3701541Srgrimes	(elm)->field.tqe_prev = &(listelm)->field.tqe_next;		\
37133793Sjulian} while (0)
3721541Srgrimes
37333793Sjulian#define TAILQ_INSERT_BEFORE(listelm, elm, field) do {			\
37413697Sgibbs	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
37513697Sgibbs	(elm)->field.tqe_next = (listelm);				\
37613697Sgibbs	*(listelm)->field.tqe_prev = (elm);				\
37713697Sgibbs	(listelm)->field.tqe_prev = &(elm)->field.tqe_next;		\
37833793Sjulian} while (0)
37913697Sgibbs
38033793Sjulian#define TAILQ_REMOVE(head, elm, field) do {				\
3811541Srgrimes	if (((elm)->field.tqe_next) != NULL)				\
3821541Srgrimes		(elm)->field.tqe_next->field.tqe_prev = 		\
3831541Srgrimes		    (elm)->field.tqe_prev;				\
3841541Srgrimes	else								\
3851541Srgrimes		(head)->tqh_last = (elm)->field.tqe_prev;		\
3861541Srgrimes	*(elm)->field.tqe_prev = (elm)->field.tqe_next;			\
38733793Sjulian} while (0)
3881541Srgrimes
3891541Srgrimes/*
3901541Srgrimes * Circular queue definitions.
3911541Srgrimes */
3921541Srgrimes#define CIRCLEQ_HEAD(name, type)					\
3931541Srgrimesstruct name {								\
3941541Srgrimes	struct type *cqh_first;		/* first element */		\
3951541Srgrimes	struct type *cqh_last;		/* last element */		\
3961541Srgrimes}
3971541Srgrimes
3981541Srgrimes#define CIRCLEQ_ENTRY(type)						\
3991541Srgrimesstruct {								\
4001541Srgrimes	struct type *cqe_next;		/* next element */		\
4011541Srgrimes	struct type *cqe_prev;		/* previous element */		\
4021541Srgrimes}
4031541Srgrimes
4041541Srgrimes/*
4051541Srgrimes * Circular queue functions.
4061541Srgrimes */
40730897Sgibbs#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
40825188Sphk
40925188Sphk#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
41025188Sphk
41125188Sphk#define CIRCLEQ_FOREACH(var, head, field)				\
41235957Sgibbs	for((var) = (head)->cqh_first;					\
41335957Sgibbs	    (var) != (void *)(head);					\
41435957Sgibbs	    (var) = (var)->field.cqe_next)
41525188Sphk
41633793Sjulian#define	CIRCLEQ_INIT(head) do {						\
4171541Srgrimes	(head)->cqh_first = (void *)(head);				\
4181541Srgrimes	(head)->cqh_last = (void *)(head);				\
41933793Sjulian} while (0)
4201541Srgrimes
42133793Sjulian#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
4221541Srgrimes	(elm)->field.cqe_next = (listelm)->field.cqe_next;		\
4231541Srgrimes	(elm)->field.cqe_prev = (listelm);				\
4241541Srgrimes	if ((listelm)->field.cqe_next == (void *)(head))		\
4251541Srgrimes		(head)->cqh_last = (elm);				\
4261541Srgrimes	else								\
4271541Srgrimes		(listelm)->field.cqe_next->field.cqe_prev = (elm);	\
4281541Srgrimes	(listelm)->field.cqe_next = (elm);				\
42933793Sjulian} while (0)
4301541Srgrimes
43133793Sjulian#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {		\
4321541Srgrimes	(elm)->field.cqe_next = (listelm);				\
4331541Srgrimes	(elm)->field.cqe_prev = (listelm)->field.cqe_prev;		\
4341541Srgrimes	if ((listelm)->field.cqe_prev == (void *)(head))		\
4351541Srgrimes		(head)->cqh_first = (elm);				\
4361541Srgrimes	else								\
4371541Srgrimes		(listelm)->field.cqe_prev->field.cqe_next = (elm);	\
4381541Srgrimes	(listelm)->field.cqe_prev = (elm);				\
43933793Sjulian} while (0)
4401541Srgrimes
44133793Sjulian#define CIRCLEQ_INSERT_HEAD(head, elm, field) do {			\
4421541Srgrimes	(elm)->field.cqe_next = (head)->cqh_first;			\
4431541Srgrimes	(elm)->field.cqe_prev = (void *)(head);				\
4441541Srgrimes	if ((head)->cqh_last == (void *)(head))				\
4451541Srgrimes		(head)->cqh_last = (elm);				\
4461541Srgrimes	else								\
4471541Srgrimes		(head)->cqh_first->field.cqe_prev = (elm);		\
4481541Srgrimes	(head)->cqh_first = (elm);					\
44933793Sjulian} while (0)
4501541Srgrimes
45133793Sjulian#define CIRCLEQ_INSERT_TAIL(head, elm, field) do {			\
4521541Srgrimes	(elm)->field.cqe_next = (void *)(head);				\
4531541Srgrimes	(elm)->field.cqe_prev = (head)->cqh_last;			\
4541541Srgrimes	if ((head)->cqh_first == (void *)(head))			\
4551541Srgrimes		(head)->cqh_first = (elm);				\
4561541Srgrimes	else								\
4571541Srgrimes		(head)->cqh_last->field.cqe_next = (elm);		\
4581541Srgrimes	(head)->cqh_last = (elm);					\
45933793Sjulian} while (0)
4601541Srgrimes
46125188Sphk#define CIRCLEQ_LAST(head) ((head)->cqh_last)
46225188Sphk
46325188Sphk#define CIRCLEQ_NEXT(elm,field) ((elm)->field.cqe_next)
46425188Sphk
46525188Sphk#define CIRCLEQ_PREV(elm,field) ((elm)->field.cqe_prev)
46625188Sphk
46733793Sjulian#define	CIRCLEQ_REMOVE(head, elm, field) do {				\
4681541Srgrimes	if ((elm)->field.cqe_next == (void *)(head))			\
4691541Srgrimes		(head)->cqh_last = (elm)->field.cqe_prev;		\
4701541Srgrimes	else								\
4711541Srgrimes		(elm)->field.cqe_next->field.cqe_prev =			\
4721541Srgrimes		    (elm)->field.cqe_prev;				\
4731541Srgrimes	if ((elm)->field.cqe_prev == (void *)(head))			\
4741541Srgrimes		(head)->cqh_first = (elm)->field.cqe_next;		\
4751541Srgrimes	else								\
4761541Srgrimes		(elm)->field.cqe_prev->field.cqe_next =			\
4771541Srgrimes		    (elm)->field.cqe_next;				\
47833793Sjulian} while (0)
47912592Sbde
48012592Sbde#ifdef KERNEL
48112592Sbde
48212592Sbde/*
48312592Sbde * XXX insque() and remque() are an old way of handling certain queues.
48412592Sbde * They bogusly assumes that all queue heads look alike.
48512592Sbde */
48612592Sbde
48712592Sbdestruct quehead {
48812592Sbde	struct quehead *qh_link;
48912592Sbde	struct quehead *qh_rlink;
49012592Sbde};
49112592Sbde
49212592Sbde#ifdef	__GNUC__
49312592Sbde
49412592Sbdestatic __inline void
49512592Sbdeinsque(void *a, void *b)
49612592Sbde{
49712592Sbde	struct quehead *element = a, *head = b;
49812592Sbde
49912592Sbde	element->qh_link = head->qh_link;
50012592Sbde	element->qh_rlink = head;
50112592Sbde	head->qh_link = element;
50212592Sbde	element->qh_link->qh_rlink = element;
50312592Sbde}
50412592Sbde
50512592Sbdestatic __inline void
50612592Sbderemque(void *a)
50712592Sbde{
50812592Sbde	struct quehead *element = a;
50912592Sbde
51012592Sbde	element->qh_link->qh_rlink = element->qh_rlink;
51112592Sbde	element->qh_rlink->qh_link = element->qh_link;
51212592Sbde	element->qh_rlink = 0;
51312592Sbde}
51412592Sbde
51512592Sbde#else /* !__GNUC__ */
51612592Sbde
51712592Sbdevoid	insque __P((void *a, void *b));
51812592Sbdevoid	remque __P((void *a));
51912592Sbde
52012592Sbde#endif /* __GNUC__ */
52112592Sbde
52212592Sbde#endif /* KERNEL */
52312592Sbde
52412592Sbde#endif /* !_SYS_QUEUE_H_ */
525