1/*	$NetBSD: queue.h,v 1.31 2002/06/01 23:51:05 lukem Exp $	*/
2
3/*
4 * Copyright (c) 1991, 1993
5 *	The Regents of the University of California.  All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 *    must display the following acknowledgement:
17 *	This product includes software developed by the University of
18 *	California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 *    may be used to endorse or promote products derived from this software
21 *    without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 *	@(#)queue.h	8.5 (Berkeley) 8/20/94
36 */
37
38#ifndef	_SYS_QUEUE_H_
39#define	_SYS_QUEUE_H_
40
41/*
42 * This file defines five types of data structures: singly-linked lists,
43 * lists, simple queues, tail queues, and circular queues.
44 *
45 * A singly-linked list is headed by a single forward pointer. The
46 * elements are singly linked for minimum space and pointer manipulation
47 * overhead at the expense of O(n) removal for arbitrary elements. New
48 * elements can be added to the list after an existing element or at the
49 * head of the list.  Elements being removed from the head of the list
50 * should use the explicit macro for this purpose for optimum
51 * efficiency. A singly-linked list may only be traversed in the forward
52 * direction.  Singly-linked lists are ideal for applications with large
53 * datasets and few or no removals or for implementing a LIFO queue.
54 *
55 * A list is headed by a single forward pointer (or an array of forward
56 * pointers for a hash table header). The elements are doubly linked
57 * so that an arbitrary element can be removed without a need to
58 * traverse the list. New elements can be added to the list before
59 * or after an existing element or at the head of the list. A list
60 * may only be traversed in the forward direction.
61 *
62 * A simple queue is headed by a pair of pointers, one the head of the
63 * list and the other to the tail of the list. The elements are singly
64 * linked to save space, so only elements can only be removed from the
65 * head of the list. New elements can be added to the list after
66 * an existing element, at the head of the list, or at the end of the
67 * list. A simple queue may only be traversed in the forward direction.
68 *
69 * A tail queue is headed by a pair of pointers, one to the head of the
70 * list and the other to the tail of the list. The elements are doubly
71 * linked so that an arbitrary element can be removed without a need to
72 * traverse the list. New elements can be added to the list before or
73 * after an existing element, at the head of the list, or at the end of
74 * the list. A tail queue may be traversed in either direction.
75 *
76 * A circle queue is headed by a pair of pointers, one to the head of the
77 * list and the other to the tail of the list. The elements are doubly
78 * linked so that an arbitrary element can be removed without a need to
79 * traverse the list. New elements can be added to the list before or after
80 * an existing element, at the head of the list, or at the end of the list.
81 * A circle queue may be traversed in either direction, but has a more
82 * complex end of list detection.
83 *
84 * For details on the use of these macros, see the queue(3) manual page.
85 */
86
87/*
88 * List definitions.
89 */
90#define LIST_HEAD(name, type)						\
91struct name {								\
92	struct type *lh_first;	/* first element */			\
93}
94
95#define LIST_HEAD_INITIALIZER(head)					\
96	{ NULL }
97
98#define LIST_ENTRY(type)						\
99struct {								\
100	struct type *le_next;	/* next element */			\
101	struct type **le_prev;	/* address of previous next element */	\
102}
103
104/*
105 * List functions.
106 */
107#if defined(_KERNEL) && defined(QUEUEDEBUG)
108#define QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field)			\
109	if ((head)->lh_first &&						\
110	    (head)->lh_first->field.le_prev != &(head)->lh_first)	\
111		panic("LIST_INSERT_HEAD %p %s:%d", (head), __FILE__, __LINE__);
112#define QUEUEDEBUG_LIST_OP(elm, field)					\
113	if ((elm)->field.le_next &&					\
114	    (elm)->field.le_next->field.le_prev !=			\
115	    &(elm)->field.le_next)					\
116		panic("LIST_* forw %p %s:%d", (elm), __FILE__, __LINE__);\
117	if (*(elm)->field.le_prev != (elm))				\
118		panic("LIST_* back %p %s:%d", (elm), __FILE__, __LINE__);
119#define QUEUEDEBUG_LIST_POSTREMOVE(elm, field)				\
120	(elm)->field.le_next = (void *)1L;				\
121	(elm)->field.le_prev = (void *)1L;
122#else
123#define QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field)
124#define QUEUEDEBUG_LIST_OP(elm, field)
125#define QUEUEDEBUG_LIST_POSTREMOVE(elm, field)
126#endif
127
128#define	LIST_INIT(head) do {						\
129	(head)->lh_first = NULL;					\
130} while (/*CONSTCOND*/0)
131
132#define LIST_INSERT_AFTER(listelm, elm, field) do {			\
133	QUEUEDEBUG_LIST_OP((listelm), field)				\
134	if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)	\
135		(listelm)->field.le_next->field.le_prev =		\
136		    &(elm)->field.le_next;				\
137	(listelm)->field.le_next = (elm);				\
138	(elm)->field.le_prev = &(listelm)->field.le_next;		\
139} while (/*CONSTCOND*/0)
140
141#define	LIST_INSERT_BEFORE(listelm, elm, field) do {			\
142	QUEUEDEBUG_LIST_OP((listelm), field)				\
143	(elm)->field.le_prev = (listelm)->field.le_prev;		\
144	(elm)->field.le_next = (listelm);				\
145	*(listelm)->field.le_prev = (elm);				\
146	(listelm)->field.le_prev = &(elm)->field.le_next;		\
147} while (/*CONSTCOND*/0)
148
149#define LIST_INSERT_HEAD(head, elm, field) do {				\
150	QUEUEDEBUG_LIST_INSERT_HEAD((head), (elm), field)		\
151	if (((elm)->field.le_next = (head)->lh_first) != NULL)		\
152		(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
153	(head)->lh_first = (elm);					\
154	(elm)->field.le_prev = &(head)->lh_first;			\
155} while (/*CONSTCOND*/0)
156
157#define LIST_REMOVE(elm, field) do {					\
158	QUEUEDEBUG_LIST_OP((elm), field)				\
159	if ((elm)->field.le_next != NULL)				\
160		(elm)->field.le_next->field.le_prev = 			\
161		    (elm)->field.le_prev;				\
162	*(elm)->field.le_prev = (elm)->field.le_next;			\
163	QUEUEDEBUG_LIST_POSTREMOVE((elm), field)			\
164} while (/*CONSTCOND*/0)
165
166#define LIST_FOREACH(var, head, field)					\
167	for ((var) = ((head)->lh_first);				\
168		(var);							\
169		(var) = ((var)->field.le_next))
170
171/*
172 * List access methods.
173 */
174#define	LIST_EMPTY(head)		((head)->lh_first == NULL)
175#define	LIST_FIRST(head)		((head)->lh_first)
176#define	LIST_NEXT(elm, field)		((elm)->field.le_next)
177
178/*
179 * Singly-linked List definitions.
180 */
181#define SLIST_HEAD(name, type)						\
182struct name {								\
183	struct type *slh_first;	/* first element */			\
184}
185
186#define SLIST_HEAD_INITIALIZER(head)					\
187	{ NULL }
188
189#define SLIST_ENTRY(type)						\
190struct {								\
191	struct type *sle_next;	/* next element */			\
192}
193
194/*
195 * Singly-linked List functions.
196 */
197#define	SLIST_EMPTY(head)	((head)->slh_first == NULL)
198#define	SLIST_FIRST(head)	((head)->slh_first)
199#define	SLIST_NEXT(elm, field)	((elm)->field.sle_next)
200
201#define SLIST_FOREACH(var, head, field)					\
202	for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
203
204#define SLIST_INIT(head) do {						\
205	(head)->slh_first = NULL;					\
206} while (/*CONSTCOND*/0)
207
208#define SLIST_INSERT_AFTER(slistelm, elm, field) do {			\
209	(elm)->field.sle_next = (slistelm)->field.sle_next;		\
210	(slistelm)->field.sle_next = (elm);				\
211} while (/*CONSTCOND*/0)
212
213#define SLIST_INSERT_HEAD(head, elm, field) do {			\
214	(elm)->field.sle_next = (head)->slh_first;			\
215	(head)->slh_first = (elm);					\
216} while (/*CONSTCOND*/0)
217
218#define SLIST_NEXT(elm, field)	((elm)->field.sle_next)
219
220#define SLIST_REMOVE_HEAD(head, field) do {				\
221	(head)->slh_first = (head)->slh_first->field.sle_next;		\
222} while (/*CONSTCOND*/0)
223
224#define SLIST_REMOVE(head, elm, type, field) do {			\
225	if ((head)->slh_first == (elm)) {				\
226		SLIST_REMOVE_HEAD((head), field);			\
227	}								\
228	else {								\
229		struct type *curelm = (head)->slh_first;		\
230		while(curelm->field.sle_next != (elm))			\
231			curelm = curelm->field.sle_next;		\
232		curelm->field.sle_next =				\
233		    curelm->field.sle_next->field.sle_next;		\
234	}								\
235} while (/*CONSTCOND*/0)
236
237/*
238 * Simple queue definitions.
239 */
240#define SIMPLEQ_HEAD(name, type)					\
241struct name {								\
242	struct type *sqh_first;	/* first element */			\
243	struct type **sqh_last;	/* addr of last next element */		\
244}
245
246#define SIMPLEQ_HEAD_INITIALIZER(head)					\
247	{ NULL, &(head).sqh_first }
248
249#define SIMPLEQ_ENTRY(type)						\
250struct {								\
251	struct type *sqe_next;	/* next element */			\
252}
253
254/*
255 * Simple queue functions.
256 */
257#define	SIMPLEQ_INIT(head) do {						\
258	(head)->sqh_first = NULL;					\
259	(head)->sqh_last = &(head)->sqh_first;				\
260} while (/*CONSTCOND*/0)
261
262#define SIMPLEQ_INSERT_HEAD(head, elm, field) do {			\
263	if (((elm)->field.sqe_next = (head)->sqh_first) == NULL)	\
264		(head)->sqh_last = &(elm)->field.sqe_next;		\
265	(head)->sqh_first = (elm);					\
266} while (/*CONSTCOND*/0)
267
268#define SIMPLEQ_INSERT_TAIL(head, elm, field) do {			\
269	(elm)->field.sqe_next = NULL;					\
270	*(head)->sqh_last = (elm);					\
271	(head)->sqh_last = &(elm)->field.sqe_next;			\
272} while (/*CONSTCOND*/0)
273
274#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
275	if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
276		(head)->sqh_last = &(elm)->field.sqe_next;		\
277	(listelm)->field.sqe_next = (elm);				\
278} while (/*CONSTCOND*/0)
279
280#define SIMPLEQ_REMOVE_HEAD(head, field) do {				\
281	if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
282		(head)->sqh_last = &(head)->sqh_first;			\
283} while (/*CONSTCOND*/0)
284
285#define SIMPLEQ_REMOVE(head, elm, type, field) do {			\
286	if ((head)->sqh_first == (elm)) {				\
287		SIMPLEQ_REMOVE_HEAD((head), field);			\
288	} else {							\
289		struct type *curelm = (head)->sqh_first;		\
290		while (curelm->field.sqe_next != (elm))			\
291			curelm = curelm->field.sqe_next;		\
292		if ((curelm->field.sqe_next =				\
293			curelm->field.sqe_next->field.sqe_next) == NULL) \
294			    (head)->sqh_last = &(curelm)->field.sqe_next; \
295	}								\
296} while (/*CONSTCOND*/0)
297
298#define SIMPLEQ_FOREACH(var, head, field)				\
299	for ((var) = ((head)->sqh_first);				\
300		(var);							\
301		(var) = ((var)->field.sqe_next))
302
303/*
304 * Simple queue access methods.
305 */
306#define	SIMPLEQ_EMPTY(head)		((head)->sqh_first == NULL)
307#define	SIMPLEQ_FIRST(head)		((head)->sqh_first)
308#define	SIMPLEQ_NEXT(elm, field)	((elm)->field.sqe_next)
309
310/*
311 * Tail queue definitions.
312 */
313#define TAILQ_HEAD(name, type)						\
314struct name {								\
315	struct type *tqh_first;	/* first element */			\
316	struct type **tqh_last;	/* addr of last next element */		\
317}
318
319#define TAILQ_HEAD_INITIALIZER(head)					\
320	{ NULL, &(head).tqh_first }
321
322#define TAILQ_ENTRY(type)						\
323struct {								\
324	struct type *tqe_next;	/* next element */			\
325	struct type **tqe_prev;	/* address of previous next element */	\
326}
327
328/*
329 * Tail queue functions.
330 */
331#if defined(_KERNEL) && defined(QUEUEDEBUG)
332#define QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field)			\
333	if ((head)->tqh_first &&					\
334	    (head)->tqh_first->field.tqe_prev != &(head)->tqh_first)	\
335		panic("TAILQ_INSERT_HEAD %p %s:%d", (head), __FILE__, __LINE__);
336#define QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field)			\
337	if (*(head)->tqh_last != NULL)					\
338		panic("TAILQ_INSERT_TAIL %p %s:%d", (head), __FILE__, __LINE__);
339#define QUEUEDEBUG_TAILQ_OP(elm, field)					\
340	if ((elm)->field.tqe_next &&					\
341	    (elm)->field.tqe_next->field.tqe_prev !=			\
342	    &(elm)->field.tqe_next)					\
343		panic("TAILQ_* forw %p %s:%d", (elm), __FILE__, __LINE__);\
344	if (*(elm)->field.tqe_prev != (elm))				\
345		panic("TAILQ_* back %p %s:%d", (elm), __FILE__, __LINE__);
346#define QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field)				\
347	(elm)->field.tqe_next = (void *)1L;				\
348	(elm)->field.tqe_prev = (void *)1L;
349#else
350#define QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field)
351#define QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field)
352#define QUEUEDEBUG_TAILQ_OP(elm, field)
353#define QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field)
354#endif
355
356#define	TAILQ_INIT(head) do {						\
357	(head)->tqh_first = NULL;					\
358	(head)->tqh_last = &(head)->tqh_first;				\
359} while (/*CONSTCOND*/0)
360
361#define TAILQ_INSERT_HEAD(head, elm, field) do {			\
362	QUEUEDEBUG_TAILQ_INSERT_HEAD((head), (elm), field)		\
363	if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)	\
364		(head)->tqh_first->field.tqe_prev =			\
365		    &(elm)->field.tqe_next;				\
366	else								\
367		(head)->tqh_last = &(elm)->field.tqe_next;		\
368	(head)->tqh_first = (elm);					\
369	(elm)->field.tqe_prev = &(head)->tqh_first;			\
370} while (/*CONSTCOND*/0)
371
372#define TAILQ_INSERT_TAIL(head, elm, field) do {			\
373	QUEUEDEBUG_TAILQ_INSERT_TAIL((head), (elm), field)		\
374	(elm)->field.tqe_next = NULL;					\
375	(elm)->field.tqe_prev = (head)->tqh_last;			\
376	*(head)->tqh_last = (elm);					\
377	(head)->tqh_last = &(elm)->field.tqe_next;			\
378} while (/*CONSTCOND*/0)
379
380#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
381	QUEUEDEBUG_TAILQ_OP((listelm), field)				\
382	if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
383		(elm)->field.tqe_next->field.tqe_prev = 		\
384		    &(elm)->field.tqe_next;				\
385	else								\
386		(head)->tqh_last = &(elm)->field.tqe_next;		\
387	(listelm)->field.tqe_next = (elm);				\
388	(elm)->field.tqe_prev = &(listelm)->field.tqe_next;		\
389} while (/*CONSTCOND*/0)
390
391#define	TAILQ_INSERT_BEFORE(listelm, elm, field) do {			\
392	QUEUEDEBUG_TAILQ_OP((listelm), field)				\
393	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
394	(elm)->field.tqe_next = (listelm);				\
395	*(listelm)->field.tqe_prev = (elm);				\
396	(listelm)->field.tqe_prev = &(elm)->field.tqe_next;		\
397} while (/*CONSTCOND*/0)
398
399#define TAILQ_REMOVE(head, elm, field) do {				\
400	QUEUEDEBUG_TAILQ_OP((elm), field)				\
401	if (((elm)->field.tqe_next) != NULL)				\
402		(elm)->field.tqe_next->field.tqe_prev = 		\
403		    (elm)->field.tqe_prev;				\
404	else								\
405		(head)->tqh_last = (elm)->field.tqe_prev;		\
406	*(elm)->field.tqe_prev = (elm)->field.tqe_next;			\
407	QUEUEDEBUG_TAILQ_POSTREMOVE((elm), field);			\
408} while (/*CONSTCOND*/0)
409
410/*
411 * Tail queue access methods.
412 */
413#define	TAILQ_EMPTY(head)		((head)->tqh_first == NULL)
414#define	TAILQ_FIRST(head)		((head)->tqh_first)
415#define	TAILQ_NEXT(elm, field)		((elm)->field.tqe_next)
416
417#define TAILQ_LAST(head, headname) \
418	(*(((struct headname *)((head)->tqh_last))->tqh_last))
419#define TAILQ_PREV(elm, headname, field) \
420	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
421
422#define TAILQ_FOREACH(var, head, field)					\
423	for ((var) = ((head)->tqh_first);				\
424		(var);							\
425		(var) = ((var)->field.tqe_next))
426
427#define TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
428	for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last));	\
429		(var);							\
430		(var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
431
432/*
433 * Circular queue definitions.
434 */
435#define CIRCLEQ_HEAD(name, type)					\
436struct name {								\
437	struct type *cqh_first;		/* first element */		\
438	struct type *cqh_last;		/* last element */		\
439}
440
441#define CIRCLEQ_HEAD_INITIALIZER(head)					\
442	{ (void *)&head, (void *)&head }
443
444#define CIRCLEQ_ENTRY(type)						\
445struct {								\
446	struct type *cqe_next;		/* next element */		\
447	struct type *cqe_prev;		/* previous element */		\
448}
449
450/*
451 * Circular queue functions.
452 */
453#define	CIRCLEQ_INIT(head) do {						\
454	(head)->cqh_first = (void *)(head);				\
455	(head)->cqh_last = (void *)(head);				\
456} while (/*CONSTCOND*/0)
457
458#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
459	(elm)->field.cqe_next = (listelm)->field.cqe_next;		\
460	(elm)->field.cqe_prev = (listelm);				\
461	if ((listelm)->field.cqe_next == (void *)(head))		\
462		(head)->cqh_last = (elm);				\
463	else								\
464		(listelm)->field.cqe_next->field.cqe_prev = (elm);	\
465	(listelm)->field.cqe_next = (elm);				\
466} while (/*CONSTCOND*/0)
467
468#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {		\
469	(elm)->field.cqe_next = (listelm);				\
470	(elm)->field.cqe_prev = (listelm)->field.cqe_prev;		\
471	if ((listelm)->field.cqe_prev == (void *)(head))		\
472		(head)->cqh_first = (elm);				\
473	else								\
474		(listelm)->field.cqe_prev->field.cqe_next = (elm);	\
475	(listelm)->field.cqe_prev = (elm);				\
476} while (/*CONSTCOND*/0)
477
478#define CIRCLEQ_INSERT_HEAD(head, elm, field) do {			\
479	(elm)->field.cqe_next = (head)->cqh_first;			\
480	(elm)->field.cqe_prev = (void *)(head);				\
481	if ((head)->cqh_last == (void *)(head))				\
482		(head)->cqh_last = (elm);				\
483	else								\
484		(head)->cqh_first->field.cqe_prev = (elm);		\
485	(head)->cqh_first = (elm);					\
486} while (/*CONSTCOND*/0)
487
488#define CIRCLEQ_INSERT_TAIL(head, elm, field) do {			\
489	(elm)->field.cqe_next = (void *)(head);				\
490	(elm)->field.cqe_prev = (head)->cqh_last;			\
491	if ((head)->cqh_first == (void *)(head))			\
492		(head)->cqh_first = (elm);				\
493	else								\
494		(head)->cqh_last->field.cqe_next = (elm);		\
495	(head)->cqh_last = (elm);					\
496} while (/*CONSTCOND*/0)
497
498#define	CIRCLEQ_REMOVE(head, elm, field) do {				\
499	if ((elm)->field.cqe_next == (void *)(head))			\
500		(head)->cqh_last = (elm)->field.cqe_prev;		\
501	else								\
502		(elm)->field.cqe_next->field.cqe_prev =			\
503		    (elm)->field.cqe_prev;				\
504	if ((elm)->field.cqe_prev == (void *)(head))			\
505		(head)->cqh_first = (elm)->field.cqe_next;		\
506	else								\
507		(elm)->field.cqe_prev->field.cqe_next =			\
508		    (elm)->field.cqe_next;				\
509} while (/*CONSTCOND*/0)
510
511#define CIRCLEQ_FOREACH(var, head, field)				\
512	for ((var) = ((head)->cqh_first);				\
513		(var) != (void *)(head);				\
514		(var) = ((var)->field.cqe_next))
515
516#define CIRCLEQ_FOREACH_REVERSE(var, head, field)			\
517	for ((var) = ((head)->cqh_last);				\
518		(var) != (void *)(head);				\
519		(var) = ((var)->field.cqe_prev))
520
521/*
522 * Circular queue access methods.
523 */
524#define	CIRCLEQ_EMPTY(head)		((head)->cqh_first == (void *)(head))
525#define	CIRCLEQ_FIRST(head)		((head)->cqh_first)
526#define	CIRCLEQ_LAST(head)		((head)->cqh_last)
527#define	CIRCLEQ_NEXT(elm, field)	((elm)->field.cqe_next)
528#define	CIRCLEQ_PREV(elm, field)	((elm)->field.cqe_prev)
529#endif	/* !_SYS_QUEUE_H_ */
530