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