queue.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1991, 1993
00003  *      The Regents of the University of California.  All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. All advertising materials mentioning features or use of this software
00014  *    must display the following acknowledgement:
00015  *      This product includes software developed by the University of
00016  *      California, Berkeley and its contributors.
00017  * 4. Neither the name of the University nor the names of its contributors
00018  *    may be used to endorse or promote products derived from this software
00019  *    without specific prior written permission.
00020  *
00021  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00022  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00023  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00024  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00025  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00026  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00027  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00028  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00029  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00030  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00031  * SUCH DAMAGE.
00032  *
00033  *      @(#)queue.h     8.5 (Berkeley) 8/20/94
00034  */
00035 
00036 #ifndef _SYS_QUEUE_H_
00037 #define _SYS_QUEUE_H_
00038 
00039 /*
00040  * This file defines five types of data structures: singly-linked lists,
00041  * lists, simple queues, tail queues, and circular queues.
00042  *
00043  * A singly-linked list is headed by a single forward pointer. The
00044  * elements are singly linked for minimum space and pointer manipulation
00045  * overhead at the expense of O(n) removal for arbitrary elements. New
00046  * elements can be added to the list after an existing element or at the
00047  * head of the list.  Elements being removed from the head of the list
00048  * should use the explicit macro for this purpose for optimum
00049  * efficiency. A singly-linked list may only be traversed in the forward
00050  * direction.  Singly-linked lists are ideal for applications with large
00051  * datasets and few or no removals or for implementing a LIFO queue.
00052  *
00053  * A list is headed by a single forward pointer (or an array of forward
00054  * pointers for a hash table header). The elements are doubly linked
00055  * so that an arbitrary element can be removed without a need to
00056  * traverse the list. New elements can be added to the list before
00057  * or after an existing element or at the head of the list. A list
00058  * may only be traversed in the forward direction.
00059  *
00060  * A simple queue is headed by a pair of pointers, one the head of the
00061  * list and the other to the tail of the list. The elements are singly
00062  * linked to save space, so only elements can only be removed from the
00063  * head of the list. New elements can be added to the list after
00064  * an existing element, at the head of the list, or at the end of the
00065  * list. A simple queue may only be traversed in the forward direction.
00066  *
00067  * A tail queue is headed by a pair of pointers, one to the head of the
00068  * list and the other to the tail of the list. The elements are doubly
00069  * linked so that an arbitrary element can be removed without a need to
00070  * traverse the list. New elements can be added to the list before or
00071  * after an existing element, at the head of the list, or at the end of
00072  * the list. A tail queue may be traversed in either direction.
00073  *
00074  * A circle queue is headed by a pair of pointers, one to the head of the
00075  * list and the other to the tail of the list. The elements are doubly
00076  * linked so that an arbitrary element can be removed without a need to
00077  * traverse the list. New elements can be added to the list before or after
00078  * an existing element, at the head of the list, or at the end of the list.
00079  * A circle queue may be traversed in either direction, but has a more
00080  * complex end of list detection.
00081  *
00082  * For details on the use of these macros, see the queue(3) manual page.
00083  */
00084 
00085 /*
00086  * List definitions.
00087  */
00088 #define LIST_HEAD(name, type)                                           \
00089 struct name {                                                           \
00090         struct type *lh_first;  /* first element */                     \
00091 }
00092 
00093 #define LIST_HEAD_INITIALIZER(head)                                     \
00094         { NULL }
00095 
00096 #define LIST_ENTRY(type)                                                \
00097 struct {                                                                \
00098         struct type *le_next;   /* next element */                      \
00099         struct type **le_prev;  /* address of previous next element */  \
00100 }
00101 
00102 /*
00103  * List functions.
00104  */
00105 #if defined(QUEUEDEBUG)
00106 #define QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field)                   \
00107         if ((head)->lh_first &&                                         \
00108             (head)->lh_first->field.le_prev != &(head)->lh_first)       \
00109                 panic("LIST_INSERT_HEAD %p %s:%d", (head), __FILE__, __LINE__);
00110 #define QUEUEDEBUG_LIST_OP(elm, field)                                  \
00111         if ((elm)->field.le_next &&                                     \
00112             (elm)->field.le_next->field.le_prev !=                      \
00113             &(elm)->field.le_next)                                      \
00114                 panic("LIST_* forw %p %s:%d", (elm), __FILE__, __LINE__);\
00115         if (*(elm)->field.le_prev != (elm))                             \
00116                 panic("LIST_* back %p %s:%d", (elm), __FILE__, __LINE__);
00117 #define QUEUEDEBUG_LIST_POSTREMOVE(elm, field)                          \
00118         (elm)->field.le_next = (void *)1L;                              \
00119         (elm)->field.le_prev = (void *)1L;
00120 #else
00121 #define QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field)
00122 #define QUEUEDEBUG_LIST_OP(elm, field)
00123 #define QUEUEDEBUG_LIST_POSTREMOVE(elm, field)
00124 #endif
00125 
00126 #define LIST_INIT(head) do {                                            \
00127         (head)->lh_first = NULL;                                        \
00128 } while (/*CONSTCOND*/0)
00129 
00130 #define LIST_INSERT_AFTER(listelm, elm, field) do {                     \
00131         QUEUEDEBUG_LIST_OP((listelm), field)                            \
00132         if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)  \
00133                 (listelm)->field.le_next->field.le_prev =               \
00134                     &(elm)->field.le_next;                              \
00135         (listelm)->field.le_next = (elm);                               \
00136         (elm)->field.le_prev = &(listelm)->field.le_next;               \
00137 } while (/*CONSTCOND*/0)
00138 
00139 #define LIST_INSERT_BEFORE(listelm, elm, field) do {                    \
00140         QUEUEDEBUG_LIST_OP((listelm), field)                            \
00141         (elm)->field.le_prev = (listelm)->field.le_prev;                \
00142         (elm)->field.le_next = (listelm);                               \
00143         *(listelm)->field.le_prev = (elm);                              \
00144         (listelm)->field.le_prev = &(elm)->field.le_next;               \
00145 } while (/*CONSTCOND*/0)
00146 
00147 #define LIST_INSERT_HEAD(head, elm, field) do {                         \
00148         QUEUEDEBUG_LIST_INSERT_HEAD((head), (elm), field)               \
00149         if (((elm)->field.le_next = (head)->lh_first) != NULL)          \
00150                 (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
00151         (head)->lh_first = (elm);                                       \
00152         (elm)->field.le_prev = &(head)->lh_first;                       \
00153 } while (/*CONSTCOND*/0)
00154 
00155 #define LIST_REMOVE(elm, field) do {                                    \
00156         QUEUEDEBUG_LIST_OP((elm), field)                                \
00157         if ((elm)->field.le_next != NULL)                               \
00158                 (elm)->field.le_next->field.le_prev =                   \
00159                     (elm)->field.le_prev;                               \
00160         *(elm)->field.le_prev = (elm)->field.le_next;                   \
00161         QUEUEDEBUG_LIST_POSTREMOVE((elm), field)                        \
00162 } while (/*CONSTCOND*/0)
00163 
00164 #define LIST_FOREACH(var, head, field)                                  \
00165         for ((var) = ((head)->lh_first);                                \
00166                 (var);                                                  \
00167                 (var) = ((var)->field.le_next))
00168 
00169 /*
00170  * List access methods.
00171  */
00172 #define LIST_EMPTY(head)                ((head)->lh_first == NULL)
00173 #define LIST_FIRST(head)                ((head)->lh_first)
00174 #define LIST_NEXT(elm, field)           ((elm)->field.le_next)
00175 
00176 /*
00177  * Singly-linked List definitions.
00178  */
00179 #define SLIST_HEAD(name, type)                                          \
00180 struct name {                                                           \
00181         struct type *slh_first; /* first element */                     \
00182 }
00183 
00184 #define SLIST_HEAD_INITIALIZER(head)                                    \
00185         { NULL }
00186  
00187 #define SLIST_ENTRY(type)                                               \
00188 struct {                                                                \
00189         struct type *sle_next;  /* next element */                      \
00190 }
00191  
00192 /*
00193  * Singly-linked List functions.
00194  */
00195 #define SLIST_EMPTY(head)       ((head)->slh_first == NULL)
00196 #define SLIST_FIRST(head)       ((head)->slh_first)
00197 #define SLIST_NEXT(elm, field)  ((elm)->field.sle_next)
00198 
00199 #define SLIST_FOREACH(var, head, field)                                 \
00200         for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
00201 
00202 #define SLIST_INIT(head) do {                                           \
00203         (head)->slh_first = NULL;                                       \
00204 } while (/*CONSTCOND*/0)
00205 
00206 #define SLIST_INSERT_AFTER(slistelm, elm, field) do {                   \
00207         (elm)->field.sle_next = (slistelm)->field.sle_next;             \
00208         (slistelm)->field.sle_next = (elm);                             \
00209 } while (/*CONSTCOND*/0)
00210 
00211 #define SLIST_INSERT_HEAD(head, elm, field) do {                        \
00212         (elm)->field.sle_next = (head)->slh_first;                      \
00213         (head)->slh_first = (elm);                                      \
00214 } while (/*CONSTCOND*/0)
00215 
00216 #define SLIST_NEXT(elm, field)  ((elm)->field.sle_next)
00217 
00218 #define SLIST_REMOVE_HEAD(head, field) do {                             \
00219         (head)->slh_first = (head)->slh_first->field.sle_next;          \
00220 } while (/*CONSTCOND*/0)
00221 
00222 #define SLIST_REMOVE(head, elm, type, field) do {                       \
00223         if ((head)->slh_first == (elm)) {                               \
00224                 SLIST_REMOVE_HEAD((head), field);                       \
00225         }                                                               \
00226         else {                                                          \
00227                 struct type *curelm = (head)->slh_first;                \
00228                 while(curelm->field.sle_next != (elm))                  \
00229                         curelm = curelm->field.sle_next;                \
00230                 curelm->field.sle_next =                                \
00231                     curelm->field.sle_next->field.sle_next;             \
00232         }                                                               \
00233 } while (/*CONSTCOND*/0)
00234 
00235 /*
00236  * Simple queue definitions.
00237  */
00238 #define SIMPLEQ_HEAD(name, type)                                        \
00239 struct name {                                                           \
00240         struct type *sqh_first; /* first element */                     \
00241         struct type **sqh_last; /* addr of last next element */         \
00242 }
00243 
00244 #define SIMPLEQ_HEAD_INITIALIZER(head)                                  \
00245         { NULL, &(head).sqh_first }
00246 
00247 #define SIMPLEQ_ENTRY(type)                                             \
00248 struct {                                                                \
00249         struct type *sqe_next;  /* next element */                      \
00250 }
00251 
00252 /*
00253  * Simple queue functions.
00254  */
00255 #define SIMPLEQ_INIT(head) do {                                         \
00256         (head)->sqh_first = NULL;                                       \
00257         (head)->sqh_last = &(head)->sqh_first;                          \
00258 } while (/*CONSTCOND*/0)
00259 
00260 #define SIMPLEQ_INSERT_HEAD(head, elm, field) do {                      \
00261         if (((elm)->field.sqe_next = (head)->sqh_first) == NULL)        \
00262                 (head)->sqh_last = &(elm)->field.sqe_next;              \
00263         (head)->sqh_first = (elm);                                      \
00264 } while (/*CONSTCOND*/0)
00265 
00266 #define SIMPLEQ_INSERT_TAIL(head, elm, field) do {                      \
00267         (elm)->field.sqe_next = NULL;                                   \
00268         *(head)->sqh_last = (elm);                                      \
00269         (head)->sqh_last = &(elm)->field.sqe_next;                      \
00270 } while (/*CONSTCOND*/0)
00271 
00272 #define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {            \
00273         if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
00274                 (head)->sqh_last = &(elm)->field.sqe_next;              \
00275         (listelm)->field.sqe_next = (elm);                              \
00276 } while (/*CONSTCOND*/0)
00277 
00278 #define SIMPLEQ_REMOVE_HEAD(head, elm, field) do {                      \
00279         if (((head)->sqh_first = (elm)->field.sqe_next) == NULL)        \
00280                 (head)->sqh_last = &(head)->sqh_first;                  \
00281 } while (/*CONSTCOND*/0)
00282 
00283 #define SIMPLEQ_FOREACH(var, head, field)                               \
00284         for ((var) = ((head)->sqh_first);                               \
00285                 (var);                                                  \
00286                 (var) = ((var)->field.sqe_next))
00287 
00288 /*
00289  * Simple queue access methods.
00290  */
00291 #define SIMPLEQ_EMPTY(head)             ((head)->sqh_first == NULL)
00292 #define SIMPLEQ_FIRST(head)             ((head)->sqh_first)
00293 #define SIMPLEQ_NEXT(elm, field)        ((elm)->field.sqe_next)
00294 
00295 /*
00296  * Tail queue definitions.
00297  */
00298 #define TAILQ_HEAD(name, type)                                          \
00299 struct name {                                                           \
00300         struct type *tqh_first; /* first element */                     \
00301         struct type **tqh_last; /* addr of last next element */         \
00302 }
00303 
00304 #define TAILQ_HEAD_INITIALIZER(head)                                    \
00305         { NULL, &(head).tqh_first }
00306 
00307 #define TAILQ_ENTRY(type)                                               \
00308 struct {                                                                \
00309         struct type *tqe_next;  /* next element */                      \
00310         struct type **tqe_prev; /* address of previous next element */  \
00311 }
00312 
00313 /*
00314  * Tail queue functions.
00315  */
00316 #if defined(QUEUEDEBUG)
00317 #define QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field)                  \
00318         if ((head)->tqh_first &&                                        \
00319             (head)->tqh_first->field.tqe_prev != &(head)->tqh_first)    \
00320                 panic("TAILQ_INSERT_HEAD %p %s:%d", (head), __FILE__, __LINE__);
00321 #define QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field)                  \
00322         if (*(head)->tqh_last != NULL)                                  \
00323                 panic("TAILQ_INSERT_TAIL %p %s:%d", (head), __FILE__, __LINE__);
00324 #define QUEUEDEBUG_TAILQ_OP(elm, field)                                 \
00325         if ((elm)->field.tqe_next &&                                    \
00326             (elm)->field.tqe_next->field.tqe_prev !=                    \
00327             &(elm)->field.tqe_next)                                     \
00328                 panic("TAILQ_* forw %p %s:%d", (elm), __FILE__, __LINE__);\
00329         if (*(elm)->field.tqe_prev != (elm))                            \
00330                 panic("TAILQ_* back %p %s:%d", (elm), __FILE__, __LINE__);
00331 #define QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field)                         \
00332         (elm)->field.tqe_next = (void *)1L;                             \
00333         (elm)->field.tqe_prev = (void *)1L;
00334 #else
00335 #define QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field)
00336 #define QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field)
00337 #define QUEUEDEBUG_TAILQ_OP(elm, field)
00338 #define QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field)
00339 #endif
00340 
00341 #define TAILQ_INIT(head) do {                                           \
00342         (head)->tqh_first = NULL;                                       \
00343         (head)->tqh_last = &(head)->tqh_first;                          \
00344 } while (/*CONSTCOND*/0)
00345 
00346 #define TAILQ_INSERT_HEAD(head, elm, field) do {                        \
00347         QUEUEDEBUG_TAILQ_INSERT_HEAD((head), (elm), field)              \
00348         if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)        \
00349                 (head)->tqh_first->field.tqe_prev =                     \
00350                     &(elm)->field.tqe_next;                             \
00351         else                                                            \
00352                 (head)->tqh_last = &(elm)->field.tqe_next;              \
00353                 (head)->tqh_first = (elm);                              \
00354         (elm)->field.tqe_prev = &(head)->tqh_first;                     \
00355 } while (/*CONSTCOND*/0)
00356 
00357 #define TAILQ_INSERT_TAIL(head, elm, field) do {                        \
00358         QUEUEDEBUG_TAILQ_INSERT_TAIL((head), (elm), field)              \
00359         (elm)->field.tqe_next = NULL;                                   \
00360         (elm)->field.tqe_prev = (head)->tqh_last;                       \
00361         *(head)->tqh_last = (elm);                                      \
00362         (head)->tqh_last = &(elm)->field.tqe_next;                      \
00363 } while (/*CONSTCOND*/0)
00364 
00365 #define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {              \
00366         QUEUEDEBUG_TAILQ_OP((listelm), field)                           \
00367         if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
00368                 (elm)->field.tqe_next->field.tqe_prev =                 \
00369                     &(elm)->field.tqe_next;                             \
00370         else                                                            \
00371                 (head)->tqh_last = &(elm)->field.tqe_next;              \
00372         (listelm)->field.tqe_next = (elm);                              \
00373         (elm)->field.tqe_prev = &(listelm)->field.tqe_next;             \
00374 } while (/*CONSTCOND*/0)
00375 
00376 #define TAILQ_INSERT_BEFORE(listelm, elm, field) do {                   \
00377         QUEUEDEBUG_TAILQ_OP((listelm), field)                           \
00378         (elm)->field.tqe_prev = (listelm)->field.tqe_prev;              \
00379         (elm)->field.tqe_next = (listelm);                              \
00380         *(listelm)->field.tqe_prev = (elm);                             \
00381         (listelm)->field.tqe_prev = &(elm)->field.tqe_next;             \
00382 } while (/*CONSTCOND*/0)
00383 
00384 #define TAILQ_REMOVE(head, elm, field) do {                             \
00385         QUEUEDEBUG_TAILQ_OP((elm), field)                               \
00386         if (((elm)->field.tqe_next) != NULL)                            \
00387                 (elm)->field.tqe_next->field.tqe_prev =                 \
00388                     (elm)->field.tqe_prev;                              \
00389         else                                                            \
00390                 (head)->tqh_last = (elm)->field.tqe_prev;               \
00391         *(elm)->field.tqe_prev = (elm)->field.tqe_next;                 \
00392         QUEUEDEBUG_TAILQ_POSTREMOVE((elm), field);                      \
00393 } while (/*CONSTCOND*/0)
00394 
00395 /*
00396  * Tail queue access methods.
00397  */
00398 #define TAILQ_EMPTY(head)               ((head)->tqh_first == NULL)
00399 #define TAILQ_FIRST(head)               ((head)->tqh_first)
00400 #define TAILQ_NEXT(elm, field)          ((elm)->field.tqe_next)
00401 
00402 #define TAILQ_LAST(head, headname) \
00403         (*(((struct headname *)((head)->tqh_last))->tqh_last))
00404 #define TAILQ_PREV(elm, headname, field) \
00405         (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
00406 
00407 #define TAILQ_FOREACH(var, head, field)                                 \
00408         for ((var) = ((head)->tqh_first);                               \
00409                 (var);                                                  \
00410                 (var) = ((var)->field.tqe_next))
00411 
00412 #define TAILQ_FOREACH_REVERSE(var, head, headname, field)               \
00413         for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last));    \
00414                 (var);                                                  \
00415                 (var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
00416 
00417 /*
00418  * Circular queue definitions.
00419  */
00420 #define CIRCLEQ_HEAD(name, type)                                        \
00421 struct name {                                                           \
00422         struct type *cqh_first;         /* first element */             \
00423         struct type *cqh_last;          /* last element */              \
00424 }
00425 
00426 #define CIRCLEQ_HEAD_INITIALIZER(head)                                  \
00427         { (void *)&head, (void *)&head }
00428 
00429 #define CIRCLEQ_ENTRY(type)                                             \
00430 struct {                                                                \
00431         struct type *cqe_next;          /* next element */              \
00432         struct type *cqe_prev;          /* previous element */          \
00433 }
00434 
00435 /*
00436  * Circular queue functions.
00437  */
00438 #define CIRCLEQ_INIT(head) do {                                         \
00439         (head)->cqh_first = (void *)(head);                             \
00440         (head)->cqh_last = (void *)(head);                              \
00441 } while (/*CONSTCOND*/0)
00442 
00443 #define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {            \
00444         (elm)->field.cqe_next = (listelm)->field.cqe_next;              \
00445         (elm)->field.cqe_prev = (listelm);                              \
00446         if ((listelm)->field.cqe_next == (void *)(head))                \
00447                 (head)->cqh_last = (elm);                               \
00448         else                                                            \
00449                 (listelm)->field.cqe_next->field.cqe_prev = (elm);      \
00450         (listelm)->field.cqe_next = (elm);                              \
00451 } while (/*CONSTCOND*/0)
00452 
00453 #define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {           \
00454         (elm)->field.cqe_next = (listelm);                              \
00455         (elm)->field.cqe_prev = (listelm)->field.cqe_prev;              \
00456         if ((listelm)->field.cqe_prev == (void *)(head))                \
00457                 (head)->cqh_first = (elm);                              \
00458         else                                                            \
00459                 (listelm)->field.cqe_prev->field.cqe_next = (elm);      \
00460         (listelm)->field.cqe_prev = (elm);                              \
00461 } while (/*CONSTCOND*/0)
00462 
00463 #define CIRCLEQ_INSERT_HEAD(head, elm, field) do {                      \
00464         (elm)->field.cqe_next = (head)->cqh_first;                      \
00465         (elm)->field.cqe_prev = (void *)(head);                         \
00466         if ((head)->cqh_last == (void *)(head))                         \
00467                 (head)->cqh_last = (elm);                               \
00468         else                                                            \
00469                 (head)->cqh_first->field.cqe_prev = (elm);              \
00470         (head)->cqh_first = (elm);                                      \
00471 } while (/*CONSTCOND*/0)
00472 
00473 #define CIRCLEQ_INSERT_TAIL(head, elm, field) do {                      \
00474         (elm)->field.cqe_next = (void *)(head);                         \
00475         (elm)->field.cqe_prev = (head)->cqh_last;                       \
00476         if ((head)->cqh_first == (void *)(head))                        \
00477                 (head)->cqh_first = (elm);                              \
00478         else                                                            \
00479                 (head)->cqh_last->field.cqe_next = (elm);               \
00480         (head)->cqh_last = (elm);                                       \
00481 } while (/*CONSTCOND*/0)
00482 
00483 #define CIRCLEQ_REMOVE(head, elm, field) do {                           \
00484         if ((elm)->field.cqe_next == (void *)(head))                    \
00485                 (head)->cqh_last = (elm)->field.cqe_prev;               \
00486         else                                                            \
00487                 (elm)->field.cqe_next->field.cqe_prev =                 \
00488                     (elm)->field.cqe_prev;                              \
00489         if ((elm)->field.cqe_prev == (void *)(head))                    \
00490                 (head)->cqh_first = (elm)->field.cqe_next;              \
00491         else                                                            \
00492                 (elm)->field.cqe_prev->field.cqe_next =                 \
00493                     (elm)->field.cqe_next;                              \
00494 } while (/*CONSTCOND*/0)
00495 
00496 #define CIRCLEQ_FOREACH(var, head, field)                               \
00497         for ((var) = ((head)->cqh_first);                               \
00498                 (var) != (void *)(head);                                \
00499                 (var) = ((var)->field.cqe_next))
00500 
00501 #define CIRCLEQ_FOREACH_REVERSE(var, head, field)                       \
00502         for ((var) = ((head)->cqh_last);                                \
00503                 (var) != (void *)(head);                                \
00504                 (var) = ((var)->field.cqe_prev))
00505 
00506 /*
00507  * Circular queue access methods.
00508  */
00509 #define CIRCLEQ_EMPTY(head)             ((head)->cqh_first == (void *)(head))
00510 #define CIRCLEQ_FIRST(head)             ((head)->cqh_first)
00511 #define CIRCLEQ_LAST(head)              ((head)->cqh_last)
00512 #define CIRCLEQ_NEXT(elm, field)        ((elm)->field.cqe_next)
00513 #define CIRCLEQ_PREV(elm, field)        ((elm)->field.cqe_prev)
00514 
00515 
00516 /*
00517  * LSE/OS Run queue definitions.
00518  * Copyright (c)2004 Arhur Kopatsy
00519  */
00520 #define RUNQ_HEAD(name, type)                                           \
00521 struct name {                                                           \
00522         struct type *rqh_ptr;           /* ptr element */               \
00523         int          flg;                                               \
00524 }
00525 
00526 #define RUNQ_HEAD_INITIALIZER(head)                                     \
00527         { NULL }
00528 
00529 #define RUNQ_ENTRY(type)                                                \
00530 struct {                                                                \
00531         struct type *rqe_next;          /* next element */              \
00532         struct type *rqe_prev;          /* previous element */          \
00533 }
00534 
00535 /*
00536  * Run queue functions.
00537  */
00538 #define RUNQ_INIT(head) do {                                            \
00539         (head)->rqh_ptr = NULL;                                         \
00540 } while (/*CONSTCOND*/0)
00541 
00542 #define RUNQ_INSERT_BEFORE(head, listelm, elm, field) do {              \
00543         (elm)->field.rqe_next = (listelm);                              \
00544         (elm)->field.rqe_prev = (listelm)->field.rqe_prev;              \
00545         (listelm)->field.rqe_prev->field.rqe_next = (elm);              \
00546         (listelm)->field.rqe_prev = (elm);                              \
00547 } while (/*CONSTCOND*/0)
00548 
00549 #define RUNQ_SET_PTR(head, elm, field) do {                             \
00550         (head)->rqh_ptr = (elm);                                        \
00551         (elm)->field.rqe_next = (elm);                                  \
00552         (elm)->field.rqe_prev = (elm);                                  \
00553 } while (/*CONSTCOND*/0)
00554 
00555 #define RUNQ_REMOVE(head, elm, field) do {                              \
00556         if ((elm)->field.rqe_next == (elm))                             \
00557                 (head)->rqh_ptr = NULL;                                 \
00558         else                                                            \
00559         {                                                               \
00560                 (elm)->field.rqe_next->field.rqe_prev =                 \
00561                     (elm)->field.rqe_prev;                              \
00562                 (elm)->field.rqe_prev->field.rqe_next =                 \
00563                     (elm)->field.rqe_next;                              \
00564         }                                                               \
00565 } while (/*CONSTCOND*/0)
00566 
00567 #define RUNQ_FOREACH(var, head, field)                                  \
00568         for ((head)->flg = 0, (var) = ((head)->rqh_ptr);                \
00569                 ((head)->flg == 0 || (var) != (head)->rqh_ptr) &&       \
00570                                                 (var) != NULL;          \
00571                 (var) = ((var)->field.rqe_next), (head)->flg = 1)
00572 
00573 /*
00574  * Circular queue access methods.
00575  */
00576 #define RUNQ_EMPTY(head)        ((head)->rqh_ptr == NULL)
00577 #define RUNQ_NEXT(elm, field)   ((elm)->field.rqe_next)
00578 #define RUNQ_PREV(elm, field)   ((elm)->field.rqe_prev)
00579 
00580 #endif  /* !_SYS_QUEUE_H_ */

Generated on Wed May 24 23:04:17 2006 for LSE/OS by  doxygen 1.4.6