1 /*        $NetBSD: queue.h,v 1.77 2024/05/12 10:34:56 rillig 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. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  *        @(#)queue.h         8.5 (Berkeley) 8/20/94
32  */
33 
34 #ifndef   _SYS_QUEUE_H_
35 #define   _SYS_QUEUE_H_
36 
37 /*
38  * This file defines five types of data structures: singly-linked lists,
39  * lists, simple queues, tail queues, and circular queues.
40  *
41  * A singly-linked list is headed by a single forward pointer. The
42  * elements are singly linked for minimum space and pointer manipulation
43  * overhead at the expense of O(n) removal for arbitrary elements. New
44  * elements can be added to the list after an existing element or at the
45  * head of the list.  Elements being removed from the head of the list
46  * should use the explicit macro for this purpose for optimum
47  * efficiency. A singly-linked list may only be traversed in the forward
48  * direction.  Singly-linked lists are ideal for applications with large
49  * datasets and few or no removals or for implementing a LIFO queue.
50  *
51  * A list is headed by a single forward pointer (or an array of forward
52  * pointers for a hash table header). The elements are doubly linked
53  * so that an arbitrary element can be removed without a need to
54  * traverse the list. New elements can be added to the list before
55  * or after an existing element or at the head of the list. A list
56  * may only be traversed in the forward direction.
57  *
58  * A simple queue is headed by a pair of pointers, one the head of the
59  * list and the other to the tail of the list. The elements are singly
60  * linked to save space, so elements can only be removed from the
61  * head of the list. New elements can be added to the list after
62  * an existing element, at the head of the list, or at the end of the
63  * list. A simple queue may only be traversed in the forward direction.
64  *
65  * A tail queue is headed by a pair of pointers, one to the head of the
66  * list and the other to the tail of the list. The elements are doubly
67  * linked so that an arbitrary element can be removed without a need to
68  * traverse the list. New elements can be added to the list before or
69  * after an existing element, at the head of the list, or at the end of
70  * the list. A tail queue may be traversed in either direction.
71  *
72  * For details on the use of these macros, see the queue(3) manual page.
73  */
74 
75 /*
76  * Include the definition of NULL only on NetBSD because sys/null.h
77  * is not available elsewhere.  This conditional makes the header
78  * portable and it can simply be dropped verbatim into any system.
79  * The caveat is that on other systems some other header
80  * must provide NULL before the macros can be used.
81  */
82 #ifdef __NetBSD__
83 #include <sys/null.h>
84 #endif
85 
86 #if defined(_KERNEL) && defined(DIAGNOSTIC)
87 #define QUEUEDEBUG  1
88 #endif
89 
90 #if defined(QUEUEDEBUG)
91 # if defined(_KERNEL)
92 #  define QUEUEDEBUG_ABORT(...) panic(__VA_ARGS__)
93 # else
94 #  include <err.h>
95 #  define QUEUEDEBUG_ABORT(...) err(1, __VA_ARGS__)
96 # endif
97 #endif
98 
99 /*
100  * Singly-linked List definitions.
101  */
102 #define   SLIST_HEAD(name, type)                                                          \
103 struct name {                                                                             \
104           struct type *slh_first;       /* first element */                     \
105 }
106 
107 #define   SLIST_HEAD_INITIALIZER(head)                                          \
108           { NULL }
109 
110 #define   SLIST_ENTRY(type)                                                     \
111 struct {                                                                        \
112           struct type *sle_next;        /* next element */                      \
113 }
114 
115 /*
116  * Singly-linked List access methods.
117  */
118 #define   SLIST_FIRST(head)   ((head)->slh_first)
119 #define   SLIST_END(head)               NULL
120 #define   SLIST_EMPTY(head)   ((head)->slh_first == NULL)
121 #define   SLIST_NEXT(elm, field)        ((elm)->field.sle_next)
122 
123 #define   SLIST_FOREACH(var, head, field)                                                 \
124           for((var) = (head)->slh_first;                                                  \
125               (var) != SLIST_END(head);                                         \
126               (var) = (var)->field.sle_next)
127 
128 #define   SLIST_FOREACH_SAFE(var, head, field, tvar)                            \
129           for ((var) = SLIST_FIRST((head));                                     \
130               (var) != SLIST_END(head) &&                                                 \
131               ((tvar) = SLIST_NEXT((var), field), 1);                           \
132               (var) = (tvar))
133 
134 /*
135  * Singly-linked List functions.
136  */
137 #define   SLIST_INIT(head) do {                                                           \
138           (head)->slh_first = SLIST_END(head);                                  \
139 } while (0)
140 
141 #define   SLIST_INSERT_AFTER(slistelm, elm, field) do {                         \
142           (elm)->field.sle_next = (slistelm)->field.sle_next;                   \
143           (slistelm)->field.sle_next = (elm);                                   \
144 } while (0)
145 
146 #define   SLIST_INSERT_HEAD(head, elm, field) do {                              \
147           (elm)->field.sle_next = (head)->slh_first;                            \
148           (head)->slh_first = (elm);                                            \
149 } while (0)
150 
151 #define   SLIST_REMOVE_AFTER(slistelm, field) do {                              \
152           (slistelm)->field.sle_next =                                          \
153               SLIST_NEXT(SLIST_NEXT((slistelm), field), field);                 \
154 } while (0)
155 
156 #define   SLIST_REMOVE_HEAD(head, field) do {                                   \
157           (head)->slh_first = (head)->slh_first->field.sle_next;                \
158 } while (0)
159 
160 #define   SLIST_REMOVE(head, elm, type, field) do {                             \
161           if ((head)->slh_first == (elm)) {                                     \
162                     SLIST_REMOVE_HEAD((head), field);                           \
163           }                                                                               \
164           else {                                                                          \
165                     struct type *curelm = (head)->slh_first;                    \
166                     while(curelm->field.sle_next != (elm))                      \
167                               curelm = curelm->field.sle_next;                  \
168                     curelm->field.sle_next =                                    \
169                         curelm->field.sle_next->field.sle_next;                 \
170           }                                                                               \
171 } while (0)
172 
173 
174 /*
175  * List definitions.
176  */
177 #define   LIST_HEAD(name, type)                                                           \
178 struct name {                                                                             \
179           struct type *lh_first;        /* first element */                     \
180 }
181 
182 #define   LIST_HEAD_INITIALIZER(head)                                           \
183           { NULL }
184 
185 #define   LIST_ENTRY(type)                                                      \
186 struct {                                                                        \
187           struct type *le_next;         /* next element */                      \
188           struct type **le_prev;        /* address of previous next element */  \
189 }
190 
191 /*
192  * List access methods.
193  */
194 #define   LIST_FIRST(head)              ((head)->lh_first)
195 #define   LIST_END(head)                          NULL
196 #define   LIST_EMPTY(head)              ((head)->lh_first == LIST_END(head))
197 #define   LIST_NEXT(elm, field)                   ((elm)->field.le_next)
198 
199 #define   LIST_FOREACH(var, head, field)                                                  \
200           for ((var) = ((head)->lh_first);                                      \
201               (var) != LIST_END(head);                                          \
202               (var) = ((var)->field.le_next))
203 
204 #define   LIST_FOREACH_SAFE(var, head, field, tvar)                             \
205           for ((var) = LIST_FIRST((head));                                      \
206               (var) != LIST_END(head) &&                                                  \
207               ((tvar) = LIST_NEXT((var), field), 1);                            \
208               (var) = (tvar))
209 
210 #define   LIST_MOVE(head1, head2, field) do {                                   \
211           LIST_INIT((head2));                                                   \
212           if (!LIST_EMPTY((head1))) {                                           \
213                     (head2)->lh_first = (head1)->lh_first;                      \
214                     (head2)->lh_first->field.le_prev = &(head2)->lh_first;      \
215                     LIST_INIT((head1));                                         \
216           }                                                                               \
217 } while (0)
218 
219 /*
220  * List functions.
221  */
222 #if defined(QUEUEDEBUG)
223 #define   QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field)                         \
224           if ((head)->lh_first &&                                                         \
225               (head)->lh_first->field.le_prev != &(head)->lh_first)   \
226                     QUEUEDEBUG_ABORT("LIST_INSERT_HEAD %p %s:%d", (head),       \
227                         __FILE__, __LINE__);
228 #define   QUEUEDEBUG_LIST_OP(elm, field)                                                  \
229           if ((elm)->field.le_next &&                                           \
230               (elm)->field.le_next->field.le_prev !=                            \
231               &(elm)->field.le_next)                                            \
232                     QUEUEDEBUG_ABORT("LIST_* forw %p %s:%d", (elm),             \
233                         __FILE__, __LINE__);                                    \
234           if (*(elm)->field.le_prev != (elm))                                   \
235                     QUEUEDEBUG_ABORT("LIST_* back %p %s:%d", (elm),             \
236                         __FILE__, __LINE__);
237 #define   QUEUEDEBUG_LIST_POSTREMOVE(elm, field)                                \
238           (elm)->field.le_next = (void *)1L;                                    \
239           (elm)->field.le_prev = (void *)1L;
240 #else
241 #define   QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field)
242 #define   QUEUEDEBUG_LIST_OP(elm, field)
243 #define   QUEUEDEBUG_LIST_POSTREMOVE(elm, field)
244 #endif
245 
246 #define   LIST_INIT(head) do {                                                            \
247           (head)->lh_first = LIST_END(head);                                    \
248 } while (0)
249 
250 #define   LIST_INSERT_AFTER(listelm, elm, field) do {                           \
251           QUEUEDEBUG_LIST_OP((listelm), field)                                  \
252           if (((elm)->field.le_next = (listelm)->field.le_next) !=    \
253               LIST_END(head))                                                   \
254                     (listelm)->field.le_next->field.le_prev =                   \
255                         &(elm)->field.le_next;                                  \
256           (listelm)->field.le_next = (elm);                                     \
257           (elm)->field.le_prev = &(listelm)->field.le_next;           \
258 } while (0)
259 
260 #define   LIST_INSERT_BEFORE(listelm, elm, field) do {                          \
261           QUEUEDEBUG_LIST_OP((listelm), field)                                  \
262           (elm)->field.le_prev = (listelm)->field.le_prev;            \
263           (elm)->field.le_next = (listelm);                                     \
264           *(listelm)->field.le_prev = (elm);                                    \
265           (listelm)->field.le_prev = &(elm)->field.le_next;           \
266 } while (0)
267 
268 #define   LIST_INSERT_HEAD(head, elm, field) do {                               \
269           QUEUEDEBUG_LIST_INSERT_HEAD((head), (elm), field)           \
270           if (((elm)->field.le_next = (head)->lh_first) != LIST_END(head))\
271                     (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
272           (head)->lh_first = (elm);                                             \
273           (elm)->field.le_prev = &(head)->lh_first;                             \
274 } while (0)
275 
276 #define   LIST_REMOVE(elm, field) do {                                          \
277           QUEUEDEBUG_LIST_OP((elm), field)                                      \
278           if ((elm)->field.le_next != NULL)                                     \
279                     (elm)->field.le_next->field.le_prev =                       \
280                         (elm)->field.le_prev;                                   \
281           *(elm)->field.le_prev = (elm)->field.le_next;                         \
282           QUEUEDEBUG_LIST_POSTREMOVE((elm), field)                              \
283 } while (0)
284 
285 #define LIST_REPLACE(elm, elm2, field) do {                                     \
286           if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
287                     (elm2)->field.le_next->field.le_prev =                      \
288                         &(elm2)->field.le_next;                                 \
289           (elm2)->field.le_prev = (elm)->field.le_prev;                         \
290           *(elm2)->field.le_prev = (elm2);                                      \
291           QUEUEDEBUG_LIST_POSTREMOVE((elm), field)                              \
292 } while (0)
293 
294 /*
295  * Simple queue definitions.
296  */
297 #define   SIMPLEQ_HEAD(name, type)                                              \
298 struct name {                                                                             \
299           struct type *sqh_first;       /* first element */                     \
300           struct type **sqh_last;       /* addr of last next element */                   \
301 }
302 
303 #define   SIMPLEQ_HEAD_INITIALIZER(head)                                                  \
304           { NULL, &(head).sqh_first }
305 
306 #define   SIMPLEQ_ENTRY(type)                                                   \
307 struct {                                                                        \
308           struct type *sqe_next;        /* next element */                      \
309 }
310 
311 /*
312  * Simple queue access methods.
313  */
314 #define   SIMPLEQ_FIRST(head)           ((head)->sqh_first)
315 #define   SIMPLEQ_END(head)             NULL
316 #define   SIMPLEQ_EMPTY(head)           ((head)->sqh_first == SIMPLEQ_END(head))
317 #define   SIMPLEQ_NEXT(elm, field)      ((elm)->field.sqe_next)
318 
319 #define   SIMPLEQ_FOREACH(var, head, field)                                     \
320           for ((var) = ((head)->sqh_first);                                     \
321               (var) != SIMPLEQ_END(head);                                                 \
322               (var) = ((var)->field.sqe_next))
323 
324 #define   SIMPLEQ_FOREACH_SAFE(var, head, field, next)                          \
325           for ((var) = ((head)->sqh_first);                                     \
326               (var) != SIMPLEQ_END(head) &&                                     \
327               ((next = ((var)->field.sqe_next)), 1);                            \
328               (var) = (next))
329 
330 /*
331  * Simple queue functions.
332  */
333 #define   SIMPLEQ_INIT(head) do {                                                         \
334           (head)->sqh_first = NULL;                                             \
335           (head)->sqh_last = &(head)->sqh_first;                                \
336 } while (0)
337 
338 #define   SIMPLEQ_INSERT_HEAD(head, elm, field) do {                            \
339           if (((elm)->field.sqe_next = (head)->sqh_first) == NULL)    \
340                     (head)->sqh_last = &(elm)->field.sqe_next;                  \
341           (head)->sqh_first = (elm);                                            \
342 } while (0)
343 
344 #define   SIMPLEQ_INSERT_TAIL(head, elm, field) do {                            \
345           (elm)->field.sqe_next = NULL;                                         \
346           *(head)->sqh_last = (elm);                                            \
347           (head)->sqh_last = &(elm)->field.sqe_next;                            \
348 } while (0)
349 
350 #define   SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {                  \
351           if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
352                     (head)->sqh_last = &(elm)->field.sqe_next;                  \
353           (listelm)->field.sqe_next = (elm);                                    \
354 } while (0)
355 
356 #define   SIMPLEQ_REMOVE_HEAD(head, field) do {                                 \
357           if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
358                     (head)->sqh_last = &(head)->sqh_first;                      \
359 } while (0)
360 
361 #define SIMPLEQ_REMOVE_AFTER(head, elm, field) do {                             \
362           if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \
363               == NULL)                                                                    \
364                     (head)->sqh_last = &(elm)->field.sqe_next;                  \
365 } while (0)
366 
367 #define   SIMPLEQ_REMOVE(head, elm, type, field) do {                           \
368           if ((head)->sqh_first == (elm)) {                                     \
369                     SIMPLEQ_REMOVE_HEAD((head), field);                         \
370           } else {                                                              \
371                     struct type *curelm = (head)->sqh_first;                    \
372                     while (curelm->field.sqe_next != (elm))                     \
373                               curelm = curelm->field.sqe_next;                  \
374                     if ((curelm->field.sqe_next =                               \
375                               curelm->field.sqe_next->field.sqe_next) == NULL) \
376                                   (head)->sqh_last = &(curelm)->field.sqe_next; \
377           }                                                                               \
378 } while (0)
379 
380 #define   SIMPLEQ_CONCAT(head1, head2) do {                                     \
381           if (!SIMPLEQ_EMPTY((head2))) {                                                  \
382                     *(head1)->sqh_last = (head2)->sqh_first;                    \
383                     (head1)->sqh_last = (head2)->sqh_last;            \
384                     SIMPLEQ_INIT((head2));                                                \
385           }                                                                               \
386 } while (0)
387 
388 #define   SIMPLEQ_LAST(head, type, field)                                                 \
389           (SIMPLEQ_EMPTY((head)) ?                                                        \
390                     NULL :                                                                \
391                   ((struct type *)(void *)                                      \
392                     ((char *)((head)->sqh_last) - offsetof(struct type, field))))
393 
394 /*
395  * Tail queue definitions.
396  */
397 #define   _TAILQ_HEAD(name, type, qual)                                         \
398 struct name {                                                                             \
399           qual type *tqh_first;                   /* first element */           \
400           qual type *qual *tqh_last;    /* addr of last next element */         \
401 }
402 #define TAILQ_HEAD(name, type)          _TAILQ_HEAD(name, struct type,)
403 
404 #define   TAILQ_HEAD_INITIALIZER(head)                                          \
405           { TAILQ_END(head), &(head).tqh_first }
406 
407 #define   _TAILQ_ENTRY(type, qual)                                              \
408 struct {                                                                        \
409           qual type *tqe_next;                    /* next element */            \
410           qual type *qual *tqe_prev;    /* address of previous next element */\
411 }
412 #define TAILQ_ENTRY(type)     _TAILQ_ENTRY(struct type,)
413 
414 /*
415  * Tail queue access methods.
416  */
417 #define   TAILQ_FIRST(head)             ((head)->tqh_first)
418 #define   TAILQ_END(head)                         (NULL)
419 #define   TAILQ_NEXT(elm, field)                  ((elm)->field.tqe_next)
420 #define   TAILQ_LAST(head, headname) \
421           (*(((struct headname *)(void *)((head)->tqh_last))->tqh_last))
422 #define   TAILQ_PREV(elm, headname, field) \
423           (*(((struct headname *)(void *)((elm)->field.tqe_prev))->tqh_last))
424 #define   TAILQ_EMPTY(head)             (TAILQ_FIRST(head) == TAILQ_END(head))
425 
426 
427 #define   TAILQ_FOREACH(var, head, field)                                                 \
428           for ((var) = ((head)->tqh_first);                                     \
429               (var) != TAILQ_END(head);                                         \
430               (var) = ((var)->field.tqe_next))
431 
432 #define   TAILQ_FOREACH_SAFE(var, head, field, next)                            \
433           for ((var) = ((head)->tqh_first);                                     \
434               (var) != TAILQ_END(head) &&                                                 \
435               ((next) = TAILQ_NEXT(var, field), 1); (var) = (next))
436 
437 #define   TAILQ_FOREACH_REVERSE(var, head, headname, field)           \
438           for ((var) = TAILQ_LAST((head), headname);                            \
439               (var) != TAILQ_END(head);                                         \
440               (var) = TAILQ_PREV((var), headname, field))
441 
442 #define   TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, prev)          \
443           for ((var) = TAILQ_LAST((head), headname);                            \
444               (var) != TAILQ_END(head) &&                                       \
445               ((prev) = TAILQ_PREV((var), headname, field), 1); (var) = (prev))
446 
447 /*
448  * Tail queue functions.
449  */
450 #if defined(QUEUEDEBUG)
451 #define   QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field)                        \
452           if ((head)->tqh_first &&                                              \
453               (head)->tqh_first->field.tqe_prev != &(head)->tqh_first)          \
454                     QUEUEDEBUG_ABORT("TAILQ_INSERT_HEAD %p %s:%d", (head),      \
455                         __FILE__, __LINE__);
456 #define   QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field)                        \
457           if (*(head)->tqh_last != NULL)                                                  \
458                     QUEUEDEBUG_ABORT("TAILQ_INSERT_TAIL %p %s:%d", (head),      \
459                         __FILE__, __LINE__);
460 #define   QUEUEDEBUG_TAILQ_OP(elm, field)                                                 \
461           if ((elm)->field.tqe_next &&                                          \
462               (elm)->field.tqe_next->field.tqe_prev !=                          \
463               &(elm)->field.tqe_next)                                           \
464                     QUEUEDEBUG_ABORT("TAILQ_* forw %p %s:%d", (elm),  \
465                         __FILE__, __LINE__);                                    \
466           if (*(elm)->field.tqe_prev != (elm))                                  \
467                     QUEUEDEBUG_ABORT("TAILQ_* back %p %s:%d", (elm),  \
468                         __FILE__, __LINE__);
469 #define   QUEUEDEBUG_TAILQ_PREREMOVE(head, elm, field)                          \
470           if ((elm)->field.tqe_next == NULL &&                                  \
471               (head)->tqh_last != &(elm)->field.tqe_next)                       \
472                     QUEUEDEBUG_ABORT("TAILQ_PREREMOVE head %p elm %p %s:%d",\
473                         (head), (elm), __FILE__, __LINE__);
474 #define   QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field)                               \
475           (elm)->field.tqe_next = (void *)1L;                                   \
476           (elm)->field.tqe_prev = (void *)1L;
477 #else
478 #define   QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field)
479 #define   QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field)
480 #define   QUEUEDEBUG_TAILQ_OP(elm, field)
481 #define   QUEUEDEBUG_TAILQ_PREREMOVE(head, elm, field)
482 #define   QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field)
483 #endif
484 
485 #define   TAILQ_INIT(head) do {                                                           \
486           (head)->tqh_first = TAILQ_END(head);                                  \
487           (head)->tqh_last = &(head)->tqh_first;                                \
488 } while (0)
489 
490 #define   TAILQ_INSERT_HEAD(head, elm, field) do {                              \
491           QUEUEDEBUG_TAILQ_INSERT_HEAD((head), (elm), field)                    \
492           if (((elm)->field.tqe_next = (head)->tqh_first) != TAILQ_END(head))\
493                     (head)->tqh_first->field.tqe_prev =                         \
494                         &(elm)->field.tqe_next;                                 \
495           else                                                                            \
496                     (head)->tqh_last = &(elm)->field.tqe_next;                  \
497           (head)->tqh_first = (elm);                                            \
498           (elm)->field.tqe_prev = &(head)->tqh_first;                           \
499 } while (0)
500 
501 #define   TAILQ_INSERT_TAIL(head, elm, field) do {                              \
502           QUEUEDEBUG_TAILQ_INSERT_TAIL((head), (elm), field)                    \
503           (elm)->field.tqe_next = TAILQ_END(head);                              \
504           (elm)->field.tqe_prev = (head)->tqh_last;                             \
505           *(head)->tqh_last = (elm);                                            \
506           (head)->tqh_last = &(elm)->field.tqe_next;                            \
507 } while (0)
508 
509 #define   TAILQ_INSERT_AFTER(head, listelm, elm, field) do {                    \
510           QUEUEDEBUG_TAILQ_OP((listelm), field)                                 \
511           if (((elm)->field.tqe_next = (listelm)->field.tqe_next) !=  \
512               TAILQ_END(head))                                                            \
513                     (elm)->field.tqe_next->field.tqe_prev =                     \
514                         &(elm)->field.tqe_next;                                 \
515           else                                                                            \
516                     (head)->tqh_last = &(elm)->field.tqe_next;                  \
517           (listelm)->field.tqe_next = (elm);                                    \
518           (elm)->field.tqe_prev = &(listelm)->field.tqe_next;                   \
519 } while (0)
520 
521 #define   TAILQ_INSERT_BEFORE(listelm, elm, field) do {                         \
522           QUEUEDEBUG_TAILQ_OP((listelm), field)                                 \
523           (elm)->field.tqe_prev = (listelm)->field.tqe_prev;                    \
524           (elm)->field.tqe_next = (listelm);                                    \
525           *(listelm)->field.tqe_prev = (elm);                                   \
526           (listelm)->field.tqe_prev = &(elm)->field.tqe_next;                   \
527 } while (0)
528 
529 #define   TAILQ_REMOVE(head, elm, field) do {                                   \
530           QUEUEDEBUG_TAILQ_PREREMOVE((head), (elm), field)            \
531           QUEUEDEBUG_TAILQ_OP((elm), field)                                     \
532           if (((elm)->field.tqe_next) != TAILQ_END(head))                       \
533                     (elm)->field.tqe_next->field.tqe_prev =                     \
534                         (elm)->field.tqe_prev;                                  \
535           else                                                                            \
536                     (head)->tqh_last = (elm)->field.tqe_prev;                   \
537           *(elm)->field.tqe_prev = (elm)->field.tqe_next;                       \
538           QUEUEDEBUG_TAILQ_POSTREMOVE((elm), field);                            \
539 } while (0)
540 
541 #define TAILQ_REPLACE(head, elm, elm2, field) do {                              \
542         if (((elm2)->field.tqe_next = (elm)->field.tqe_next) !=       \
543               TAILQ_END(head))                                                            \
544                 (elm2)->field.tqe_next->field.tqe_prev =              \
545                     &(elm2)->field.tqe_next;                                    \
546         else                                                                              \
547                 (head)->tqh_last = &(elm2)->field.tqe_next;           \
548         (elm2)->field.tqe_prev = (elm)->field.tqe_prev;                         \
549         *(elm2)->field.tqe_prev = (elm2);                                       \
550           QUEUEDEBUG_TAILQ_POSTREMOVE((elm), field);                            \
551 } while (0)
552 
553 #define   TAILQ_CONCAT(head1, head2, field) do {                                \
554           if (!TAILQ_EMPTY(head2)) {                                            \
555                     *(head1)->tqh_last = (head2)->tqh_first;                    \
556                     (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last;     \
557                     (head1)->tqh_last = (head2)->tqh_last;                      \
558                     TAILQ_INIT((head2));                                                  \
559           }                                                                               \
560 } while (0)
561 
562 /*
563  * Singly-linked Tail queue declarations.
564  */
565 #define   STAILQ_HEAD(name, type)                                                         \
566 struct name {                                                                             \
567           struct type *stqh_first;      /* first element */           \
568           struct type **stqh_last;      /* addr of last next element */         \
569 }
570 
571 #define   STAILQ_HEAD_INITIALIZER(head)                                         \
572           { NULL, &(head).stqh_first }
573 
574 #define   STAILQ_ENTRY(type)                                                    \
575 struct {                                                                        \
576           struct type *stqe_next;       /* next element */                      \
577 }
578 
579 /*
580  * Singly-linked Tail queue access methods.
581  */
582 #define   STAILQ_FIRST(head)  ((head)->stqh_first)
583 #define   STAILQ_END(head)    NULL
584 #define   STAILQ_NEXT(elm, field)       ((elm)->field.stqe_next)
585 #define   STAILQ_EMPTY(head)  (STAILQ_FIRST(head) == STAILQ_END(head))
586 
587 /*
588  * Singly-linked Tail queue functions.
589  */
590 #define   STAILQ_INIT(head) do {                                                          \
591           (head)->stqh_first = NULL;                                            \
592           (head)->stqh_last = &(head)->stqh_first;                                        \
593 } while (0)
594 
595 #define   STAILQ_INSERT_HEAD(head, elm, field) do {                             \
596           if (((elm)->field.stqe_next = (head)->stqh_first) == NULL)  \
597                     (head)->stqh_last = &(elm)->field.stqe_next;                \
598           (head)->stqh_first = (elm);                                           \
599 } while (0)
600 
601 #define   STAILQ_INSERT_TAIL(head, elm, field) do {                             \
602           (elm)->field.stqe_next = NULL;                                                  \
603           *(head)->stqh_last = (elm);                                           \
604           (head)->stqh_last = &(elm)->field.stqe_next;                          \
605 } while (0)
606 
607 #define   STAILQ_INSERT_AFTER(head, listelm, elm, field) do {                   \
608           if (((elm)->field.stqe_next = (listelm)->field.stqe_next) == NULL)\
609                     (head)->stqh_last = &(elm)->field.stqe_next;                \
610           (listelm)->field.stqe_next = (elm);                                   \
611 } while (0)
612 
613 #define   STAILQ_REMOVE_HEAD(head, field) do {                                  \
614           if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == NULL) \
615                     (head)->stqh_last = &(head)->stqh_first;                              \
616 } while (0)
617 
618 #define   STAILQ_REMOVE(head, elm, type, field) do {                            \
619           if ((head)->stqh_first == (elm)) {                                    \
620                     STAILQ_REMOVE_HEAD((head), field);                          \
621           } else {                                                              \
622                     struct type *curelm = (head)->stqh_first;                   \
623                     while (curelm->field.stqe_next != (elm))                              \
624                               curelm = curelm->field.stqe_next;                 \
625                     if ((curelm->field.stqe_next =                                        \
626                               curelm->field.stqe_next->field.stqe_next) == NULL) \
627                                   (head)->stqh_last = &(curelm)->field.stqe_next; \
628           }                                                                               \
629 } while (0)
630 
631 #define   STAILQ_FOREACH(var, head, field)                                      \
632           for ((var) = ((head)->stqh_first);                                    \
633                     (var);                                                                \
634                     (var) = ((var)->field.stqe_next))
635 
636 #define   STAILQ_FOREACH_SAFE(var, head, field, tvar)                           \
637           for ((var) = STAILQ_FIRST((head));                                    \
638               (var) && ((tvar) = STAILQ_NEXT((var), field), 1);                 \
639               (var) = (tvar))
640 
641 #define   STAILQ_CONCAT(head1, head2) do {                                      \
642           if (!STAILQ_EMPTY((head2))) {                                         \
643                     *(head1)->stqh_last = (head2)->stqh_first;                  \
644                     (head1)->stqh_last = (head2)->stqh_last;                    \
645                     STAILQ_INIT((head2));                                                 \
646           }                                                                               \
647 } while (0)
648 
649 #define   STAILQ_LAST(head, type, field)                                                  \
650           (STAILQ_EMPTY((head)) ?                                                         \
651                     NULL :                                                                \
652                   ((struct type *)(void *)                                      \
653                     ((char *)((head)->stqh_last) - offsetof(struct type, field))))
654 
655 #endif    /* !_SYS_QUEUE_H_ */
656