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