The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/sys/queue.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 5c0cbb5365337541b9d03353cb76fada


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.