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/gcq.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 /* $NetBSD: gcq.h,v 1.2 2007/08/19 07:35:32 kiyohara Exp $ */
    2 /*
    3  * Not (c) 2007 Matthew Orgass
    4  * This file is public domain, meaning anyone can make any use of part or all 
    5  * of this file including copying into other works without credit.  Any use, 
    6  * modified or not, is solely the responsibility of the user.  If this file is 
    7  * part of a collection then use in the collection is governed by the terms of 
    8  * the collection.
    9  */
   10 
   11 /*
   12  * Generic Circular Queues: Pointer arithmetic is used to recover the 
   13  * enclosing object.  Merge operation is provided.  Items can be multiply 
   14  * removed, but queue traversal requires separate knowledge of the queue head.
   15  */
   16 
   17 #ifndef _GCQ_H
   18 #define _GCQ_H
   19 
   20 #ifdef _KERNEL
   21 #include <sys/types.h>
   22 #include <sys/null.h>
   23 #include <lib/libkern/libkern.h>
   24 #else
   25 #include <stdbool.h>
   26 #include <stdint.h>
   27 #include <stddef.h>
   28 #include <assert.h>
   29 #endif
   30 
   31 #ifdef GCQ_USE_ASSERT
   32 #define GCQ_ASSERT(x) assert(x)
   33 #else
   34 #ifdef _KERNEL
   35 #define GCQ_ASSERT(x) KASSERT(x)
   36 #else
   37 #define GCQ_ASSERT(x) _DIAGASSERT(x)
   38 #endif
   39 #endif
   40 
   41 struct gcq {
   42         struct gcq *q_next;
   43         struct gcq *q_prev;
   44 };
   45 
   46 struct gcq_head {
   47         struct gcq hq;
   48 };
   49 
   50 #define GCQ_INIT(q) { &(q), &(q) }
   51 #define GCQ_INIT_HEAD(head) { GCQ_INIT((head).hq) }
   52 
   53 __attribute__((nonnull, always_inline)) static inline void
   54 gcq_init(struct gcq *q)
   55 {
   56         q->q_next = q->q_prev = q;
   57 }
   58 
   59 __attribute__((nonnull, const, warn_unused_result, always_inline)) 
   60 static inline struct gcq *
   61 gcq_q(struct gcq *q)
   62 {
   63         return q;
   64 }
   65 
   66 __attribute__((nonnull, const, warn_unused_result, always_inline)) 
   67 static inline struct gcq *
   68 gcq_hq(struct gcq_head *head)
   69 {
   70         return (struct gcq *)head;
   71 }
   72 
   73 __attribute__((nonnull, const, warn_unused_result, always_inline)) 
   74 static inline struct gcq_head *
   75 gcq_head(struct gcq *q)
   76 {
   77         return (struct gcq_head *)q;
   78 }
   79 
   80 __attribute__((nonnull, always_inline)) static inline void
   81 gcq_init_head(struct gcq_head *head)
   82 {
   83         gcq_init(gcq_hq(head));
   84 }
   85 
   86 __attribute__((nonnull, pure, warn_unused_result, always_inline))
   87 static inline bool
   88 gcq_onlist(struct gcq *q)
   89 {
   90         return (q->q_next != q);
   91 }
   92 
   93 __attribute__((nonnull, pure, warn_unused_result, always_inline))
   94 static inline bool
   95 gcq_empty(struct gcq_head *head)
   96 {
   97         return (!gcq_onlist(gcq_hq(head)));
   98 }
   99 
  100 __attribute__((nonnull, pure, warn_unused_result, always_inline))
  101 static inline bool
  102 gcq_linked(struct gcq *prev, struct gcq *next)
  103 {
  104         return (prev->q_next == next && next->q_prev == prev);
  105 }
  106 
  107 __attribute__((nonnull, always_inline)) static inline void
  108 gcq_insert_after(struct gcq *on, struct gcq *off)
  109 {
  110         struct gcq *on_next;
  111         GCQ_ASSERT(off->q_next == off && off->q_prev == off);
  112         on_next = on->q_next;
  113 
  114         off->q_prev = on;
  115         off->q_next = on_next;
  116         on_next->q_prev = off;
  117         on->q_next = off;
  118 }
  119 
  120 __attribute__((nonnull)) static inline void
  121 gcq_insert_before(struct gcq *on, struct gcq *off)
  122 {
  123         struct gcq *on_prev;
  124         GCQ_ASSERT(off->q_next == off && off->q_prev == off);
  125         on_prev = on->q_prev;
  126 
  127         off->q_next = on;
  128         off->q_prev = on_prev;
  129         on_prev->q_next = off;
  130         on->q_prev = off;
  131 }
  132 
  133 __attribute__((nonnull, always_inline)) static inline void
  134 gcq_insert_head(struct gcq_head *head, struct gcq *q)
  135 {
  136         gcq_insert_after(gcq_hq(head), q);
  137 }
  138 
  139 __attribute__((nonnull, always_inline)) static inline void
  140 gcq_insert_tail(struct gcq_head *head, struct gcq *q)
  141 {
  142         gcq_insert_before(gcq_hq(head), q);
  143 }
  144 
  145 __attribute__((nonnull)) static inline void
  146 gcq_tie(struct gcq *dst, struct gcq *src)
  147 {
  148         struct gcq *dst_next, *src_prev;
  149         dst_next = dst->q_next;
  150         src_prev = src->q_prev;
  151 
  152         src_prev->q_next = dst_next;
  153         dst_next->q_prev = src_prev;
  154         src->q_prev = dst;
  155         dst->q_next = src;
  156 }
  157 
  158 __attribute__((nonnull, always_inline)) static inline void
  159 gcq_tie_after(struct gcq *dst, struct gcq *src)
  160 {
  161         GCQ_ASSERT(dst != src && dst->q_prev != src);
  162         gcq_tie(dst, src);
  163 }
  164 
  165 __attribute__((nonnull, always_inline)) static inline void
  166 gcq_tie_before(struct gcq *dst, struct gcq *src)
  167 {
  168         gcq_tie_after(dst->q_prev, src);
  169 }
  170 
  171 __attribute__((nonnull)) static inline struct gcq *
  172 gcq_remove(struct gcq *q)
  173 {
  174         struct gcq *next, *prev;
  175         next = q->q_next;
  176         prev = q->q_prev;
  177 
  178         prev->q_next = next;
  179         next->q_prev = prev;
  180         gcq_init(q);
  181         return q;
  182 }
  183 
  184 #ifdef GCQ_UNCONDITIONAL_MERGE
  185 __attribute__((nonnull)) static inline void
  186 gcq_merge(struct gcq *dst, struct gcq *src)
  187 {
  188         GCQ_ASSERT(dst != src && dst->q_prev != src);
  189         gcq_tie(dst, src);
  190         gcq_tie(src, src);
  191 }
  192 
  193 __attribute__((nonnull, always_inline)) static inline void
  194 gcq_merge_head(struct gcq_head *dst, struct gcq_head *src)
  195 {
  196         gcq_merge(gcq_hq(dst), gcq_hq(src));
  197 }
  198 
  199 __attribute__((nonnull, always_inline)) static inline void
  200 gcq_merge_tail(struct gcq_head *dst, struct gcq_head *src)
  201 {
  202         gcq_merge(gcq_hq(dst)->q_prev, gcq_hq(src));
  203 }
  204 #else
  205 __attribute__((nonnull)) static inline void
  206 gcq_merge(struct gcq *dst, struct gcq *src)
  207 {
  208         struct gcq *dst_next, *src_prev, *src_next;
  209         GCQ_ASSERT(dst != src && dst->q_prev != src);
  210 
  211         if (gcq_onlist(src)) {
  212                 dst_next = dst->q_next;
  213                 src_prev = src->q_prev;
  214                 src_next = src->q_next;
  215 
  216                 dst_next->q_prev = src_prev;
  217                 src_prev->q_next = dst_next;
  218                 dst->q_next = src_next;
  219                 src_next->q_prev = dst;
  220                 gcq_init(src);
  221         }
  222 }
  223 
  224 __attribute__((nonnull, always_inline)) static inline void
  225 gcq_merge_head(struct gcq_head *dst, struct gcq_head *src)
  226 {
  227         gcq_merge(gcq_hq(dst), gcq_hq(src));
  228 }
  229 
  230 __attribute__((nonnull, always_inline)) static inline void
  231 gcq_merge_tail(struct gcq_head *dst, struct gcq_head *src)
  232 {
  233         gcq_merge(gcq_hq(dst)->q_prev, gcq_hq(src));
  234 }
  235 #endif
  236 
  237 __attribute__((nonnull)) static inline void
  238 gcq_clear(struct gcq *q)
  239 {
  240         struct gcq *nq, *next;
  241         nq=q;
  242         do {
  243                 next = nq->q_next;
  244                 gcq_init(nq);
  245                 nq = next;
  246         } while (next != q);
  247 }
  248 
  249 __attribute__((nonnull, always_inline)) static inline void
  250 gcq_remove_all(struct gcq_head *head)
  251 {
  252         gcq_clear(gcq_hq(head));
  253 }
  254 
  255 __attribute__((nonnull, always_inline)) static inline struct gcq *
  256 _gcq_next(struct gcq *current, struct gcq_head *head, struct gcq *start)
  257 {
  258         struct gcq *q, *hq;
  259         hq = gcq_hq(head);
  260         q = current->q_next;
  261         if (hq != start && q == hq)
  262                 q = hq->q_next;
  263         if (current != start)
  264                 GCQ_ASSERT(gcq_onlist(current));
  265         return q;
  266 }
  267 
  268 __attribute__((nonnull, always_inline)) static inline struct gcq *
  269 _gcq_prev(struct gcq *current, struct gcq_head *head, struct gcq *start)
  270 {
  271         struct gcq *q, *hq;
  272         hq = gcq_hq(head);
  273         q = current->q_prev;
  274         if (hq != start && q == hq)
  275                 q = hq->q_prev;
  276         if (current != start)
  277                 GCQ_ASSERT(gcq_onlist(current));
  278         return q;
  279 }
  280 
  281 
  282 #define GCQ_ITEM(q, type, name)                                         \
  283     ((type *)(void *)((uint8_t *)gcq_q(q) - offsetof(type, name)))
  284 
  285 
  286 #define _GCQ_GDQ(var, h, ptr, fn) (gcq_hq(h)->ptr != gcq_hq(h) ?        \
  287     (var = fn(gcq_hq(h)->ptr), true) : (var = NULL, false))
  288 #define _GCQ_GDQ_TYPED(tvar, h, type, name, ptr, fn)                    \
  289     (gcq_hq(h)->ptr != gcq_hq(h) ? (tvar = GCQ_ITEM(fn(gcq_hq(h)->ptr), \
  290     type, name), true) : (tvar = NULL, false))
  291 #define _GCQ_NP(var, current, head, start, np, fn)                      \
  292     (np(current, head, start) != (start) ?                              \
  293     (var = fn(np(current, head, start)), true) : (var = NULL, false))
  294 #define _GCQ_NP_TYPED(tvar, current, head, start, type, name, np, fn)   \
  295     (np(current, head, start) != (start) ?                              \
  296     (tvar = GCQ_ITEM(fn(np(current, head, start)), type, name), true) : \
  297     (tvar = NULL, false))
  298 
  299 #define _GCQ_GDQ_COND(var, h, ptr, rem, cond)                           \
  300     (gcq_hq(h)->ptr != gcq_hq(h) ? (var = gcq_hq(h)->ptr,               \
  301     ((cond) ? (rem, true) : (var = NULL, false))) :                     \
  302     (var = NULL, false))
  303 #define _GCQ_GDQ_COND_TYPED(tvar, h, type, name, ptr, rem, cond)        \
  304     (gcq_hq(h)->ptr != gcq_hq(h) ? (tvar = GCQ_ITEM(gcq_hq(h)->ptr,     \
  305     type, name), ((cond) ? (rem, true) : (tvar = NULL, false))) :       \
  306     (tvar = NULL, false))
  307 #define _GCQ_NP_COND(var, current, head, start, np, rem, cond)          \
  308     (np(current, head, start) != (start) ?                              \
  309     (var = fn(np(current, head, start)), ((cond) ? (rem), true) :       \
  310     (var = NULL, false))) : (var = NULL, false))
  311 #define _GCQ_NP_COND_TYPED(tvar, current, head, start, type, name, np,  \
  312     rem, cond) (np(current, head, start) != (start) ?                   \
  313     (tvar = GCQ_ITEM(fn(np(current, head, start)), type, name),         \
  314     ((cond) ? (rem, true) : (var = NULL, false))) :                     \
  315     (tvar = NULL, false))
  316 
  317 #define GCQ_GOT_FIRST(var, h) _GCQ_GDQ(var, h, q_next, gcq_q)
  318 #define GCQ_GOT_LAST(var, h) _GCQ_GDQ(var, h, q_prev, gcq_q)
  319 #define GCQ_DEQUEUED_FIRST(var, h) _GCQ_GDQ(var, h, q_next, gcq_remove)
  320 #define GCQ_DEQUEUED_LAST(var, h) _GCQ_GDQ(var, h, q_prev, gcq_remove)
  321 #define GCQ_GOT_FIRST_TYPED(tvar, h, type, name)                        \
  322     _GCQ_GDQ_TYPED(tvar, h, type, name, q_next, gcq_q)
  323 #define GCQ_GOT_LAST_TYPED(tvar, h, type, name)                         \
  324     _GCQ_GDQ_TYPED(tvar, h, type, name, q_prev, gcq_q)
  325 #define GCQ_DEQUEUED_FIRST_TYPED(tvar, h, type, name)                   \
  326     _GCQ_GDQ_TYPED(tvar, h, type, name, q_next, gcq_remove)
  327 #define GCQ_DEQUEUED_LAST_TYPED(tvar, h, type, name)                    \
  328     _GCQ_GDQ_TYPED(tvar, h, type, name, q_prev, gcq_remove)
  329 #define GCQ_GOT_NEXT(var, current, head, start)                         \
  330     _GCQ_NP(var, current, head, start, _gcq_next, gcq_q)
  331 #define GCQ_GOT_PREV(var, current, head, start)                         \
  332     _GCQ_NP(var, current, head, start, _gcq_prev, gcq_q)
  333 #define GCQ_DEQUEUED_NEXT(var, current, head, start)                    \
  334     _GCQ_NP(var, current, head, start, _gcq_next, gcq_remove)
  335 #define GCQ_DEQUEUED_PREV(var, current, head, start)                    \
  336     _GCQ_NP(var, current, head, start, _gcq_prev, gcq_remove)
  337 #define GCQ_GOT_NEXT_TYPED(tvar, current, head, start, type, name)      \
  338     _GCQ_NP_TYPED(tvar, current, head, start, type, name,               \
  339     _gcq_next, gcq_q)
  340 #define GCQ_GOT_PREV_TYPED(tvar, current, head, start, type, name)      \
  341     _GCQ_NP_TYPED(tvar, current, head, start, type, name,               \
  342     _gcq_prev, gcq_q)
  343 #define GCQ_DEQUEUED_NEXT_TYPED(tvar, current, head, start, type, name) \
  344     _GCQ_NP_TYPED(tvar, current, head, start, type, name,               \
  345     _gcq_next, gcq_remove)
  346 #define GCQ_DEQUEUED_PREV_TYPED(tvar, current, head, start, type, name) \
  347     _GCQ_NP_TYPED(tvar, current, head, start, type, name,               \
  348     _gcq_prev, gcq_remove)
  349 
  350 #define GCQ_GOT_FIRST_COND(var, h, cond)                                \
  351     _GCQ_GDQ_COND(var, h, q_next, ((void)0), cond)
  352 #define GCQ_GOT_LAST_COND(var, h, cond)                                 \
  353     _GCQ_GDQ_COND(var, h, q_prev, ((void)0), cond)
  354 #define GCQ_DEQUEUED_FIRST_COND(var, h, cond)                           \
  355     _GCQ_GDQ_COND(var, h, q_next, gcq_remove(var), cond)
  356 #define GCQ_DEQUEUED_LAST_COND(var, h, cond)                            \
  357     _GCQ_GDQ_COND(var, h, q_prev, gcq_remove(var), cond)
  358 #define GCQ_GOT_FIRST_COND_TYPED(tvar, h, type, name, cond)             \
  359     _GCQ_GDQ_COND_TYPED(tvar, h, type, name, q_next, ((void)0), cond)
  360 #define GCQ_GOT_LAST_COND_TYPED(tvar, h, type, name, cond)              \
  361     _GCQ_GDQ_COND_TYPED(tvar, h, type, name, q_prev, ((void)0), cond)
  362 #define GCQ_DEQUEUED_FIRST_COND_TYPED(tvar, h, type, name, cond)        \
  363     _GCQ_GDQ_COND_TYPED(tvar, h, type, name, q_next,                    \
  364     gcq_remove(&(tvar)->name), cond)
  365 #define GCQ_DEQUEUED_LAST_COND_TYPED(tvar, h, type, name, cond)         \
  366     _GCQ_GDQ_COND_TYPED(tvar, h, type, name, q_prev,                    \
  367     gcq_remove(&(tvar)->name), cond)
  368 #define GCQ_GOT_NEXT_COND(var, current, head, start, cond)              \
  369     _GCQ_NP_COND(var, current, head, start, _gcq_next, ((void)0), cond)
  370 #define GCQ_GOT_PREV_COND(var, current, head, start, cond)              \
  371     _GCQ_NP_COND(var, current, head, start, _gcq_prev, ((void)0), cond)
  372 #define GCQ_DEQUEUED_NEXT_COND(var, current, head, start, cond)         \
  373     _GCQ_NP_COND(var, current, head, start, _gcq_next, gcq_remove(var), \
  374     cond)
  375 #define GCQ_DEQUEUED_PREV_COND(var, current, head, start, cond)         \
  376     _GCQ_NP_COND(var, current, head, start, _gcq_prev, gcq_remove(var), \
  377     cond)
  378 #define GCQ_GOT_NEXT_COND_TYPED(tvar, current, head, start, type, name, \
  379     cond) _GCQ_NP_COND_TYPED(tvar, current, head, start, type, name,    \
  380     _gcq_next, ((void)0), cond)
  381 #define GCQ_GOT_PREV_COND_TYPED(tvar, current, head, start, type, name, \
  382     cond) _GCQ_NP_COND_TYPED(tvar, current, head, start, type, name,    \
  383     _gcq_prev, ((void)0), cond)
  384 #define GCQ_DEQUEUED_NEXT_COND_TYPED(tvar, current, head, start, type,  \
  385     name, cond) _GCQ_NP_COND_TYPED(tvar, current, head, start, type,    \
  386     name, _gcq_next, gcq_remove(&(tvar)->name), cond)
  387 #define GCQ_DEQUEUED_PREV_COND_TYPED(tvar, current, head, start, type,  \
  388     name, cond) _GCQ_NP_COND_TYPED(tvar, current, head, start, type,    \
  389     name, _gcq_prev, gcq_remove(&(tvar)->name), cond)
  390 
  391 
  392 #define _GCQ_FOREACH(var, h, tnull, item, ptr)                          \
  393     for ((var)=gcq_hq(h)->ptr; ((var) != gcq_hq(h) &&                   \
  394     (GCQ_ASSERT(gcq_onlist(var)), item, true)) ||                       \
  395     (tnull, false); (var)=(var)->ptr)
  396 #define _GCQ_FOREACH_NVAR(var, nvar, h, tnull, item, ptr, ol, rem, ro)  \
  397     for ((nvar)=gcq_hq(h)->ptr; (((var)=(nvar), (nvar) != gcq_hq(h)) && \
  398     (ol, (nvar)=(nvar)->ptr, rem, item, true)) || (tnull, false); ro)
  399 
  400 #define GCQ_FOREACH(var, h)                                             \
  401     _GCQ_FOREACH(var, h, ((void)0), ((void)0), q_next)
  402 #define GCQ_FOREACH_REV(var, h)                                         \
  403     _GCQ_FOREACH(var, h, ((void)0), ((void)0), q_prev)
  404 #define GCQ_FOREACH_NVAR(var, nvar, h)                                  \
  405     _GCQ_FOREACH_NVAR(var, nvar, h, ((void)0), ((void)0),               \
  406     q_next, GCQ_ASSERT(gcq_onlist(nvar)), ((void)0), ((void)0))
  407 #define GCQ_FOREACH_NVAR_REV(var, nvar, h)                              \
  408     _GCQ_FOREACH_NVAR(var, nvar, h, ((void)0), ((void)0),               \
  409     q_prev, GCQ_ASSERT(gcq_onlist(nvar)), ((void)0), ((void)0))
  410 #define GCQ_FOREACH_RO(var, nvar, h)                                    \
  411     _GCQ_FOREACH_NVAR(var, nvar, h, ((void)0), ((void)0),               \
  412     q_next, ((void)0), ((void)0), GCQ_ASSERT(gcq_linked(var, nvar)))
  413 #define GCQ_FOREACH_RO_REV(var, nvar, h)                                \
  414     _GCQ_FOREACH_NVAR(var, nvar, h, ((void)0), ((void)0),               \
  415     q_prev, ((void)0), ((void)0), GCQ_ASSERT(gcq_linked(nvar, var)))
  416 #define GCQ_FOREACH_DEQUEUED(var, nvar, h)                              \
  417     _GCQ_FOREACH_NVAR(var, nvar, h, ((void)0), ((void)0),               \
  418     q_next, GCQ_ASSERT(gcq_onlist(nvar)), gcq_remove(var), ((void)0)
  419 #define GCQ_FOREACH_DEQUEUED_REV(var, nvar, h)                          \
  420     _GCQ_FOREACH_NVAR(var, nvar, h, ((void)0), ((void)0),               \
  421     q_prev, GCQ_ASSERT(gcq_onlist(nvar)), gcq_remove(var), ((void)0)
  422 
  423 #define GCQ_FOREACH_TYPED(var, h, tvar, type, name)                     \
  424     _GCQ_FOREACH(var, h, (tvar)=NULL, (tvar)=GCQ_ITEM(var, type, name), \
  425     q_next)
  426 #define GCQ_FOREACH_TYPED_REV(var, h, tvar, type, name)                 \
  427     _GCQ_FOREACH(var, h, (tvar)=NULL, (tvar)=GCQ_ITEM(var, type, name), \
  428     q_prev)
  429 #define GCQ_FOREACH_NVAR_TYPED(var, nvar, h, tvar, type, name)          \
  430     _GCQ_FOREACH_NVAR(var, nvar, h, (tvar)=NULL,                        \
  431     (tvar)=GCQ_ITEM(var, type, name),                                   \
  432     q_next, GCQ_ASSERT(gcq_onlist(nvar)), ((void)0), ((void)0))
  433 #define GCQ_FOREACH_NVAR_REV_TYPED(var, nvar, h, tvar, type, name)      \
  434     _GCQ_FOREACH_NVAR(var, nvar, h, (tvar)=NULL,                        \
  435     (tvar)=GCQ_ITEM(var, type, name),                                   \
  436     q_prev, GCQ_ASSERT(gcq_onlist(nvar)), ((void)0), ((void)0))
  437 #define GCQ_FOREACH_RO_TYPED(var, nvar, h, tvar, type, name)            \
  438     _GCQ_FOREACH_NVAR(var, nvar, h, (tvar)=NULL,                        \
  439     (tvar)=GCQ_ITEM(var, type, name),                                   \
  440     q_next, ((void)0), ((void)0), GCQ_ASSERT(gcq_lined(var, nvar)))
  441 #define GCQ_FOREACH_RO_REV_TYPED(var, nvar, h, tvar, type, name)        \
  442     _GCQ_FOREACH_NVAR(var, nvar, h, (tvar)=NULL,                        \
  443     (tvar)=GCQ_ITEM(var, type, name),                                   \
  444     q_prev, ((void)0), ((void)0), GCQ_ASSERT(gcq_linked(nvar, var)))
  445 #define GCQ_FOREACH_DEQUEUED_TYPED(var, nvar, h, tvar, type, name)      \
  446     _GCQ_FOREACH_NVAR(var, nvar, h, (tvar)=NULL,                        \
  447     (tvar)=GCQ_ITEM(var, type, name),                                   \
  448     q_next, GCQ_ASSERT(gcq_onlist(nvar)), gcq_remove(var), ((void)0))
  449 #define GCQ_FOREACH_DEQUEUED_REV_TYPED(var, nvar, h, tvar, type, name)  \
  450     _GCQ_FOREACH_NVAR(var, nvar, h, (tvar)=NULL,                        \
  451     (tvar)=GCQ_ITEM(var, type, name),                                   \
  452     q_prev, GCQ_ASSERT(gcq_onlist(nvar)), gcq_remove(var), ((void)0))
  453 
  454 #define _GCQ_COND(fe, cond) do { fe { if (cond) break; } } while (0)
  455 
  456 #define GCQ_FIND(var, h, cond) _GCQ_COND(GCQ_FOREACH(var, h), cond)
  457 #define GCQ_FIND_REV(var, h, cond) _GCQ_COND(GCQ_FOREACH_REV(var, h), cond)
  458 #define GCQ_FIND_TYPED(var, h, tvar, type, name, cond)                  \
  459     _GCQ_COND(GCQ_FOREACH_TYPED(var, h, tvar, type, name), cond)
  460 #define GCQ_FIND_TYPED_REV(var, h, tvar, type, name, cond)              \
  461     _GCQ_COND(GCQ_FOREACH_REV_TYPED(var, h, tvar, type, name), cond)
  462 
  463 #endif /* _GCQ_H */

Cache object: d6f9f8bec883df612f86957e7f34ef27


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