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