1290001Sglebius/*	$OpenBSD: queue.h,v 1.16 2000/09/07 19:47:59 art Exp $	*/
2290001Sglebius/*	$NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $	*/
3290001Sglebius
4290001Sglebius/*
5290001Sglebius * Copyright (c) 1991, 1993
6290001Sglebius *	The Regents of the University of California.  All rights reserved.
7290001Sglebius *
8290001Sglebius * Redistribution and use in source and binary forms, with or without
9290001Sglebius * modification, are permitted provided that the following conditions
10290001Sglebius * are met:
11290001Sglebius * 1. Redistributions of source code must retain the above copyright
12290001Sglebius *    notice, this list of conditions and the following disclaimer.
13290001Sglebius * 2. Redistributions in binary form must reproduce the above copyright
14290001Sglebius *    notice, this list of conditions and the following disclaimer in the
15290001Sglebius *    documentation and/or other materials provided with the distribution.
16290001Sglebius * 3. Neither the name of the University nor the names of its contributors
17290001Sglebius *    may be used to endorse or promote products derived from this software
18290001Sglebius *    without specific prior written permission.
19290001Sglebius *
20290001Sglebius * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21290001Sglebius * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22290001Sglebius * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23290001Sglebius * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24290001Sglebius * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25290001Sglebius * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26290001Sglebius * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27290001Sglebius * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28290001Sglebius * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29290001Sglebius * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30290001Sglebius * SUCH DAMAGE.
31290001Sglebius *
32290001Sglebius *	@(#)queue.h	8.5 (Berkeley) 8/20/94
33290001Sglebius */
34290001Sglebius
35290001Sglebius#ifndef	SYS_QUEUE_H__
36290001Sglebius#define	SYS_QUEUE_H__
37290001Sglebius
38290001Sglebius/*
39290001Sglebius * This file defines five types of data structures: singly-linked lists,
40290001Sglebius * lists, simple queues, tail queues, and circular queues.
41290001Sglebius *
42290001Sglebius *
43290001Sglebius * A singly-linked list is headed by a single forward pointer. The elements
44290001Sglebius * are singly linked for minimum space and pointer manipulation overhead at
45290001Sglebius * the expense of O(n) removal for arbitrary elements. New elements can be
46290001Sglebius * added to the list after an existing element or at the head of the list.
47290001Sglebius * Elements being removed from the head of the list should use the explicit
48290001Sglebius * macro for this purpose for optimum efficiency. A singly-linked list may
49290001Sglebius * only be traversed in the forward direction.  Singly-linked lists are ideal
50290001Sglebius * for applications with large datasets and few or no removals or for
51290001Sglebius * implementing a LIFO queue.
52290001Sglebius *
53290001Sglebius * A list is headed by a single forward pointer (or an array of forward
54290001Sglebius * pointers for a hash table header). The elements are doubly linked
55290001Sglebius * so that an arbitrary element can be removed without a need to
56290001Sglebius * traverse the list. New elements can be added to the list before
57290001Sglebius * or after an existing element or at the head of the list. A list
58290001Sglebius * may only be traversed in the forward direction.
59290001Sglebius *
60290001Sglebius * A simple queue is headed by a pair of pointers, one the head of the
61290001Sglebius * list and the other to the tail of the list. The elements are singly
62290001Sglebius * linked to save space, so elements can only be removed from the
63290001Sglebius * head of the list. New elements can be added to the list before or after
64290001Sglebius * an existing element, at the head of the list, or at the end of the
65290001Sglebius * list. A simple queue may only be traversed in the forward direction.
66290001Sglebius *
67290001Sglebius * A tail queue is headed by a pair of pointers, one to the head of the
68290001Sglebius * list and the other to the tail of the list. The elements are doubly
69290001Sglebius * linked so that an arbitrary element can be removed without a need to
70290001Sglebius * traverse the list. New elements can be added to the list before or
71290001Sglebius * after an existing element, at the head of the list, or at the end of
72290001Sglebius * the list. A tail queue may be traversed in either direction.
73290001Sglebius *
74290001Sglebius * A circle queue is headed by a pair of pointers, one to the head of the
75290001Sglebius * list and the other to the tail of the list. The elements are doubly
76290001Sglebius * linked so that an arbitrary element can be removed without a need to
77290001Sglebius * traverse the list. New elements can be added to the list before or after
78290001Sglebius * an existing element, at the head of the list, or at the end of the list.
79290001Sglebius * A circle queue may be traversed in either direction, but has a more
80290001Sglebius * complex end of list detection.
81290001Sglebius *
82290001Sglebius * For details on the use of these macros, see the queue(3) manual page.
83290001Sglebius */
84290001Sglebius
85290001Sglebius/*
86290001Sglebius * Singly-linked List definitions.
87290001Sglebius */
88290001Sglebius#define SLIST_HEAD(name, type)						\
89290001Sglebiusstruct name {								\
90290001Sglebius	struct type *slh_first;	/* first element */			\
91290001Sglebius}
92290001Sglebius
93290001Sglebius#define	SLIST_HEAD_INITIALIZER(head)					\
94290001Sglebius	{ NULL }
95290001Sglebius
96290001Sglebius#ifndef _WIN32
97290001Sglebius#define SLIST_ENTRY(type)						\
98290001Sglebiusstruct {								\
99290001Sglebius	struct type *sle_next;	/* next element */			\
100290001Sglebius}
101290001Sglebius#endif
102290001Sglebius
103290001Sglebius/*
104290001Sglebius * Singly-linked List access methods.
105290001Sglebius */
106290001Sglebius#define	SLIST_FIRST(head)	((head)->slh_first)
107290001Sglebius#define	SLIST_END(head)		NULL
108290001Sglebius#define	SLIST_EMPTY(head)	(SLIST_FIRST(head) == SLIST_END(head))
109290001Sglebius#define	SLIST_NEXT(elm, field)	((elm)->field.sle_next)
110290001Sglebius
111290001Sglebius#define	SLIST_FOREACH(var, head, field)					\
112290001Sglebius	for((var) = SLIST_FIRST(head);					\
113290001Sglebius	    (var) != SLIST_END(head);					\
114290001Sglebius	    (var) = SLIST_NEXT(var, field))
115290001Sglebius
116290001Sglebius/*
117290001Sglebius * Singly-linked List functions.
118290001Sglebius */
119290001Sglebius#define	SLIST_INIT(head) {						\
120290001Sglebius	SLIST_FIRST(head) = SLIST_END(head);				\
121290001Sglebius}
122290001Sglebius
123290001Sglebius#define	SLIST_INSERT_AFTER(slistelm, elm, field) do {			\
124290001Sglebius	(elm)->field.sle_next = (slistelm)->field.sle_next;		\
125290001Sglebius	(slistelm)->field.sle_next = (elm);				\
126290001Sglebius} while (0)
127290001Sglebius
128290001Sglebius#define	SLIST_INSERT_HEAD(head, elm, field) do {			\
129290001Sglebius	(elm)->field.sle_next = (head)->slh_first;			\
130290001Sglebius	(head)->slh_first = (elm);					\
131290001Sglebius} while (0)
132290001Sglebius
133290001Sglebius#define	SLIST_REMOVE_HEAD(head, field) do {				\
134290001Sglebius	(head)->slh_first = (head)->slh_first->field.sle_next;		\
135290001Sglebius} while (0)
136290001Sglebius
137290001Sglebius/*
138290001Sglebius * List definitions.
139290001Sglebius */
140290001Sglebius#define LIST_HEAD(name, type)						\
141290001Sglebiusstruct name {								\
142290001Sglebius	struct type *lh_first;	/* first element */			\
143290001Sglebius}
144290001Sglebius
145290001Sglebius#define LIST_HEAD_INITIALIZER(head)					\
146290001Sglebius	{ NULL }
147290001Sglebius
148290001Sglebius#define LIST_ENTRY(type)						\
149290001Sglebiusstruct {								\
150290001Sglebius	struct type *le_next;	/* next element */			\
151290001Sglebius	struct type **le_prev;	/* address of previous next element */	\
152290001Sglebius}
153290001Sglebius
154290001Sglebius/*
155290001Sglebius * List access methods
156290001Sglebius */
157290001Sglebius#define	LIST_FIRST(head)		((head)->lh_first)
158290001Sglebius#define	LIST_END(head)			NULL
159290001Sglebius#define	LIST_EMPTY(head)		(LIST_FIRST(head) == LIST_END(head))
160290001Sglebius#define	LIST_NEXT(elm, field)		((elm)->field.le_next)
161290001Sglebius
162290001Sglebius#define LIST_FOREACH(var, head, field)					\
163290001Sglebius	for((var) = LIST_FIRST(head);					\
164290001Sglebius	    (var)!= LIST_END(head);					\
165290001Sglebius	    (var) = LIST_NEXT(var, field))
166290001Sglebius
167290001Sglebius/*
168290001Sglebius * List functions.
169290001Sglebius */
170290001Sglebius#define	LIST_INIT(head) do {						\
171290001Sglebius	LIST_FIRST(head) = LIST_END(head);				\
172290001Sglebius} while (0)
173290001Sglebius
174290001Sglebius#define LIST_INSERT_AFTER(listelm, elm, field) do {			\
175290001Sglebius	if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)	\
176290001Sglebius		(listelm)->field.le_next->field.le_prev =		\
177290001Sglebius		    &(elm)->field.le_next;				\
178290001Sglebius	(listelm)->field.le_next = (elm);				\
179290001Sglebius	(elm)->field.le_prev = &(listelm)->field.le_next;		\
180290001Sglebius} while (0)
181290001Sglebius
182290001Sglebius#define	LIST_INSERT_BEFORE(listelm, elm, field) do {			\
183290001Sglebius	(elm)->field.le_prev = (listelm)->field.le_prev;		\
184290001Sglebius	(elm)->field.le_next = (listelm);				\
185290001Sglebius	*(listelm)->field.le_prev = (elm);				\
186290001Sglebius	(listelm)->field.le_prev = &(elm)->field.le_next;		\
187290001Sglebius} while (0)
188290001Sglebius
189290001Sglebius#define LIST_INSERT_HEAD(head, elm, field) do {				\
190290001Sglebius	if (((elm)->field.le_next = (head)->lh_first) != NULL)		\
191290001Sglebius		(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
192290001Sglebius	(head)->lh_first = (elm);					\
193290001Sglebius	(elm)->field.le_prev = &(head)->lh_first;			\
194290001Sglebius} while (0)
195290001Sglebius
196290001Sglebius#define LIST_REMOVE(elm, field) do {					\
197290001Sglebius	if ((elm)->field.le_next != NULL)				\
198290001Sglebius		(elm)->field.le_next->field.le_prev =			\
199290001Sglebius		    (elm)->field.le_prev;				\
200290001Sglebius	*(elm)->field.le_prev = (elm)->field.le_next;			\
201290001Sglebius} while (0)
202290001Sglebius
203290001Sglebius#define LIST_REPLACE(elm, elm2, field) do {				\
204290001Sglebius	if (((elm2)->field.le_next = (elm)->field.le_next) != NULL)	\
205290001Sglebius		(elm2)->field.le_next->field.le_prev =			\
206290001Sglebius		    &(elm2)->field.le_next;				\
207290001Sglebius	(elm2)->field.le_prev = (elm)->field.le_prev;			\
208290001Sglebius	*(elm2)->field.le_prev = (elm2);				\
209290001Sglebius} while (0)
210290001Sglebius
211290001Sglebius/*
212290001Sglebius * Simple queue definitions.
213290001Sglebius */
214290001Sglebius#define SIMPLEQ_HEAD(name, type)					\
215290001Sglebiusstruct name {								\
216290001Sglebius	struct type *sqh_first;	/* first element */			\
217290001Sglebius	struct type **sqh_last;	/* addr of last next element */		\
218290001Sglebius}
219290001Sglebius
220290001Sglebius#define SIMPLEQ_HEAD_INITIALIZER(head)					\
221290001Sglebius	{ NULL, &(head).sqh_first }
222290001Sglebius
223290001Sglebius#define SIMPLEQ_ENTRY(type)						\
224290001Sglebiusstruct {								\
225290001Sglebius	struct type *sqe_next;	/* next element */			\
226290001Sglebius}
227290001Sglebius
228290001Sglebius/*
229290001Sglebius * Simple queue access methods.
230290001Sglebius */
231290001Sglebius#define	SIMPLEQ_FIRST(head)	    ((head)->sqh_first)
232290001Sglebius#define	SIMPLEQ_END(head)	    NULL
233290001Sglebius#define	SIMPLEQ_EMPTY(head)	    (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
234290001Sglebius#define	SIMPLEQ_NEXT(elm, field)    ((elm)->field.sqe_next)
235290001Sglebius
236290001Sglebius#define SIMPLEQ_FOREACH(var, head, field)				\
237290001Sglebius	for((var) = SIMPLEQ_FIRST(head);				\
238290001Sglebius	    (var) != SIMPLEQ_END(head);					\
239290001Sglebius	    (var) = SIMPLEQ_NEXT(var, field))
240290001Sglebius
241290001Sglebius/*
242290001Sglebius * Simple queue functions.
243290001Sglebius */
244290001Sglebius#define	SIMPLEQ_INIT(head) do {						\
245290001Sglebius	(head)->sqh_first = NULL;					\
246290001Sglebius	(head)->sqh_last = &(head)->sqh_first;				\
247290001Sglebius} while (0)
248290001Sglebius
249290001Sglebius#define SIMPLEQ_INSERT_HEAD(head, elm, field) do {			\
250290001Sglebius	if (((elm)->field.sqe_next = (head)->sqh_first) == NULL)	\
251290001Sglebius		(head)->sqh_last = &(elm)->field.sqe_next;		\
252290001Sglebius	(head)->sqh_first = (elm);					\
253290001Sglebius} while (0)
254290001Sglebius
255290001Sglebius#define SIMPLEQ_INSERT_TAIL(head, elm, field) do {			\
256290001Sglebius	(elm)->field.sqe_next = NULL;					\
257290001Sglebius	*(head)->sqh_last = (elm);					\
258290001Sglebius	(head)->sqh_last = &(elm)->field.sqe_next;			\
259290001Sglebius} while (0)
260290001Sglebius
261290001Sglebius#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
262290001Sglebius	if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
263290001Sglebius		(head)->sqh_last = &(elm)->field.sqe_next;		\
264290001Sglebius	(listelm)->field.sqe_next = (elm);				\
265290001Sglebius} while (0)
266290001Sglebius
267290001Sglebius#define SIMPLEQ_REMOVE_HEAD(head, elm, field) do {			\
268290001Sglebius	if (((head)->sqh_first = (elm)->field.sqe_next) == NULL)	\
269290001Sglebius		(head)->sqh_last = &(head)->sqh_first;			\
270290001Sglebius} while (0)
271290001Sglebius
272290001Sglebius/*
273290001Sglebius * Tail queue definitions.
274290001Sglebius */
275290001Sglebius#define TAILQ_HEAD(name, type)						\
276290001Sglebiusstruct name {								\
277290001Sglebius	struct type *tqh_first;	/* first element */			\
278290001Sglebius	struct type **tqh_last;	/* addr of last next element */		\
279290001Sglebius}
280290001Sglebius
281290001Sglebius#define TAILQ_HEAD_INITIALIZER(head)					\
282290001Sglebius	{ NULL, &(head).tqh_first }
283290001Sglebius
284290001Sglebius#define TAILQ_ENTRY(type)						\
285290001Sglebiusstruct {								\
286290001Sglebius	struct type *tqe_next;	/* next element */			\
287290001Sglebius	struct type **tqe_prev;	/* address of previous next element */	\
288290001Sglebius}
289290001Sglebius
290290001Sglebius/*
291290001Sglebius * tail queue access methods
292290001Sglebius */
293290001Sglebius#define	TAILQ_FIRST(head)		((head)->tqh_first)
294290001Sglebius#define	TAILQ_END(head)			NULL
295290001Sglebius#define	TAILQ_NEXT(elm, field)		((elm)->field.tqe_next)
296290001Sglebius#define TAILQ_LAST(head, headname)					\
297290001Sglebius	(*(((struct headname *)((head)->tqh_last))->tqh_last))
298290001Sglebius/* XXX */
299290001Sglebius#define TAILQ_PREV(elm, headname, field)				\
300290001Sglebius	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
301290001Sglebius#define	TAILQ_EMPTY(head)						\
302290001Sglebius	(TAILQ_FIRST(head) == TAILQ_END(head))
303290001Sglebius
304290001Sglebius#define TAILQ_FOREACH(var, head, field)					\
305290001Sglebius	for((var) = TAILQ_FIRST(head);					\
306290001Sglebius	    (var) != TAILQ_END(head);					\
307290001Sglebius	    (var) = TAILQ_NEXT(var, field))
308290001Sglebius
309290001Sglebius#define TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
310290001Sglebius	for((var) = TAILQ_LAST(head, headname);				\
311290001Sglebius	    (var) != TAILQ_END(head);					\
312290001Sglebius	    (var) = TAILQ_PREV(var, headname, field))
313290001Sglebius
314290001Sglebius/*
315290001Sglebius * Tail queue functions.
316290001Sglebius */
317290001Sglebius#define	TAILQ_INIT(head) do {						\
318290001Sglebius	(head)->tqh_first = NULL;					\
319290001Sglebius	(head)->tqh_last = &(head)->tqh_first;				\
320290001Sglebius} while (0)
321290001Sglebius
322290001Sglebius#define TAILQ_INSERT_HEAD(head, elm, field) do {			\
323290001Sglebius	if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)	\
324290001Sglebius		(head)->tqh_first->field.tqe_prev =			\
325290001Sglebius		    &(elm)->field.tqe_next;				\
326290001Sglebius	else								\
327290001Sglebius		(head)->tqh_last = &(elm)->field.tqe_next;		\
328290001Sglebius	(head)->tqh_first = (elm);					\
329290001Sglebius	(elm)->field.tqe_prev = &(head)->tqh_first;			\
330290001Sglebius} while (0)
331290001Sglebius
332290001Sglebius#define TAILQ_INSERT_TAIL(head, elm, field) do {			\
333290001Sglebius	(elm)->field.tqe_next = NULL;					\
334290001Sglebius	(elm)->field.tqe_prev = (head)->tqh_last;			\
335290001Sglebius	*(head)->tqh_last = (elm);					\
336290001Sglebius	(head)->tqh_last = &(elm)->field.tqe_next;			\
337290001Sglebius} while (0)
338290001Sglebius
339290001Sglebius#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
340290001Sglebius	if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
341290001Sglebius		(elm)->field.tqe_next->field.tqe_prev =			\
342290001Sglebius		    &(elm)->field.tqe_next;				\
343290001Sglebius	else								\
344290001Sglebius		(head)->tqh_last = &(elm)->field.tqe_next;		\
345290001Sglebius	(listelm)->field.tqe_next = (elm);				\
346290001Sglebius	(elm)->field.tqe_prev = &(listelm)->field.tqe_next;		\
347290001Sglebius} while (0)
348290001Sglebius
349290001Sglebius#define	TAILQ_INSERT_BEFORE(listelm, elm, field) do {			\
350290001Sglebius	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
351290001Sglebius	(elm)->field.tqe_next = (listelm);				\
352290001Sglebius	*(listelm)->field.tqe_prev = (elm);				\
353290001Sglebius	(listelm)->field.tqe_prev = &(elm)->field.tqe_next;		\
354290001Sglebius} while (0)
355290001Sglebius
356290001Sglebius#define TAILQ_REMOVE(head, elm, field) do {				\
357290001Sglebius	if (((elm)->field.tqe_next) != NULL)				\
358290001Sglebius		(elm)->field.tqe_next->field.tqe_prev =			\
359290001Sglebius		    (elm)->field.tqe_prev;				\
360290001Sglebius	else								\
361290001Sglebius		(head)->tqh_last = (elm)->field.tqe_prev;		\
362290001Sglebius	*(elm)->field.tqe_prev = (elm)->field.tqe_next;			\
363290001Sglebius} while (0)
364290001Sglebius
365290001Sglebius#define TAILQ_REPLACE(head, elm, elm2, field) do {			\
366290001Sglebius	if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL)	\
367290001Sglebius		(elm2)->field.tqe_next->field.tqe_prev =		\
368290001Sglebius		    &(elm2)->field.tqe_next;				\
369290001Sglebius	else								\
370290001Sglebius		(head)->tqh_last = &(elm2)->field.tqe_next;		\
371290001Sglebius	(elm2)->field.tqe_prev = (elm)->field.tqe_prev;			\
372290001Sglebius	*(elm2)->field.tqe_prev = (elm2);				\
373290001Sglebius} while (0)
374290001Sglebius
375290001Sglebius/*
376290001Sglebius * Circular queue definitions.
377290001Sglebius */
378290001Sglebius#define CIRCLEQ_HEAD(name, type)					\
379290001Sglebiusstruct name {								\
380290001Sglebius	struct type *cqh_first;		/* first element */		\
381290001Sglebius	struct type *cqh_last;		/* last element */		\
382290001Sglebius}
383290001Sglebius
384290001Sglebius#define CIRCLEQ_HEAD_INITIALIZER(head)					\
385290001Sglebius	{ CIRCLEQ_END(&head), CIRCLEQ_END(&head) }
386290001Sglebius
387290001Sglebius#define CIRCLEQ_ENTRY(type)						\
388290001Sglebiusstruct {								\
389290001Sglebius	struct type *cqe_next;		/* next element */		\
390290001Sglebius	struct type *cqe_prev;		/* previous element */		\
391290001Sglebius}
392290001Sglebius
393290001Sglebius/*
394290001Sglebius * Circular queue access methods
395290001Sglebius */
396290001Sglebius#define	CIRCLEQ_FIRST(head)		((head)->cqh_first)
397290001Sglebius#define	CIRCLEQ_LAST(head)		((head)->cqh_last)
398290001Sglebius#define	CIRCLEQ_END(head)		((void *)(head))
399290001Sglebius#define	CIRCLEQ_NEXT(elm, field)	((elm)->field.cqe_next)
400290001Sglebius#define	CIRCLEQ_PREV(elm, field)	((elm)->field.cqe_prev)
401290001Sglebius#define	CIRCLEQ_EMPTY(head)						\
402290001Sglebius	(CIRCLEQ_FIRST(head) == CIRCLEQ_END(head))
403290001Sglebius
404290001Sglebius#define CIRCLEQ_FOREACH(var, head, field)				\
405290001Sglebius	for((var) = CIRCLEQ_FIRST(head);				\
406290001Sglebius	    (var) != CIRCLEQ_END(head);					\
407290001Sglebius	    (var) = CIRCLEQ_NEXT(var, field))
408290001Sglebius
409290001Sglebius#define CIRCLEQ_FOREACH_REVERSE(var, head, field)			\
410290001Sglebius	for((var) = CIRCLEQ_LAST(head);					\
411290001Sglebius	    (var) != CIRCLEQ_END(head);					\
412290001Sglebius	    (var) = CIRCLEQ_PREV(var, field))
413290001Sglebius
414290001Sglebius/*
415290001Sglebius * Circular queue functions.
416290001Sglebius */
417290001Sglebius#define	CIRCLEQ_INIT(head) do {						\
418290001Sglebius	(head)->cqh_first = CIRCLEQ_END(head);				\
419290001Sglebius	(head)->cqh_last = CIRCLEQ_END(head);				\
420290001Sglebius} while (0)
421290001Sglebius
422290001Sglebius#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
423290001Sglebius	(elm)->field.cqe_next = (listelm)->field.cqe_next;		\
424290001Sglebius	(elm)->field.cqe_prev = (listelm);				\
425290001Sglebius	if ((listelm)->field.cqe_next == CIRCLEQ_END(head))		\
426290001Sglebius		(head)->cqh_last = (elm);				\
427290001Sglebius	else								\
428290001Sglebius		(listelm)->field.cqe_next->field.cqe_prev = (elm);	\
429290001Sglebius	(listelm)->field.cqe_next = (elm);				\
430290001Sglebius} while (0)
431290001Sglebius
432290001Sglebius#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {		\
433290001Sglebius	(elm)->field.cqe_next = (listelm);				\
434290001Sglebius	(elm)->field.cqe_prev = (listelm)->field.cqe_prev;		\
435290001Sglebius	if ((listelm)->field.cqe_prev == CIRCLEQ_END(head))		\
436290001Sglebius		(head)->cqh_first = (elm);				\
437290001Sglebius	else								\
438290001Sglebius		(listelm)->field.cqe_prev->field.cqe_next = (elm);	\
439290001Sglebius	(listelm)->field.cqe_prev = (elm);				\
440290001Sglebius} while (0)
441290001Sglebius
442290001Sglebius#define CIRCLEQ_INSERT_HEAD(head, elm, field) do {			\
443290001Sglebius	(elm)->field.cqe_next = (head)->cqh_first;			\
444290001Sglebius	(elm)->field.cqe_prev = CIRCLEQ_END(head);			\
445290001Sglebius	if ((head)->cqh_last == CIRCLEQ_END(head))			\
446290001Sglebius		(head)->cqh_last = (elm);				\
447290001Sglebius	else								\
448290001Sglebius		(head)->cqh_first->field.cqe_prev = (elm);		\
449290001Sglebius	(head)->cqh_first = (elm);					\
450290001Sglebius} while (0)
451290001Sglebius
452290001Sglebius#define CIRCLEQ_INSERT_TAIL(head, elm, field) do {			\
453290001Sglebius	(elm)->field.cqe_next = CIRCLEQ_END(head);			\
454290001Sglebius	(elm)->field.cqe_prev = (head)->cqh_last;			\
455290001Sglebius	if ((head)->cqh_first == CIRCLEQ_END(head))			\
456290001Sglebius		(head)->cqh_first = (elm);				\
457290001Sglebius	else								\
458290001Sglebius		(head)->cqh_last->field.cqe_next = (elm);		\
459290001Sglebius	(head)->cqh_last = (elm);					\
460290001Sglebius} while (0)
461290001Sglebius
462290001Sglebius#define	CIRCLEQ_REMOVE(head, elm, field) do {				\
463290001Sglebius	if ((elm)->field.cqe_next == CIRCLEQ_END(head))			\
464290001Sglebius		(head)->cqh_last = (elm)->field.cqe_prev;		\
465290001Sglebius	else								\
466290001Sglebius		(elm)->field.cqe_next->field.cqe_prev =			\
467290001Sglebius		    (elm)->field.cqe_prev;				\
468290001Sglebius	if ((elm)->field.cqe_prev == CIRCLEQ_END(head))			\
469290001Sglebius		(head)->cqh_first = (elm)->field.cqe_next;		\
470290001Sglebius	else								\
471290001Sglebius		(elm)->field.cqe_prev->field.cqe_next =			\
472290001Sglebius		    (elm)->field.cqe_next;				\
473290001Sglebius} while (0)
474290001Sglebius
475290001Sglebius#define CIRCLEQ_REPLACE(head, elm, elm2, field) do {			\
476290001Sglebius	if (((elm2)->field.cqe_next = (elm)->field.cqe_next) ==		\
477290001Sglebius	    CIRCLEQ_END(head))						\
478290001Sglebius		(head).cqh_last = (elm2);				\
479290001Sglebius	else								\
480290001Sglebius		(elm2)->field.cqe_next->field.cqe_prev = (elm2);	\
481290001Sglebius	if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) ==		\
482290001Sglebius	    CIRCLEQ_END(head))						\
483290001Sglebius		(head).cqh_first = (elm2);				\
484290001Sglebius	else								\
485290001Sglebius		(elm2)->field.cqe_prev->field.cqe_next = (elm2);	\
486290001Sglebius} while (0)
487290001Sglebius
488290001Sglebius#endif	/* !SYS_QUEUE_H__ */
489