]> Git Repo - qemu.git/blob - slirp/qtailq.h
vhost-net: revamp configure logic
[qemu.git] / slirp / qtailq.h
1 /*      $NetBSD: queue.h,v 1.52 2009/04/20 09:56:08 mschuett Exp $ */
2
3 /*
4  * slirp version: Copy from QEMU, removed all but tail queues.
5  */
6
7 /*
8  * Copyright (c) 1991, 1993
9  *      The Regents of the University of California.  All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  *      @(#)queue.h     8.5 (Berkeley) 8/20/94
36  */
37
38 #ifndef QTAILQ_H
39 #define QTAILQ_H
40
41 /*
42  * A tail queue is headed by a pair of pointers, one to the head of the
43  * list and the other to the tail of the list. The elements are doubly
44  * linked so that an arbitrary element can be removed without a need to
45  * traverse the list. New elements can be added to the list before or
46  * after an existing element, at the head of the list, or at the end of
47  * the list. A tail queue may be traversed in either direction.
48  */
49 typedef struct QTailQLink {
50     void *tql_next;
51     struct QTailQLink *tql_prev;
52 } QTailQLink;
53
54 /*
55  * Tail queue definitions.  The union acts as a poor man template, as if
56  * it were QTailQLink<type>.
57  */
58 #define QTAILQ_HEAD(name, type)                                         \
59     union name {                                                        \
60         struct type *tqh_first;       /* first element */               \
61         QTailQLink tqh_circ;          /* link for circular backwards list */ \
62     }
63
64 #define QTAILQ_HEAD_INITIALIZER(head)           \
65     { .tqh_circ = { NULL, &(head).tqh_circ } }
66
67 #define QTAILQ_ENTRY(type)                                              \
68     union {                                                             \
69         struct type *tqe_next;        /* next element */                \
70         QTailQLink tqe_circ;          /* link for circular backwards list */ \
71     }
72
73 #define QTAILQ_INIT(head) do {                                          \
74         (head)->tqh_first = NULL;                                       \
75         (head)->tqh_circ.tql_prev = &(head)->tqh_circ;                  \
76 } while (/*CONSTCOND*/0)
77
78 #define QTAILQ_INSERT_HEAD(head, elm, field) do {                       \
79         if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)        \
80             (head)->tqh_first->field.tqe_circ.tql_prev =                \
81                 &(elm)->field.tqe_circ;                                 \
82         else                                                            \
83             (head)->tqh_circ.tql_prev = &(elm)->field.tqe_circ;         \
84         (head)->tqh_first = (elm);                                      \
85         (elm)->field.tqe_circ.tql_prev = &(head)->tqh_circ;             \
86 } while (/*CONSTCOND*/0)
87
88 #define QTAILQ_INSERT_TAIL(head, elm, field) do {                       \
89         (elm)->field.tqe_next = NULL;                                   \
90         (elm)->field.tqe_circ.tql_prev = (head)->tqh_circ.tql_prev;     \
91         (head)->tqh_circ.tql_prev->tql_next = (elm);                    \
92         (head)->tqh_circ.tql_prev = &(elm)->field.tqe_circ;             \
93 } while (/*CONSTCOND*/0)
94
95 #define QTAILQ_INSERT_AFTER(head, listelm, elm, field) do {             \
96         if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
97             (elm)->field.tqe_next->field.tqe_circ.tql_prev =            \
98                 &(elm)->field.tqe_circ;                                 \
99         else                                                            \
100             (head)->tqh_circ.tql_prev = &(elm)->field.tqe_circ;         \
101         (listelm)->field.tqe_next = (elm);                              \
102         (elm)->field.tqe_circ.tql_prev = &(listelm)->field.tqe_circ;    \
103 } while (/*CONSTCOND*/0)
104
105 #define QTAILQ_INSERT_BEFORE(listelm, elm, field) do {                       \
106         (elm)->field.tqe_circ.tql_prev = (listelm)->field.tqe_circ.tql_prev; \
107         (elm)->field.tqe_next = (listelm);                                   \
108         (listelm)->field.tqe_circ.tql_prev->tql_next = (elm);                \
109         (listelm)->field.tqe_circ.tql_prev = &(elm)->field.tqe_circ;         \
110 } while (/*CONSTCOND*/0)
111
112 #define QTAILQ_REMOVE(head, elm, field) do {                            \
113         if (((elm)->field.tqe_next) != NULL)                            \
114             (elm)->field.tqe_next->field.tqe_circ.tql_prev =            \
115                 (elm)->field.tqe_circ.tql_prev;                         \
116         else                                                            \
117             (head)->tqh_circ.tql_prev = (elm)->field.tqe_circ.tql_prev; \
118         (elm)->field.tqe_circ.tql_prev->tql_next = (elm)->field.tqe_next; \
119         (elm)->field.tqe_circ.tql_prev = NULL;                          \
120 } while (/*CONSTCOND*/0)
121
122 #define QTAILQ_FOREACH(var, head, field)                                \
123         for ((var) = ((head)->tqh_first);                               \
124                 (var);                                                  \
125                 (var) = ((var)->field.tqe_next))
126
127 #define QTAILQ_FOREACH_SAFE(var, head, field, next_var)                 \
128         for ((var) = ((head)->tqh_first);                               \
129                 (var) && ((next_var) = ((var)->field.tqe_next), 1);     \
130                 (var) = (next_var))
131
132 #define QTAILQ_FOREACH_REVERSE(var, head, field)                        \
133         for ((var) = QTAILQ_LAST(head);                                 \
134                 (var);                                                  \
135                 (var) = QTAILQ_PREV(var, field))
136
137 #define QTAILQ_FOREACH_REVERSE_SAFE(var, head, field, prev_var)         \
138         for ((var) = QTAILQ_LAST(head);                                 \
139              (var) && ((prev_var) = QTAILQ_PREV(var, field));           \
140              (var) = (prev_var))
141
142 /*
143  * Tail queue access methods.
144  */
145 #define QTAILQ_EMPTY(head)               ((head)->tqh_first == NULL)
146 #define QTAILQ_FIRST(head)               ((head)->tqh_first)
147 #define QTAILQ_NEXT(elm, field)          ((elm)->field.tqe_next)
148 #define QTAILQ_IN_USE(elm, field)        ((elm)->field.tqe_circ.tql_prev != NULL)
149
150 #define QTAILQ_LINK_PREV(link)                                          \
151         ((link).tql_prev->tql_prev->tql_next)
152 #define QTAILQ_LAST(head)                                               \
153         ((typeof((head)->tqh_first)) QTAILQ_LINK_PREV((head)->tqh_circ))
154 #define QTAILQ_PREV(elm, field)                                         \
155         ((typeof((elm)->field.tqe_next)) QTAILQ_LINK_PREV((elm)->field.tqe_circ))
156
157 #define field_at_offset(base, offset, type)                                    \
158         ((type *) (((char *) (base)) + (offset)))
159
160 /*
161  * Raw access of elements of a tail queue head.  Offsets are all zero
162  * because it's a union.
163  */
164 #define QTAILQ_RAW_FIRST(head)                                                 \
165         field_at_offset(head, 0, void *)
166 #define QTAILQ_RAW_TQH_CIRC(head)                                              \
167         field_at_offset(head, 0, QTailQLink)
168
169 /*
170  * Raw access of elements of a tail entry
171  */
172 #define QTAILQ_RAW_NEXT(elm, entry)                                            \
173         field_at_offset(elm, entry, void *)
174 #define QTAILQ_RAW_TQE_CIRC(elm, entry)                                        \
175         field_at_offset(elm, entry, QTailQLink)
176 /*
177  * Tail queue traversal using pointer arithmetic.
178  */
179 #define QTAILQ_RAW_FOREACH(elm, head, entry)                                   \
180         for ((elm) = *QTAILQ_RAW_FIRST(head);                                  \
181              (elm);                                                            \
182              (elm) = *QTAILQ_RAW_NEXT(elm, entry))
183 /*
184  * Tail queue insertion using pointer arithmetic.
185  */
186 #define QTAILQ_RAW_INSERT_TAIL(head, elm, entry) do {                           \
187         *QTAILQ_RAW_NEXT(elm, entry) = NULL;                                    \
188         QTAILQ_RAW_TQE_CIRC(elm, entry)->tql_prev = QTAILQ_RAW_TQH_CIRC(head)->tql_prev; \
189         QTAILQ_RAW_TQH_CIRC(head)->tql_prev->tql_next = (elm);                  \
190         QTAILQ_RAW_TQH_CIRC(head)->tql_prev = QTAILQ_RAW_TQE_CIRC(elm, entry);  \
191 } while (/*CONSTCOND*/0)
192
193 #endif /* QTAILQ_H */
This page took 0.036895 seconds and 4 git commands to generate.