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