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

Cache object: 085dd80180ad09af0b8e37d455ac2d66


[ 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.