Main Page | Modules | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members | Related Pages

queue.h

Go to the documentation of this file.
00001 
00009 /*
00010  * Copyright (c) 1991, 1993
00011  *  The Regents of the University of California.  All rights reserved.
00012  *
00013  * Redistribution and use in source and binary forms, with or without
00014  * modification, are permitted provided that the following conditions
00015  * are met:
00016  * 1. Redistributions of source code must retain the above copyright
00017  *    notice, this list of conditions and the following disclaimer.
00018  * 2. Redistributions in binary form must reproduce the above copyright
00019  *    notice, this list of conditions and the following disclaimer in the
00020  *    documentation and/or other materials provided with the distribution.
00021  * 3. All advertising materials mentioning features or use of this software
00022  *    must display the following acknowledgement:
00023  *  This product includes software developed by the University of
00024  *  California, Berkeley and its contributors.
00025  * 4. Neither the name of the University nor the names of its contributors
00026  *    may be used to endorse or promote products derived from this software
00027  *    without specific prior written permission.
00028  *
00029  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00030  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00031  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00032  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00033  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00034  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00035  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00036  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00037  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00038  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00039  * SUCH DAMAGE.
00040  *
00041  *  @(#)queue.h 8.5 (Berkeley) 8/20/94
00042  */
00043 
00044 #ifndef _SYS_QUEUE_H_
00045 #define _SYS_QUEUE_H_
00046 
00047 /*
00048  * This file defines three types of data structures: lists, tail queues,
00049  * and circular queues.
00050  *
00051  * A list is headed by a single forward pointer (or an array of forward
00052  * pointers for a hash table header). The elements are doubly linked
00053  * so that an arbitrary element can be removed without a need to
00054  * traverse the list. New elements can be added to the list before
00055  * or after an existing element or at the head of the list. A list
00056  * may only be traversed in the forward direction.
00057  *
00058  * A simple queue is headed by a pair of pointers, one the head of the
00059  * list and the other to the tail of the list. The elements are singly
00060  * linked to save space, so only elements can only be removed from the
00061  * head of the list. New elements can be added to the list before or after
00062  * an existing element, at the head of the list, or at the end of the
00063  * list. A simple queue may only be traversed in the forward direection.
00064  *
00065  * A tail queue is headed by a pair of pointers, one to the head of the
00066  * list and the other to the tail of the list. The elements are doubly
00067  * linked so that an arbitrary element can be removed without a need to
00068  * traverse the list. New elements can be added to the list before or
00069  * after an existing element, at the head of the list, or at the end of
00070  * the list. A tail queue may only be traversed in the forward direction.
00071  *
00072  * A circle queue is headed by a pair of pointers, one to the head of the
00073  * list and the other to the tail of the list. The elements are doubly
00074  * linked so that an arbitrary element can be removed without a need to
00075  * traverse the list. New elements can be added to the list before or after
00076  * an existing element, at the head of the list, or at the end of the list.
00077  * A circle queue may be traversed in either direction, but has a more
00078  * complex end of list detection.
00079  *
00080  * For details on the use of these macros, see the queue(3) manual page.
00081  */
00082 
00083 /*
00084  * List definitions.
00085  */
00086 #define LIST_HEAD(name, type)                       \
00087 struct name {                               \
00088     struct type *lh_first;  /* first element */         \
00089 }
00090 
00091 #define LIST_HEAD_INITIALIZER(head)                 \
00092     { NULL }
00093 
00094 #define LIST_ENTRY(type)                        \
00095 struct {                                \
00096     struct type *le_next;   /* next element */          \
00097     struct type **le_prev;  /* address of previous next element */  \
00098 }
00099 
00100 #define LIST_ENTRY_INITIALIZER                      \
00101     { NULL, NULL }
00102 
00103 /*
00104  * List functions.
00105  */
00106 #define LIST_INIT(head) do {                        \
00107     (head)->lh_first = NULL;                    \
00108 } while (0)
00109 
00110 #define LIST_ENTRY_INIT(elm, field) do {                \
00111     (elm)->field.le_next = NULL;                    \
00112     (elm)->field.le_prev = NULL;                    \
00113 } while (0)
00114 
00115 #define LIST_INSERT_AFTER(listelm, elm, field) do {         \
00116     if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)  \
00117         (listelm)->field.le_next->field.le_prev =       \
00118             &(elm)->field.le_next;              \
00119     (listelm)->field.le_next = (elm);               \
00120     (elm)->field.le_prev = &(listelm)->field.le_next;       \
00121 } while (0)
00122 
00123 #define LIST_INSERT_BEFORE(listelm, elm, field) do {            \
00124     (elm)->field.le_prev = (listelm)->field.le_prev;        \
00125     (elm)->field.le_next = (listelm);               \
00126     *(listelm)->field.le_prev = (elm);              \
00127     (listelm)->field.le_prev = &(elm)->field.le_next;       \
00128 } while (0)
00129 
00130 #define LIST_INSERT_HEAD(head, elm, field) do {             \
00131     if (((elm)->field.le_next = (head)->lh_first) != NULL)      \
00132         (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
00133     (head)->lh_first = (elm);                   \
00134     (elm)->field.le_prev = &(head)->lh_first;           \
00135 } while (0)
00136 
00137 #define LIST_REMOVE(elm, field) do {                    \
00138     if ((elm)->field.le_next != NULL)               \
00139         (elm)->field.le_next->field.le_prev =           \
00140             (elm)->field.le_prev;               \
00141     *(elm)->field.le_prev = (elm)->field.le_next;           \
00142 } while (0)
00143 
00144 #define LIST_FIRST(head)                        \
00145     ((head)->lh_first)
00146 
00147 #define LIST_NEXT(elm, field)                       \
00148     ((elm)->field.le_next)
00149 
00150 /*
00151  * Simple queue definitions.
00152  */
00153 #define SIMPLEQ_HEAD(name, type)                    \
00154 struct name {                               \
00155     struct type *sqh_first; /* first element */         \
00156     struct type **sqh_last; /* addr of last next element */     \
00157 }
00158 
00159 #define SIMPLEQ_HEAD_INITIALIZER(head)                  \
00160     { NULL, &(head).sqh_first }
00161 
00162 #define SIMPLEQ_ENTRY(type)                     \
00163 struct {                                \
00164     struct type *sqe_next;  /* next element */          \
00165 }
00166 
00167 /*
00168  * Simple queue functions.
00169  */
00170 #define SIMPLEQ_INIT(head) do {                     \
00171     (head)->sqh_first = NULL;                   \
00172     (head)->sqh_last = &(head)->sqh_first;              \
00173 } while (0)
00174 
00175 #define SIMPLEQ_INSERT_HEAD(head, elm, field) do {          \
00176     if (((elm)->field.sqe_next = (head)->sqh_first) == NULL)    \
00177         (head)->sqh_last = &(elm)->field.sqe_next;      \
00178     (head)->sqh_first = (elm);                  \
00179 } while (0)
00180 
00181 #define SIMPLEQ_INSERT_TAIL(head, elm, field) do {          \
00182     (elm)->field.sqe_next = NULL;                   \
00183     *(head)->sqh_last = (elm);                  \
00184     (head)->sqh_last = &(elm)->field.sqe_next;          \
00185 } while (0)
00186 
00187 #define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {        \
00188     if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
00189         (head)->sqh_last = &(elm)->field.sqe_next;      \
00190     (listelm)->field.sqe_next = (elm);              \
00191 } while (0)
00192 
00193 #define SIMPLEQ_REMOVE_HEAD(head, elm, field) do {          \
00194     if (((head)->sqh_first = (elm)->field.sqe_next) == NULL)    \
00195         (head)->sqh_last = &(head)->sqh_first;          \
00196 } while (0)
00197 
00198 /*
00199  * Tail queue definitions.
00200  */
00201 #define TAILQ_HEAD(name, type)                      \
00202 struct name {                               \
00203     struct type *tqh_first; /* first element */         \
00204     struct type **tqh_last; /* addr of last next element */     \
00205 }
00206 
00207 #define TAILQ_HEAD_INITIALIZER(head)                    \
00208     { NULL, &(head).tqh_first }
00209 
00210 #define TAILQ_ENTRY(type)                       \
00211 struct {                                \
00212     struct type *tqe_next;  /* next element */          \
00213     struct type **tqe_prev; /* address of previous next element */  \
00214 }
00215 
00216 /*
00217  * Tail queue functions.
00218  */
00219 #define TAILQ_INIT(head) do {                       \
00220     (head)->tqh_first = NULL;                   \
00221     (head)->tqh_last = &(head)->tqh_first;              \
00222 } while (0)
00223 
00224 #define TAILQ_INSERT_HEAD(head, elm, field) do {            \
00225     if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)    \
00226         (head)->tqh_first->field.tqe_prev =         \
00227             &(elm)->field.tqe_next;             \
00228     else                                \
00229         (head)->tqh_last = &(elm)->field.tqe_next;      \
00230     (head)->tqh_first = (elm);                  \
00231     (elm)->field.tqe_prev = &(head)->tqh_first;         \
00232 } while (0)
00233 
00234 #define TAILQ_INSERT_TAIL(head, elm, field) do {            \
00235     (elm)->field.tqe_next = NULL;                   \
00236     (elm)->field.tqe_prev = (head)->tqh_last;           \
00237     *(head)->tqh_last = (elm);                  \
00238     (head)->tqh_last = &(elm)->field.tqe_next;          \
00239 } while (0)
00240 
00241 #define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {      \
00242     if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
00243         (elm)->field.tqe_next->field.tqe_prev =         \
00244             &(elm)->field.tqe_next;             \
00245     else                                \
00246         (head)->tqh_last = &(elm)->field.tqe_next;      \
00247     (listelm)->field.tqe_next = (elm);              \
00248     (elm)->field.tqe_prev = &(listelm)->field.tqe_next;     \
00249 } while (0)
00250 
00251 #define TAILQ_INSERT_BEFORE(listelm, elm, field) do {           \
00252     (elm)->field.tqe_prev = (listelm)->field.tqe_prev;      \
00253     (elm)->field.tqe_next = (listelm);              \
00254     *(listelm)->field.tqe_prev = (elm);             \
00255     (listelm)->field.tqe_prev = &(elm)->field.tqe_next;     \
00256 } while (0)
00257 
00258 #define TAILQ_REMOVE(head, elm, field) do {             \
00259     if (((elm)->field.tqe_next) != NULL)                \
00260         (elm)->field.tqe_next->field.tqe_prev =         \
00261             (elm)->field.tqe_prev;              \
00262     else                                \
00263         (head)->tqh_last = (elm)->field.tqe_prev;       \
00264     *(elm)->field.tqe_prev = (elm)->field.tqe_next;         \
00265 } while (0)
00266 
00267 /*
00268  * Circular queue definitions.
00269  */
00270 #define CIRCLEQ_HEAD(name, type)                    \
00271 struct name {                               \
00272     struct type *cqh_first;     /* first element */     \
00273     struct type *cqh_last;      /* last element */      \
00274 }
00275 
00276 #define CIRCLEQ_HEAD_INITIALIZER(head)                  \
00277     { (void *)&head, (void *)&head }
00278 
00279 #define CIRCLEQ_ENTRY(type)                     \
00280 struct {                                \
00281     struct type *cqe_next;      /* next element */      \
00282     struct type *cqe_prev;      /* previous element */      \
00283 }
00284 
00285 /*
00286  * Circular queue functions.
00287  */
00288 #define CIRCLEQ_INIT(head) do {                     \
00289     (head)->cqh_first = (void *)(head);             \
00290     (head)->cqh_last = (void *)(head);              \
00291 } while (0)
00292 
00293 #define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {        \
00294     (elm)->field.cqe_next = (listelm)->field.cqe_next;      \
00295     (elm)->field.cqe_prev = (listelm);              \
00296     if ((listelm)->field.cqe_next == (void *)(head))        \
00297         (head)->cqh_last = (elm);               \
00298     else                                \
00299         (listelm)->field.cqe_next->field.cqe_prev = (elm);  \
00300     (listelm)->field.cqe_next = (elm);              \
00301 } while (0)
00302 
00303 #define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {       \
00304     (elm)->field.cqe_next = (listelm);              \
00305     (elm)->field.cqe_prev = (listelm)->field.cqe_prev;      \
00306     if ((listelm)->field.cqe_prev == (void *)(head))        \
00307         (head)->cqh_first = (elm);              \
00308     else                                \
00309         (listelm)->field.cqe_prev->field.cqe_next = (elm);  \
00310     (listelm)->field.cqe_prev = (elm);              \
00311 } while (0)
00312 
00313 #define CIRCLEQ_INSERT_HEAD(head, elm, field) do {          \
00314     (elm)->field.cqe_next = (head)->cqh_first;          \
00315     (elm)->field.cqe_prev = (void *)(head);             \
00316     if ((head)->cqh_last == (void *)(head))             \
00317         (head)->cqh_last = (elm);               \
00318     else                                \
00319         (head)->cqh_first->field.cqe_prev = (elm);      \
00320     (head)->cqh_first = (elm);                  \
00321 } while (0)
00322 
00323 #define CIRCLEQ_INSERT_TAIL(head, elm, field) do {          \
00324     (elm)->field.cqe_next = (void *)(head);             \
00325     (elm)->field.cqe_prev = (head)->cqh_last;           \
00326     if ((head)->cqh_first == (void *)(head))            \
00327         (head)->cqh_first = (elm);              \
00328     else                                \
00329         (head)->cqh_last->field.cqe_next = (elm);       \
00330     (head)->cqh_last = (elm);                   \
00331 } while (0)
00332 
00333 #define CIRCLEQ_REMOVE(head, elm, field) do {               \
00334     if ((elm)->field.cqe_next == (void *)(head))            \
00335         (head)->cqh_last = (elm)->field.cqe_prev;       \
00336     else                                \
00337         (elm)->field.cqe_next->field.cqe_prev =         \
00338             (elm)->field.cqe_prev;              \
00339     if ((elm)->field.cqe_prev == (void *)(head))            \
00340         (head)->cqh_first = (elm)->field.cqe_next;      \
00341     else                                \
00342         (elm)->field.cqe_prev->field.cqe_next =         \
00343             (elm)->field.cqe_next;              \
00344 } while (0)
00345 #endif  /* !_SYS_QUEUE_H_ */

Generated at Sat Oct 25 20:56:09 2003 for Services using Doxygen.
Services Copyr. 1996-2001 Chip Norkus, Max Byrd, Greg Poma, Michael Graff, James Hess, Dafydd James. All rights reserved See LICENSE for licensing information.