1 /* $NetBSD: queue.h,v 1.52 2009/04/20 09:56:08 mschuett Exp $ */
4 * slirp version: Copy from QEMU, removed all but tail queues.
8 * Copyright (c) 1991, 1993
9 * The Regents of the University of California. All rights reserved.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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
35 * @(#)queue.h 8.5 (Berkeley) 8/20/94
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.
49 typedef struct QTailQLink
{
51 struct QTailQLink
*tql_prev
;
55 * Tail queue definitions. The union acts as a poor man template, as if
56 * it were QTailQLink<type>.
58 #define QTAILQ_HEAD(name, type) \
60 struct type *tqh_first; /* first element */ \
61 QTailQLink tqh_circ; /* link for circular backwards list */ \
64 #define QTAILQ_HEAD_INITIALIZER(head) \
65 { .tqh_circ = { NULL, &(head).tqh_circ } }
67 #define QTAILQ_ENTRY(type) \
69 struct type *tqe_next; /* next element */ \
70 QTailQLink tqe_circ; /* link for circular backwards list */ \
73 #define QTAILQ_INIT(head) do { \
74 (head)->tqh_first = NULL; \
75 (head)->tqh_circ.tql_prev = &(head)->tqh_circ; \
76 } while (/*CONSTCOND*/0)
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; \
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)
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)
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; \
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)
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)
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; \
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)
122 #define QTAILQ_FOREACH(var, head, field) \
123 for ((var) = ((head)->tqh_first); \
125 (var) = ((var)->field.tqe_next))
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); \
132 #define QTAILQ_FOREACH_REVERSE(var, head, field) \
133 for ((var) = QTAILQ_LAST(head); \
135 (var) = QTAILQ_PREV(var, field))
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)); \
143 * Tail queue access methods.
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)
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))
157 #define field_at_offset(base, offset, type) \
158 ((type *) (((char *) (base)) + (offset)))
161 * Raw access of elements of a tail queue head. Offsets are all zero
162 * because it's a union.
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)
170 * Raw access of elements of a tail entry
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)
177 * Tail queue traversal using pointer arithmetic.
179 #define QTAILQ_RAW_FOREACH(elm, head, entry) \
180 for ((elm) = *QTAILQ_RAW_FIRST(head); \
182 (elm) = *QTAILQ_RAW_NEXT(elm, entry))
184 * Tail queue insertion using pointer arithmetic.
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)
193 #endif /* QTAILQ_H */