Subversion Repositories Kolibri OS

Rev

Rev 4921 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  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 _SYS_QUEUE_H_
  34. #define _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 be traversed in either 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.  *                              SLIST   LIST    STAILQ  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. #ifdef QUEUE_MACRO_DEBUG
  106. /* Store the last 2 places the queue element or head was altered */
  107. struct qm_trace {
  108.         unsigned long    lastline;
  109.         unsigned long    prevline;
  110.         const char      *lastfile;
  111.         const char      *prevfile;
  112. };
  113.  
  114. #define TRACEBUF        struct qm_trace trace;
  115. #define TRACEBUF_INITIALIZER    { __FILE__, __LINE__, NULL, 0 } ,
  116. #define TRASHIT(x)      do {(x) = (void *)-1;} while (0)
  117. #define QMD_SAVELINK(name, link)        void **name = (void *)&(link)
  118.  
  119. #define QMD_TRACE_HEAD(head) do {                                       \
  120.         (head)->trace.prevline = (head)->trace.lastline;                \
  121.         (head)->trace.prevfile = (head)->trace.lastfile;                \
  122.         (head)->trace.lastline = __LINE__;                              \
  123.         (head)->trace.lastfile = __FILE__;                              \
  124. } while (0)
  125.  
  126. #define QMD_TRACE_ELEM(elem) do {                                       \
  127.         (elem)->trace.prevline = (elem)->trace.lastline;                \
  128.         (elem)->trace.prevfile = (elem)->trace.lastfile;                \
  129.         (elem)->trace.lastline = __LINE__;                              \
  130.         (elem)->trace.lastfile = __FILE__;                              \
  131. } while (0)
  132.  
  133. #else
  134. #define QMD_TRACE_ELEM(elem)
  135. #define QMD_TRACE_HEAD(head)
  136. #define QMD_SAVELINK(name, link)
  137. #define TRACEBUF
  138. #define TRACEBUF_INITIALIZER
  139. #define TRASHIT(x)
  140. #endif  /* QUEUE_MACRO_DEBUG */
  141.  
  142. /*
  143.  * Singly-linked List declarations.
  144.  */
  145. #define SLIST_HEAD(name, type)                                          \
  146. struct name {                                                           \
  147.         struct type *slh_first; /* first element */                     \
  148. }
  149.  
  150. #define SLIST_HEAD_INITIALIZER(head)                                    \
  151.         { NULL }
  152.  
  153. #define SLIST_ENTRY(type)                                               \
  154. struct {                                                                \
  155.         struct type *sle_next;  /* next element */                      \
  156. }
  157.  
  158. /*
  159.  * Singly-linked List functions.
  160.  */
  161. #define SLIST_EMPTY(head)       ((head)->slh_first == NULL)
  162.  
  163. #define SLIST_FIRST(head)       ((head)->slh_first)
  164.  
  165. #define SLIST_FOREACH(var, head, field)                                 \
  166.         for ((var) = SLIST_FIRST((head));                               \
  167.             (var);                                                      \
  168.             (var) = SLIST_NEXT((var), field))
  169.  
  170. #define SLIST_FOREACH_SAFE(var, head, field, tvar)                      \
  171.         for ((var) = SLIST_FIRST((head));                               \
  172.             (var) && ((tvar) = SLIST_NEXT((var), field), 1);            \
  173.             (var) = (tvar))
  174.  
  175. #define SLIST_FOREACH_PREVPTR(var, varp, head, field)                   \
  176.         for ((varp) = &SLIST_FIRST((head));                             \
  177.             ((var) = *(varp)) != NULL;                                  \
  178.             (varp) = &SLIST_NEXT((var), field))
  179.  
  180. #define SLIST_INIT(head) do {                                           \
  181.         SLIST_FIRST((head)) = NULL;                                     \
  182. } while (0)
  183.  
  184. #define SLIST_INSERT_AFTER(slistelm, elm, field) do {                   \
  185.         SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field);       \
  186.         SLIST_NEXT((slistelm), field) = (elm);                          \
  187. } while (0)
  188.  
  189. #define SLIST_INSERT_HEAD(head, elm, field) do {                        \
  190.         SLIST_NEXT((elm), field) = SLIST_FIRST((head));                 \
  191.         SLIST_FIRST((head)) = (elm);                                    \
  192. } while (0)
  193.  
  194. #define SLIST_NEXT(elm, field)  ((elm)->field.sle_next)
  195.  
  196. #define SLIST_REMOVE(head, elm, type, field) do {                       \
  197.         QMD_SAVELINK(oldnext, (elm)->field.sle_next);                   \
  198.         if (SLIST_FIRST((head)) == (elm)) {                             \
  199.                 SLIST_REMOVE_HEAD((head), field);                       \
  200.         }                                                               \
  201.         else {                                                          \
  202.                 struct type *curelm = SLIST_FIRST((head));              \
  203.                 while (SLIST_NEXT(curelm, field) != (elm))              \
  204.                         curelm = SLIST_NEXT(curelm, field);             \
  205.                 SLIST_REMOVE_AFTER(curelm, field);                      \
  206.         }                                                               \
  207.         TRASHIT(*oldnext);                                              \
  208. } while (0)
  209.  
  210. #define SLIST_REMOVE_AFTER(elm, field) do {                             \
  211.         SLIST_NEXT(elm, field) =                                        \
  212.             SLIST_NEXT(SLIST_NEXT(elm, field), field);                  \
  213. } while (0)
  214.  
  215. #define SLIST_REMOVE_HEAD(head, field) do {                             \
  216.         SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field);   \
  217. } while (0)
  218.  
  219. #define SLIST_SWAP(head1, head2, type) do {                             \
  220.         struct type *swap_first = SLIST_FIRST(head1);                   \
  221.         SLIST_FIRST(head1) = SLIST_FIRST(head2);                        \
  222.         SLIST_FIRST(head2) = swap_first;                                \
  223. } while (0)
  224.  
  225. /*
  226.  * Singly-linked Tail queue declarations.
  227.  */
  228. #define STAILQ_HEAD(name, type)                                         \
  229. struct name {                                                           \
  230.         struct type *stqh_first;/* first element */                     \
  231.         struct type **stqh_last;/* addr of last next element */         \
  232. }
  233.  
  234. #define STAILQ_HEAD_INITIALIZER(head)                                   \
  235.         { NULL, &(head).stqh_first }
  236.  
  237. #define STAILQ_ENTRY(type)                                              \
  238. struct {                                                                \
  239.         struct type *stqe_next; /* next element */                      \
  240. }
  241.  
  242. /*
  243.  * Singly-linked Tail queue functions.
  244.  */
  245. #define STAILQ_CONCAT(head1, head2) do {                                \
  246.         if (!STAILQ_EMPTY((head2))) {                                   \
  247.                 *(head1)->stqh_last = (head2)->stqh_first;              \
  248.                 (head1)->stqh_last = (head2)->stqh_last;                \
  249.                 STAILQ_INIT((head2));                                   \
  250.         }                                                               \
  251. } while (0)
  252.  
  253. #define STAILQ_EMPTY(head)      ((head)->stqh_first == NULL)
  254.  
  255. #define STAILQ_FIRST(head)      ((head)->stqh_first)
  256.  
  257. #define STAILQ_FOREACH(var, head, field)                                \
  258.         for((var) = STAILQ_FIRST((head));                               \
  259.            (var);                                                       \
  260.            (var) = STAILQ_NEXT((var), field))
  261.  
  262.  
  263. #define STAILQ_FOREACH_SAFE(var, head, field, tvar)                     \
  264.         for ((var) = STAILQ_FIRST((head));                              \
  265.             (var) && ((tvar) = STAILQ_NEXT((var), field), 1);           \
  266.             (var) = (tvar))
  267.  
  268. #define STAILQ_INIT(head) do {                                          \
  269.         STAILQ_FIRST((head)) = NULL;                                    \
  270.         (head)->stqh_last = &STAILQ_FIRST((head));                      \
  271. } while (0)
  272.  
  273. #define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do {               \
  274.         if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
  275.                 (head)->stqh_last = &STAILQ_NEXT((elm), field);         \
  276.         STAILQ_NEXT((tqelm), field) = (elm);                            \
  277. } while (0)
  278.  
  279. #define STAILQ_INSERT_HEAD(head, elm, field) do {                       \
  280.         if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
  281.                 (head)->stqh_last = &STAILQ_NEXT((elm), field);         \
  282.         STAILQ_FIRST((head)) = (elm);                                   \
  283. } while (0)
  284.  
  285. #define STAILQ_INSERT_TAIL(head, elm, field) do {                       \
  286.         STAILQ_NEXT((elm), field) = NULL;                               \
  287.         *(head)->stqh_last = (elm);                                     \
  288.         (head)->stqh_last = &STAILQ_NEXT((elm), field);                 \
  289. } while (0)
  290.  
  291. #define STAILQ_LAST(head, type, field)                                  \
  292.         (STAILQ_EMPTY((head)) ? NULL :                                  \
  293.             __containerof((head)->stqh_last, struct type, field.stqe_next))
  294.  
  295. #define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
  296.  
  297. #define STAILQ_REMOVE(head, elm, type, field) do {                      \
  298.         QMD_SAVELINK(oldnext, (elm)->field.stqe_next);                  \
  299.         if (STAILQ_FIRST((head)) == (elm)) {                            \
  300.                 STAILQ_REMOVE_HEAD((head), field);                      \
  301.         }                                                               \
  302.         else {                                                          \
  303.                 struct type *curelm = STAILQ_FIRST((head));             \
  304.                 while (STAILQ_NEXT(curelm, field) != (elm))             \
  305.                         curelm = STAILQ_NEXT(curelm, field);            \
  306.                 STAILQ_REMOVE_AFTER(head, curelm, field);               \
  307.         }                                                               \
  308.         TRASHIT(*oldnext);                                              \
  309. } while (0)
  310.  
  311. #define STAILQ_REMOVE_AFTER(head, elm, field) do {                      \
  312.         if ((STAILQ_NEXT(elm, field) =                                  \
  313.              STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL)      \
  314.                 (head)->stqh_last = &STAILQ_NEXT((elm), field);         \
  315. } while (0)
  316.  
  317. #define STAILQ_REMOVE_HEAD(head, field) do {                            \
  318.         if ((STAILQ_FIRST((head)) =                                     \
  319.              STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL)         \
  320.                 (head)->stqh_last = &STAILQ_FIRST((head));              \
  321. } while (0)
  322.  
  323. #define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do {                 \
  324.         if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \
  325.                 (head)->stqh_last = &STAILQ_FIRST((head));              \
  326. } while (0)
  327.  
  328. #define STAILQ_SWAP(head1, head2, type) do {                            \
  329.         struct type *swap_first = STAILQ_FIRST(head1);                  \
  330.         struct type **swap_last = (head1)->stqh_last;                   \
  331.         STAILQ_FIRST(head1) = STAILQ_FIRST(head2);                      \
  332.         (head1)->stqh_last = (head2)->stqh_last;                        \
  333.         STAILQ_FIRST(head2) = swap_first;                               \
  334.         (head2)->stqh_last = swap_last;                                 \
  335.         if (STAILQ_EMPTY(head1))                                        \
  336.                 (head1)->stqh_last = &STAILQ_FIRST(head1);              \
  337.         if (STAILQ_EMPTY(head2))                                        \
  338.                 (head2)->stqh_last = &STAILQ_FIRST(head2);              \
  339. } while (0)
  340.  
  341.  
  342. /*
  343.  * List declarations.
  344.  */
  345. #define LIST_HEAD(name, type)                                           \
  346. struct name {                                                           \
  347.         struct type *lh_first;  /* first element */                     \
  348. }
  349.  
  350. #define LIST_HEAD_INITIALIZER(head)                                     \
  351.         { NULL }
  352.  
  353. #define LIST_ENTRY(type)                                                \
  354. struct {                                                                \
  355.         struct type *le_next;   /* next element */                      \
  356.         struct type **le_prev;  /* address of previous next element */  \
  357. }
  358.  
  359. /*
  360.  * List functions.
  361.  */
  362.  
  363. #if (defined(_KERNEL) && defined(INVARIANTS))
  364. #define QMD_LIST_CHECK_HEAD(head, field) do {                           \
  365.         if (LIST_FIRST((head)) != NULL &&                               \
  366.             LIST_FIRST((head))->field.le_prev !=                        \
  367.              &LIST_FIRST((head)))                                       \
  368.                 panic("Bad list head %p first->prev != head", (head));  \
  369. } while (0)
  370.  
  371. #define QMD_LIST_CHECK_NEXT(elm, field) do {                            \
  372.         if (LIST_NEXT((elm), field) != NULL &&                          \
  373.             LIST_NEXT((elm), field)->field.le_prev !=                   \
  374.              &((elm)->field.le_next))                                   \
  375.                 panic("Bad link elm %p next->prev != elm", (elm));      \
  376. } while (0)
  377.  
  378. #define QMD_LIST_CHECK_PREV(elm, field) do {                            \
  379.         if (*(elm)->field.le_prev != (elm))                             \
  380.                 panic("Bad link elm %p prev->next != elm", (elm));      \
  381. } while (0)
  382. #else
  383. #define QMD_LIST_CHECK_HEAD(head, field)
  384. #define QMD_LIST_CHECK_NEXT(elm, field)
  385. #define QMD_LIST_CHECK_PREV(elm, field)
  386. #endif /* (_KERNEL && INVARIANTS) */
  387.  
  388. #define LIST_EMPTY(head)        ((head)->lh_first == NULL)
  389.  
  390. #define LIST_FIRST(head)        ((head)->lh_first)
  391.  
  392. #define LIST_FOREACH(var, head, field)                                  \
  393.         for ((var) = LIST_FIRST((head));                                \
  394.             (var);                                                      \
  395.             (var) = LIST_NEXT((var), field))
  396.  
  397. #define LIST_FOREACH_SAFE(var, head, field, tvar)                       \
  398.         for ((var) = LIST_FIRST((head));                                \
  399.             (var) && ((tvar) = LIST_NEXT((var), field), 1);             \
  400.             (var) = (tvar))
  401.  
  402. #define LIST_INIT(head) do {                                            \
  403.         LIST_FIRST((head)) = NULL;                                      \
  404. } while (0)
  405.  
  406. #define LIST_INSERT_AFTER(listelm, elm, field) do {                     \
  407.         QMD_LIST_CHECK_NEXT(listelm, field);                            \
  408.         if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
  409.                 LIST_NEXT((listelm), field)->field.le_prev =            \
  410.                     &LIST_NEXT((elm), field);                           \
  411.         LIST_NEXT((listelm), field) = (elm);                            \
  412.         (elm)->field.le_prev = &LIST_NEXT((listelm), field);            \
  413. } while (0)
  414.  
  415. #define LIST_INSERT_BEFORE(listelm, elm, field) do {                    \
  416.         QMD_LIST_CHECK_PREV(listelm, field);                            \
  417.         (elm)->field.le_prev = (listelm)->field.le_prev;                \
  418.         LIST_NEXT((elm), field) = (listelm);                            \
  419.         *(listelm)->field.le_prev = (elm);                              \
  420.         (listelm)->field.le_prev = &LIST_NEXT((elm), field);            \
  421. } while (0)
  422.  
  423. #define LIST_INSERT_HEAD(head, elm, field) do {                         \
  424.         QMD_LIST_CHECK_HEAD((head), field);                             \
  425.         if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL)     \
  426.                 LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
  427.         LIST_FIRST((head)) = (elm);                                     \
  428.         (elm)->field.le_prev = &LIST_FIRST((head));                     \
  429. } while (0)
  430.  
  431. #define LIST_NEXT(elm, field)   ((elm)->field.le_next)
  432.  
  433. #define LIST_PREV(elm, head, type, field)                               \
  434.         ((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL :           \
  435.             __containerof((elm)->field.le_prev, struct type, field.le_next))
  436.  
  437. #define LIST_REMOVE(elm, field) do {                                    \
  438.         QMD_SAVELINK(oldnext, (elm)->field.le_next);                    \
  439.         QMD_SAVELINK(oldprev, (elm)->field.le_prev);                    \
  440.         QMD_LIST_CHECK_NEXT(elm, field);                                \
  441.         QMD_LIST_CHECK_PREV(elm, field);                                \
  442.         if (LIST_NEXT((elm), field) != NULL)                            \
  443.                 LIST_NEXT((elm), field)->field.le_prev =                \
  444.                     (elm)->field.le_prev;                               \
  445.         *(elm)->field.le_prev = LIST_NEXT((elm), field);                \
  446.         TRASHIT(*oldnext);                                              \
  447.         TRASHIT(*oldprev);                                              \
  448. } while (0)
  449.  
  450. #define LIST_SWAP(head1, head2, type, field) do {                       \
  451.         struct type *swap_tmp = LIST_FIRST((head1));                    \
  452.         LIST_FIRST((head1)) = LIST_FIRST((head2));                      \
  453.         LIST_FIRST((head2)) = swap_tmp;                                 \
  454.         if ((swap_tmp = LIST_FIRST((head1))) != NULL)                   \
  455.                 swap_tmp->field.le_prev = &LIST_FIRST((head1));         \
  456.         if ((swap_tmp = LIST_FIRST((head2))) != NULL)                   \
  457.                 swap_tmp->field.le_prev = &LIST_FIRST((head2));         \
  458. } while (0)
  459.  
  460. /*
  461.  * Tail queue declarations.
  462.  */
  463. #define TAILQ_HEAD(name, type)                                          \
  464. struct name {                                                           \
  465.         struct type *tqh_first; /* first element */                     \
  466.         struct type **tqh_last; /* addr of last next element */         \
  467.         TRACEBUF                                                        \
  468. }
  469.  
  470. #define TAILQ_HEAD_INITIALIZER(head)                                    \
  471.         { NULL, &(head).tqh_first, TRACEBUF_INITIALIZER }
  472.  
  473. #define TAILQ_ENTRY(type)                                               \
  474. struct {                                                                \
  475.         struct type *tqe_next;  /* next element */                      \
  476.         struct type **tqe_prev; /* address of previous next element */  \
  477.         TRACEBUF                                                        \
  478. }
  479.  
  480. /*
  481.  * Tail queue functions.
  482.  */
  483. #if (defined(_KERNEL) && defined(INVARIANTS))
  484. #define QMD_TAILQ_CHECK_HEAD(head, field) do {                          \
  485.         if (!TAILQ_EMPTY(head) &&                                       \
  486.             TAILQ_FIRST((head))->field.tqe_prev !=                      \
  487.              &TAILQ_FIRST((head)))                                      \
  488.                 panic("Bad tailq head %p first->prev != head", (head)); \
  489. } while (0)
  490.  
  491. #define QMD_TAILQ_CHECK_TAIL(head, field) do {                          \
  492.         if (*(head)->tqh_last != NULL)                                  \
  493.                 panic("Bad tailq NEXT(%p->tqh_last) != NULL", (head));  \
  494. } while (0)
  495.  
  496. #define QMD_TAILQ_CHECK_NEXT(elm, field) do {                           \
  497.         if (TAILQ_NEXT((elm), field) != NULL &&                         \
  498.             TAILQ_NEXT((elm), field)->field.tqe_prev !=                 \
  499.              &((elm)->field.tqe_next))                                  \
  500.                 panic("Bad link elm %p next->prev != elm", (elm));      \
  501. } while (0)
  502.  
  503. #define QMD_TAILQ_CHECK_PREV(elm, field) do {                           \
  504.         if (*(elm)->field.tqe_prev != (elm))                            \
  505.                 panic("Bad link elm %p prev->next != elm", (elm));      \
  506. } while (0)
  507. #else
  508. #define QMD_TAILQ_CHECK_HEAD(head, field)
  509. #define QMD_TAILQ_CHECK_TAIL(head, headname)
  510. #define QMD_TAILQ_CHECK_NEXT(elm, field)
  511. #define QMD_TAILQ_CHECK_PREV(elm, field)
  512. #endif /* (_KERNEL && INVARIANTS) */
  513.  
  514. #define TAILQ_CONCAT(head1, head2, field) do {                          \
  515.         if (!TAILQ_EMPTY(head2)) {                                      \
  516.                 *(head1)->tqh_last = (head2)->tqh_first;                \
  517.                 (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
  518.                 (head1)->tqh_last = (head2)->tqh_last;                  \
  519.                 TAILQ_INIT((head2));                                    \
  520.                 QMD_TRACE_HEAD(head1);                                  \
  521.                 QMD_TRACE_HEAD(head2);                                  \
  522.         }                                                               \
  523. } while (0)
  524.  
  525. #define TAILQ_EMPTY(head)       ((head)->tqh_first == NULL)
  526.  
  527. #define TAILQ_FIRST(head)       ((head)->tqh_first)
  528.  
  529. #define TAILQ_FOREACH(var, head, field)                                 \
  530.         for ((var) = TAILQ_FIRST((head));                               \
  531.             (var);                                                      \
  532.             (var) = TAILQ_NEXT((var), field))
  533.  
  534. #define TAILQ_FOREACH_SAFE(var, head, field, tvar)                      \
  535.         for ((var) = TAILQ_FIRST((head));                               \
  536.             (var) && ((tvar) = TAILQ_NEXT((var), field), 1);            \
  537.             (var) = (tvar))
  538.  
  539. #define TAILQ_FOREACH_REVERSE(var, head, headname, field)               \
  540.         for ((var) = TAILQ_LAST((head), headname);                      \
  541.             (var);                                                      \
  542.             (var) = TAILQ_PREV((var), headname, field))
  543.  
  544. #define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar)    \
  545.         for ((var) = TAILQ_LAST((head), headname);                      \
  546.             (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1);  \
  547.             (var) = (tvar))
  548.  
  549. #define TAILQ_INIT(head) do {                                           \
  550.         TAILQ_FIRST((head)) = NULL;                                     \
  551.         (head)->tqh_last = &TAILQ_FIRST((head));                        \
  552.         QMD_TRACE_HEAD(head);                                           \
  553. } while (0)
  554.  
  555. #define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {              \
  556.         QMD_TAILQ_CHECK_NEXT(listelm, field);                           \
  557.         if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
  558.                 TAILQ_NEXT((elm), field)->field.tqe_prev =              \
  559.                     &TAILQ_NEXT((elm), field);                          \
  560.         else {                                                          \
  561.                 (head)->tqh_last = &TAILQ_NEXT((elm), field);           \
  562.                 QMD_TRACE_HEAD(head);                                   \
  563.         }                                                               \
  564.         TAILQ_NEXT((listelm), field) = (elm);                           \
  565.         (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field);          \
  566.         QMD_TRACE_ELEM(&(elm)->field);                                  \
  567.         QMD_TRACE_ELEM(&listelm->field);                                \
  568. } while (0)
  569.  
  570. #define TAILQ_INSERT_BEFORE(listelm, elm, field) do {                   \
  571.         QMD_TAILQ_CHECK_PREV(listelm, field);                           \
  572.         (elm)->field.tqe_prev = (listelm)->field.tqe_prev;              \
  573.         TAILQ_NEXT((elm), field) = (listelm);                           \
  574.         *(listelm)->field.tqe_prev = (elm);                             \
  575.         (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field);          \
  576.         QMD_TRACE_ELEM(&(elm)->field);                                  \
  577.         QMD_TRACE_ELEM(&listelm->field);                                \
  578. } while (0)
  579.  
  580. #define TAILQ_INSERT_HEAD(head, elm, field) do {                        \
  581.         QMD_TAILQ_CHECK_HEAD(head, field);                              \
  582.         if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL)   \
  583.                 TAILQ_FIRST((head))->field.tqe_prev =                   \
  584.                     &TAILQ_NEXT((elm), field);                          \
  585.         else                                                            \
  586.                 (head)->tqh_last = &TAILQ_NEXT((elm), field);           \
  587.         TAILQ_FIRST((head)) = (elm);                                    \
  588.         (elm)->field.tqe_prev = &TAILQ_FIRST((head));                   \
  589.         QMD_TRACE_HEAD(head);                                           \
  590.         QMD_TRACE_ELEM(&(elm)->field);                                  \
  591. } while (0)
  592.  
  593. #define TAILQ_INSERT_TAIL(head, elm, field) do {                        \
  594.         QMD_TAILQ_CHECK_TAIL(head, field);                              \
  595.         TAILQ_NEXT((elm), field) = NULL;                                \
  596.         (elm)->field.tqe_prev = (head)->tqh_last;                       \
  597.         *(head)->tqh_last = (elm);                                      \
  598.         (head)->tqh_last = &TAILQ_NEXT((elm), field);                   \
  599.         QMD_TRACE_HEAD(head);                                           \
  600.         QMD_TRACE_ELEM(&(elm)->field);                                  \
  601. } while (0)
  602.  
  603. #define TAILQ_LAST(head, headname)                                      \
  604.         (*(((struct headname *)((head)->tqh_last))->tqh_last))
  605.  
  606. #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
  607.  
  608. #define TAILQ_PREV(elm, headname, field)                                \
  609.         (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
  610.  
  611. #define TAILQ_REMOVE(head, elm, field) do {                             \
  612.         QMD_SAVELINK(oldnext, (elm)->field.tqe_next);                   \
  613.         QMD_SAVELINK(oldprev, (elm)->field.tqe_prev);                   \
  614.         QMD_TAILQ_CHECK_NEXT(elm, field);                               \
  615.         QMD_TAILQ_CHECK_PREV(elm, field);                               \
  616.         if ((TAILQ_NEXT((elm), field)) != NULL)                         \
  617.                 TAILQ_NEXT((elm), field)->field.tqe_prev =              \
  618.                     (elm)->field.tqe_prev;                              \
  619.         else {                                                          \
  620.                 (head)->tqh_last = (elm)->field.tqe_prev;               \
  621.                 QMD_TRACE_HEAD(head);                                   \
  622.         }                                                               \
  623.         *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field);              \
  624.         TRASHIT(*oldnext);                                              \
  625.         TRASHIT(*oldprev);                                              \
  626.         QMD_TRACE_ELEM(&(elm)->field);                                  \
  627. } while (0)
  628.  
  629. #define TAILQ_SWAP(head1, head2, type, field) do {                      \
  630.         struct type *swap_first = (head1)->tqh_first;                   \
  631.         struct type **swap_last = (head1)->tqh_last;                    \
  632.         (head1)->tqh_first = (head2)->tqh_first;                        \
  633.         (head1)->tqh_last = (head2)->tqh_last;                          \
  634.         (head2)->tqh_first = swap_first;                                \
  635.         (head2)->tqh_last = swap_last;                                  \
  636.         if ((swap_first = (head1)->tqh_first) != NULL)                  \
  637.                 swap_first->field.tqe_prev = &(head1)->tqh_first;       \
  638.         else                                                            \
  639.                 (head1)->tqh_last = &(head1)->tqh_first;                \
  640.         if ((swap_first = (head2)->tqh_first) != NULL)                  \
  641.                 swap_first->field.tqe_prev = &(head2)->tqh_first;       \
  642.         else                                                            \
  643.                 (head2)->tqh_last = &(head2)->tqh_first;                \
  644. } while (0)
  645.  
  646. #ifdef _KERNEL
  647.  
  648. /*
  649.  * XXX insque() and remque() are an old way of handling certain queues.
  650.  * They bogusly assumes that all queue heads look alike.
  651.  */
  652.  
  653. struct quehead {
  654.         struct quehead *qh_link;
  655.         struct quehead *qh_rlink;
  656. };
  657.  
  658. #ifdef  __GNUC__
  659.  
  660. static __inline void
  661. insque(void *a, void *b)
  662. {
  663.         struct quehead *element = (struct quehead *)a,
  664.                  *head = (struct quehead *)b;
  665.  
  666.         element->qh_link = head->qh_link;
  667.         element->qh_rlink = head;
  668.         head->qh_link = element;
  669.         element->qh_link->qh_rlink = element;
  670. }
  671.  
  672. static __inline void
  673. remque(void *a)
  674. {
  675.         struct quehead *element = (struct quehead *)a;
  676.  
  677.         element->qh_link->qh_rlink = element->qh_rlink;
  678.         element->qh_rlink->qh_link = element->qh_link;
  679.         element->qh_rlink = 0;
  680. }
  681.  
  682. #else /* !__GNUC__ */
  683.  
  684. void    insque(void *a, void *b);
  685. void    remque(void *a);
  686.  
  687. #endif /* __GNUC__ */
  688.  
  689. #endif /* _KERNEL */
  690.  
  691. #endif /* !_SYS_QUEUE_H_ */
  692.