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  * 4. Neither the name of the University nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  *	@(#)queue.h	8.5 (Berkeley) 8/20/94
30  * $FreeBSD$
31  */
32 
33 #ifndef XEN__SYS_QUEUE_H_
34 #define	XEN__SYS_QUEUE_H_
35 
36 /* #include <sys/cdefs.h> */
37 
38 /*
39  * This file defines four types of data structures: singly-linked lists,
40  * singly-linked tail queues, lists and tail queues.
41  *
42  * A singly-linked list is headed by a single forward pointer. The elements
43  * are singly linked for minimum space and pointer manipulation overhead at
44  * the expense of O(n) removal for arbitrary elements. New elements can be
45  * added to the list after an existing element or at the head of the list.
46  * Elements being removed from the head of the list should use the explicit
47  * macro for this purpose for optimum efficiency. A singly-linked list may
48  * only be traversed in the forward direction.  Singly-linked lists are ideal
49  * for applications with large datasets and few or no removals or for
50  * implementing a LIFO queue.
51  *
52  * A singly-linked tail queue is headed by a pair of pointers, one to the
53  * head of the list and the other to the tail of the list. The elements are
54  * singly linked for minimum space and pointer manipulation overhead at the
55  * expense of O(n) removal for arbitrary elements. New elements can be added
56  * to the list after an existing element, at the head of the list, or at the
57  * end of the list. Elements being removed from the head of the tail queue
58  * should use the explicit macro for this purpose for optimum efficiency.
59  * A singly-linked tail queue may only be traversed in the forward direction.
60  * Singly-linked tail queues are ideal for applications with large datasets
61  * and few or no removals or for implementing a FIFO queue.
62  *
63  * A list is headed by a single forward pointer (or an array of forward
64  * pointers for a hash table header). The elements are doubly linked
65  * so that an arbitrary element can be removed without a need to
66  * traverse the list. New elements can be added to the list before
67  * or after an existing element or at the head of the list. A list
68  * may only be traversed in the forward direction.
69  *
70  * A tail queue is headed by a pair of pointers, one to the head of the
71  * list and the other to the tail of the list. The elements are doubly
72  * linked 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 or
74  * after an existing element, at the head of the list, or at the end of
75  * the list. A tail queue may be traversed in either direction.
76  *
77  * For details on the use of these macros, see the queue(3) manual page.
78  *
79  *
80  *				XEN_SLIST	XEN_LIST	XEN_STAILQ	XEN_TAILQ
81  * _HEAD			+	+	+	+
82  * _HEAD_INITIALIZER		+	+	+	+
83  * _ENTRY			+	+	+	+
84  * _INIT			+	+	+	+
85  * _EMPTY			+	+	+	+
86  * _FIRST			+	+	+	+
87  * _NEXT			+	+	+	+
88  * _PREV			-	-	-	+
89  * _LAST			-	-	+	+
90  * _FOREACH			+	+	+	+
91  * _FOREACH_SAFE		+	+	+	+
92  * _FOREACH_REVERSE		-	-	-	+
93  * _FOREACH_REVERSE_SAFE	-	-	-	+
94  * _INSERT_HEAD			+	+	+	+
95  * _INSERT_BEFORE		-	+	-	+
96  * _INSERT_AFTER		+	+	+	+
97  * _INSERT_TAIL			-	-	+	+
98  * _CONCAT			-	-	+	+
99  * _REMOVE_AFTER		+	-	+	-
100  * _REMOVE_HEAD			+	-	+	-
101  * _REMOVE			+	+	+	+
102  * _SWAP			+	+	+	+
103  *
104  */
105 
106 /*
107  * Singly-linked List declarations.
108  */
109 #define	XEN_SLIST_HEAD(name, type)					\
110 struct name {								\
111 	type *slh_first;	/* first element */			\
112 }
113 
114 #define	XEN_SLIST_HEAD_INITIALIZER(head)				\
115 	{ 0 }
116 
117 #define	XEN_SLIST_ENTRY(type)						\
118 struct {								\
119 	type *sle_next;	/* next element */				\
120 }
121 
122 /*
123  * Singly-linked List functions.
124  */
125 #define	XEN_SLIST_EMPTY(head)	((head)->slh_first == 0)
126 
127 #define	XEN_SLIST_FIRST(head)	((head)->slh_first)
128 
129 #define	XEN_SLIST_FOREACH(var, head, field)				\
130 	for ((var) = XEN_SLIST_FIRST((head));				\
131 	    (var);							\
132 	    (var) = XEN_SLIST_NEXT((var), field))
133 
134 #define	XEN_SLIST_FOREACH_SAFE(var, head, field, tvar)			\
135 	for ((var) = XEN_SLIST_FIRST((head));				\
136 	    (var) && ((tvar) = XEN_SLIST_NEXT((var), field), 1);	\
137 	    (var) = (tvar))
138 
139 #define	XEN_SLIST_FOREACH_PREVPTR(var, varp, head, field)		\
140 	for ((varp) = &XEN_SLIST_FIRST((head));				\
141 	    ((var) = *(varp)) != 0;					\
142 	    (varp) = &XEN_SLIST_NEXT((var), field))
143 
144 #define	XEN_SLIST_INIT(head) do {					\
145 	XEN_SLIST_FIRST((head)) = 0;					\
146 } while (0)
147 
148 #define	XEN_SLIST_INSERT_AFTER(slistelm, elm, field) do {		\
149 	XEN_SLIST_NEXT((elm), field) = XEN_SLIST_NEXT((slistelm), field);\
150 	XEN_SLIST_NEXT((slistelm), field) = (elm);			\
151 } while (0)
152 
153 #define	XEN_SLIST_INSERT_HEAD(head, elm, field) do {			\
154 	XEN_SLIST_NEXT((elm), field) = XEN_SLIST_FIRST((head));		\
155 	XEN_SLIST_FIRST((head)) = (elm);				\
156 } while (0)
157 
158 #define	XEN_SLIST_NEXT(elm, field)	((elm)->field.sle_next)
159 
160 #define	XEN_SLIST_REMOVE(head, elm, type, field) do {			\
161 	if (XEN_SLIST_FIRST((head)) == (elm)) {				\
162 		XEN_SLIST_REMOVE_HEAD((head), field);			\
163 	}								\
164 	else {								\
165 		type *curelm = XEN_SLIST_FIRST((head));			\
166 		while (XEN_SLIST_NEXT(curelm, field) != (elm))		\
167 			curelm = XEN_SLIST_NEXT(curelm, field);		\
168 		XEN_SLIST_REMOVE_AFTER(curelm, field);			\
169 	}								\
170 } while (0)
171 
172 #define XEN_SLIST_REMOVE_AFTER(elm, field) do {				\
173 	XEN_SLIST_NEXT(elm, field) =					\
174 	    XEN_SLIST_NEXT(XEN_SLIST_NEXT(elm, field), field);		\
175 } while (0)
176 
177 #define	XEN_SLIST_REMOVE_HEAD(head, field) do {				\
178 	XEN_SLIST_FIRST((head)) = XEN_SLIST_NEXT(XEN_SLIST_FIRST((head)), field);\
179 } while (0)
180 
181 #define XEN_SLIST_SWAP(head1, head2, type) do {				\
182 	type *swap_first = XEN_SLIST_FIRST(head1);			\
183 	XEN_SLIST_FIRST(head1) = XEN_SLIST_FIRST(head2);		\
184 	XEN_SLIST_FIRST(head2) = swap_first;				\
185 } while (0)
186 
187 /*
188  * Singly-linked Tail queue declarations.
189  */
190 #define	XEN_STAILQ_HEAD(name, type)					\
191 struct name {								\
192 	type *stqh_first;/* first element */				\
193 	type **stqh_last;/* addr of last next element */		\
194 }
195 
196 #define	XEN_STAILQ_HEAD_INITIALIZER(head)				\
197 	{ 0, &(head).stqh_first }
198 
199 #define	XEN_STAILQ_ENTRY(type)						\
200 struct {								\
201 	type *stqe_next;	/* next element */			\
202 }
203 
204 /*
205  * Singly-linked Tail queue functions.
206  */
207 #define	XEN_STAILQ_CONCAT(head1, head2) do {				\
208 	if (!XEN_STAILQ_EMPTY((head2))) {				\
209 		*(head1)->stqh_last = (head2)->stqh_first;		\
210 		(head1)->stqh_last = (head2)->stqh_last;		\
211 		XEN_STAILQ_INIT((head2));				\
212 	}								\
213 } while (0)
214 
215 #define	XEN_STAILQ_EMPTY(head)	((head)->stqh_first == 0)
216 
217 #define	XEN_STAILQ_FIRST(head)	((head)->stqh_first)
218 
219 #define	XEN_STAILQ_FOREACH(var, head, field)				\
220 	for((var) = XEN_STAILQ_FIRST((head));				\
221 	   (var);							\
222 	   (var) = XEN_STAILQ_NEXT((var), field))
223 
224 
225 #define	XEN_STAILQ_FOREACH_SAFE(var, head, field, tvar)			\
226 	for ((var) = XEN_STAILQ_FIRST((head));				\
227 	    (var) && ((tvar) = XEN_STAILQ_NEXT((var), field), 1);	\
228 	    (var) = (tvar))
229 
230 #define	XEN_STAILQ_INIT(head) do {					\
231 	XEN_STAILQ_FIRST((head)) = 0;					\
232 	(head)->stqh_last = &XEN_STAILQ_FIRST((head));			\
233 } while (0)
234 
235 #define	XEN_STAILQ_INSERT_AFTER(head, tqelm, elm, field) do {		\
236 	if ((XEN_STAILQ_NEXT((elm), field) = XEN_STAILQ_NEXT((tqelm), field)) == 0)\
237 		(head)->stqh_last = &XEN_STAILQ_NEXT((elm), field);	\
238 	XEN_STAILQ_NEXT((tqelm), field) = (elm);			\
239 } while (0)
240 
241 #define	XEN_STAILQ_INSERT_HEAD(head, elm, field) do {			\
242 	if ((XEN_STAILQ_NEXT((elm), field) = XEN_STAILQ_FIRST((head))) == 0)\
243 		(head)->stqh_last = &XEN_STAILQ_NEXT((elm), field);	\
244 	XEN_STAILQ_FIRST((head)) = (elm);				\
245 } while (0)
246 
247 #define	XEN_STAILQ_INSERT_TAIL(head, elm, field) do {			\
248 	XEN_STAILQ_NEXT((elm), field) = 0;				\
249 	*(head)->stqh_last = (elm);					\
250 	(head)->stqh_last = &XEN_STAILQ_NEXT((elm), field);		\
251 } while (0)
252 
253 #define	XEN_STAILQ_LAST(head, type, field)				\
254 	(XEN_STAILQ_EMPTY((head)) ?					\
255 		0 :							\
256 	        ((type *)(void *)					\
257 		((char *)((head)->stqh_last) - offsetof(type, field))))
258 
259 #define	XEN_STAILQ_NEXT(elm, field)	((elm)->field.stqe_next)
260 
261 #define	XEN_STAILQ_REMOVE(head, elm, type, field) do {			\
262 	if (XEN_STAILQ_FIRST((head)) == (elm)) {			\
263 		XEN_STAILQ_REMOVE_HEAD((head), field);			\
264 	}								\
265 	else {								\
266 		type *curelm = XEN_STAILQ_FIRST((head));		\
267 		while (XEN_STAILQ_NEXT(curelm, field) != (elm))		\
268 			curelm = XEN_STAILQ_NEXT(curelm, field);	\
269 		XEN_STAILQ_REMOVE_AFTER(head, curelm, field);		\
270 	}								\
271 } while (0)
272 
273 #define XEN_STAILQ_REMOVE_AFTER(head, elm, field) do {			\
274 	if ((XEN_STAILQ_NEXT(elm, field) =				\
275 	     XEN_STAILQ_NEXT(XEN_STAILQ_NEXT(elm, field), field)) == 0)	\
276 		(head)->stqh_last = &XEN_STAILQ_NEXT((elm), field);	\
277 } while (0)
278 
279 #define	XEN_STAILQ_REMOVE_HEAD(head, field) do {			\
280 	if ((XEN_STAILQ_FIRST((head)) =					\
281 	     XEN_STAILQ_NEXT(XEN_STAILQ_FIRST((head)), field)) == 0)	\
282 		(head)->stqh_last = &XEN_STAILQ_FIRST((head));		\
283 } while (0)
284 
285 #define XEN_STAILQ_SWAP(head1, head2, type) do {			\
286 	type *swap_first = XEN_STAILQ_FIRST(head1);			\
287 	type **swap_last = (head1)->stqh_last;				\
288 	XEN_STAILQ_FIRST(head1) = XEN_STAILQ_FIRST(head2);		\
289 	(head1)->stqh_last = (head2)->stqh_last;			\
290 	XEN_STAILQ_FIRST(head2) = swap_first;				\
291 	(head2)->stqh_last = swap_last;					\
292 	if (XEN_STAILQ_EMPTY(head1))					\
293 		(head1)->stqh_last = &XEN_STAILQ_FIRST(head1);		\
294 	if (XEN_STAILQ_EMPTY(head2))					\
295 		(head2)->stqh_last = &XEN_STAILQ_FIRST(head2);		\
296 } while (0)
297 
298 
299 /*
300  * List declarations.
301  */
302 #define	XEN_LIST_HEAD(name, type)					\
303 struct name {								\
304 	type *lh_first;	/* first element */				\
305 }
306 
307 #define	XEN_LIST_HEAD_INITIALIZER(head)					\
308 	{ 0 }
309 
310 #define	XEN_LIST_ENTRY(type)						\
311 struct {								\
312 	type *le_next;	/* next element */				\
313 	type **le_prev;	/* address of previous next element */		\
314 }
315 
316 /*
317  * List functions.
318  */
319 
320 #define	XEN_LIST_EMPTY(head)	((head)->lh_first == 0)
321 
322 #define	XEN_LIST_FIRST(head)	((head)->lh_first)
323 
324 #define	XEN_LIST_FOREACH(var, head, field)				\
325 	for ((var) = XEN_LIST_FIRST((head));				\
326 	    (var);							\
327 	    (var) = XEN_LIST_NEXT((var), field))
328 
329 #define	XEN_LIST_FOREACH_SAFE(var, head, field, tvar)			\
330 	for ((var) = XEN_LIST_FIRST((head));				\
331 	    (var) && ((tvar) = XEN_LIST_NEXT((var), field), 1);		\
332 	    (var) = (tvar))
333 
334 #define	XEN_LIST_INIT(head) do {					\
335 	XEN_LIST_FIRST((head)) = 0;					\
336 } while (0)
337 
338 #define	XEN_LIST_INSERT_AFTER(listelm, elm, field) do {			\
339 	if ((XEN_LIST_NEXT((elm), field) = XEN_LIST_NEXT((listelm), field)) != 0)\
340 		XEN_LIST_NEXT((listelm), field)->field.le_prev =	\
341 		    &XEN_LIST_NEXT((elm), field);			\
342 	XEN_LIST_NEXT((listelm), field) = (elm);			\
343 	(elm)->field.le_prev = &XEN_LIST_NEXT((listelm), field);	\
344 } while (0)
345 
346 #define	XEN_LIST_INSERT_BEFORE(listelm, elm, field) do {		\
347 	(elm)->field.le_prev = (listelm)->field.le_prev;		\
348 	XEN_LIST_NEXT((elm), field) = (listelm);			\
349 	*(listelm)->field.le_prev = (elm);				\
350 	(listelm)->field.le_prev = &XEN_LIST_NEXT((elm), field);	\
351 } while (0)
352 
353 #define	XEN_LIST_INSERT_HEAD(head, elm, field) do {			\
354 	if ((XEN_LIST_NEXT((elm), field) = XEN_LIST_FIRST((head))) != 0)\
355 		XEN_LIST_FIRST((head))->field.le_prev = &XEN_LIST_NEXT((elm), field);\
356 	XEN_LIST_FIRST((head)) = (elm);					\
357 	(elm)->field.le_prev = &XEN_LIST_FIRST((head));			\
358 } while (0)
359 
360 #define	XEN_LIST_NEXT(elm, field)	((elm)->field.le_next)
361 
362 #define	XEN_LIST_REMOVE(elm, field) do {				\
363 	if (XEN_LIST_NEXT((elm), field) != 0)				\
364 		XEN_LIST_NEXT((elm), field)->field.le_prev =		\
365 		    (elm)->field.le_prev;				\
366 	*(elm)->field.le_prev = XEN_LIST_NEXT((elm), field);		\
367 } while (0)
368 
369 #define XEN_LIST_SWAP(head1, head2, type, field) do {			\
370 	type *swap_tmp = XEN_LIST_FIRST((head1));			\
371 	XEN_LIST_FIRST((head1)) = XEN_LIST_FIRST((head2));		\
372 	XEN_LIST_FIRST((head2)) = swap_tmp;				\
373 	if ((swap_tmp = XEN_LIST_FIRST((head1))) != 0)			\
374 		swap_tmp->field.le_prev = &XEN_LIST_FIRST((head1));	\
375 	if ((swap_tmp = XEN_LIST_FIRST((head2))) != 0)			\
376 		swap_tmp->field.le_prev = &XEN_LIST_FIRST((head2));	\
377 } while (0)
378 
379 /*
380  * Tail queue declarations.
381  */
382 #define	XEN_TAILQ_HEAD(name, type)					\
383 struct name {								\
384 	type *tqh_first;	/* first element */			\
385 	type **tqh_last;	/* addr of last next element */		\
386 }
387 
388 #define	XEN_TAILQ_HEAD_INITIALIZER(head)				\
389 	{ 0, &(head).tqh_first }
390 
391 #define	XEN_TAILQ_ENTRY(type)						\
392 struct {								\
393 	type *tqe_next;	/* next element */				\
394 	type **tqe_prev;	/* address of previous next element */	\
395 }
396 
397 /*
398  * Tail queue functions.
399  */
400 
401 #define	XEN_TAILQ_CONCAT(head1, head2, field) do {			\
402 	if (!XEN_TAILQ_EMPTY(head2)) {					\
403 		*(head1)->tqh_last = (head2)->tqh_first;		\
404 		(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last;	\
405 		(head1)->tqh_last = (head2)->tqh_last;			\
406 		XEN_TAILQ_INIT((head2));				\
407 	}								\
408 } while (0)
409 
410 #define	XEN_TAILQ_EMPTY(head)	((head)->tqh_first == 0)
411 
412 #define	XEN_TAILQ_FIRST(head)	((head)->tqh_first)
413 
414 #define	XEN_TAILQ_FOREACH(var, head, field)				\
415 	for ((var) = XEN_TAILQ_FIRST((head));				\
416 	    (var);							\
417 	    (var) = XEN_TAILQ_NEXT((var), field))
418 
419 #define	XEN_TAILQ_FOREACH_SAFE(var, head, field, tvar)			\
420 	for ((var) = XEN_TAILQ_FIRST((head));				\
421 	    (var) && ((tvar) = XEN_TAILQ_NEXT((var), field), 1);	\
422 	    (var) = (tvar))
423 
424 #define	XEN_TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
425 	for ((var) = XEN_TAILQ_LAST((head), headname);			\
426 	    (var);							\
427 	    (var) = XEN_TAILQ_PREV((var), headname, field))
428 
429 #define	XEN_TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar)	\
430 	for ((var) = XEN_TAILQ_LAST((head), headname);			\
431 	    (var) && ((tvar) = XEN_TAILQ_PREV((var), headname, field), 1);\
432 	    (var) = (tvar))
433 
434 #define	XEN_TAILQ_INIT(head) do {					\
435 	XEN_TAILQ_FIRST((head)) = 0;					\
436 	(head)->tqh_last = &XEN_TAILQ_FIRST((head));			\
437 } while (0)
438 
439 #define	XEN_TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
440 	if ((XEN_TAILQ_NEXT((elm), field) = XEN_TAILQ_NEXT((listelm), field)) != 0)\
441 		XEN_TAILQ_NEXT((elm), field)->field.tqe_prev =		\
442 		    &XEN_TAILQ_NEXT((elm), field);			\
443 	else {								\
444 		(head)->tqh_last = &XEN_TAILQ_NEXT((elm), field);	\
445 	}								\
446 	XEN_TAILQ_NEXT((listelm), field) = (elm);			\
447 	(elm)->field.tqe_prev = &XEN_TAILQ_NEXT((listelm), field);	\
448 } while (0)
449 
450 #define	XEN_TAILQ_INSERT_BEFORE(listelm, elm, field) do {		\
451 	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
452 	XEN_TAILQ_NEXT((elm), field) = (listelm);			\
453 	*(listelm)->field.tqe_prev = (elm);				\
454 	(listelm)->field.tqe_prev = &XEN_TAILQ_NEXT((elm), field);	\
455 } while (0)
456 
457 #define	XEN_TAILQ_INSERT_HEAD(head, elm, field) do {			\
458 	if ((XEN_TAILQ_NEXT((elm), field) = XEN_TAILQ_FIRST((head))) != 0)\
459 		XEN_TAILQ_FIRST((head))->field.tqe_prev =		\
460 		    &XEN_TAILQ_NEXT((elm), field);			\
461 	else								\
462 		(head)->tqh_last = &XEN_TAILQ_NEXT((elm), field);	\
463 	XEN_TAILQ_FIRST((head)) = (elm);				\
464 	(elm)->field.tqe_prev = &XEN_TAILQ_FIRST((head));		\
465 } while (0)
466 
467 #define	XEN_TAILQ_INSERT_TAIL(head, elm, field) do {			\
468 	XEN_TAILQ_NEXT((elm), field) = 0;				\
469 	(elm)->field.tqe_prev = (head)->tqh_last;			\
470 	*(head)->tqh_last = (elm);					\
471 	(head)->tqh_last = &XEN_TAILQ_NEXT((elm), field);		\
472 } while (0)
473 
474 #define	XEN_TAILQ_LAST(head, headname)					\
475 	(*(((struct headname *)((head)->tqh_last))->tqh_last))
476 
477 #define	XEN_TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
478 
479 #define	XEN_TAILQ_PREV(elm, headname, field)				\
480 	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
481 
482 #define	XEN_TAILQ_REMOVE(head, elm, field) do {				\
483 	if ((XEN_TAILQ_NEXT((elm), field)) != 0)			\
484 		XEN_TAILQ_NEXT((elm), field)->field.tqe_prev =		\
485 		    (elm)->field.tqe_prev;				\
486 	else {								\
487 		(head)->tqh_last = (elm)->field.tqe_prev;		\
488 	}								\
489 	*(elm)->field.tqe_prev = XEN_TAILQ_NEXT((elm), field);		\
490 } while (0)
491 
492 #define XEN_TAILQ_SWAP(head1, head2, type, field) do {			\
493 	type *swap_first = (head1)->tqh_first;				\
494 	type **swap_last = (head1)->tqh_last;				\
495 	(head1)->tqh_first = (head2)->tqh_first;			\
496 	(head1)->tqh_last = (head2)->tqh_last;				\
497 	(head2)->tqh_first = swap_first;				\
498 	(head2)->tqh_last = swap_last;					\
499 	if ((swap_first = (head1)->tqh_first) != 0)			\
500 		swap_first->field.tqe_prev = &(head1)->tqh_first;	\
501 	else								\
502 		(head1)->tqh_last = &(head1)->tqh_first;		\
503 	if ((swap_first = (head2)->tqh_first) != 0)			\
504 		swap_first->field.tqe_prev = &(head2)->tqh_first;	\
505 	else								\
506 		(head2)->tqh_last = &(head2)->tqh_first;		\
507 } while (0)
508 
509 #endif /* !XEN__SYS_QUEUE_H_ */
510