1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/netwerk/sctp/src/user_queue.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,642 @@ 1.4 +/*- 1.5 + * Copyright (c) 1991, 1993 1.6 + * The Regents of the University of California. All rights reserved. 1.7 + * 1.8 + * Redistribution and use in source and binary forms, with or without 1.9 + * modification, are permitted provided that the following conditions 1.10 + * are met: 1.11 + * 1. Redistributions of source code must retain the above copyright 1.12 + * notice, this list of conditions and the following disclaimer. 1.13 + * 2. Redistributions in binary form must reproduce the above copyright 1.14 + * notice, this list of conditions and the following disclaimer in the 1.15 + * documentation and/or other materials provided with the distribution. 1.16 + * 4. Neither the name of the University nor the names of its contributors 1.17 + * may be used to endorse or promote products derived from this software 1.18 + * without specific prior written permission. 1.19 + * 1.20 + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1.21 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1.22 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1.23 + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 1.24 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1.25 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 1.26 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 1.27 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 1.28 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 1.29 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 1.30 + * SUCH DAMAGE. 1.31 + * 1.32 + */ 1.33 + 1.34 +#ifndef _USER_QUEUE_H_ 1.35 +#define _USER_QUEUE_H_ 1.36 + 1.37 +#if !defined (__Userspace_os_Windows) 1.38 +#include <sys/cdefs.h> 1.39 +#endif 1.40 +/* 1.41 + * This file defines four types of data structures: singly-linked lists, 1.42 + * singly-linked tail queues, lists and tail queues. 1.43 + * 1.44 + * A singly-linked list is headed by a single forward pointer. The elements 1.45 + * are singly linked for minimum space and pointer manipulation overhead at 1.46 + * the expense of O(n) removal for arbitrary elements. New elements can be 1.47 + * added to the list after an existing element or at the head of the list. 1.48 + * Elements being removed from the head of the list should use the explicit 1.49 + * macro for this purpose for optimum efficiency. A singly-linked list may 1.50 + * only be traversed in the forward direction. Singly-linked lists are ideal 1.51 + * for applications with large datasets and few or no removals or for 1.52 + * implementing a LIFO queue. 1.53 + * 1.54 + * A singly-linked tail queue is headed by a pair of pointers, one to the 1.55 + * head of the list and the other to the tail of the list. The elements are 1.56 + * singly linked for minimum space and pointer manipulation overhead at the 1.57 + * expense of O(n) removal for arbitrary elements. New elements can be added 1.58 + * to the list after an existing element, at the head of the list, or at the 1.59 + * end of the list. Elements being removed from the head of the tail queue 1.60 + * should use the explicit macro for this purpose for optimum efficiency. 1.61 + * A singly-linked tail queue may only be traversed in the forward direction. 1.62 + * Singly-linked tail queues are ideal for applications with large datasets 1.63 + * and few or no removals or for implementing a FIFO queue. 1.64 + * 1.65 + * A list is headed by a single forward pointer (or an array of forward 1.66 + * pointers for a hash table header). The elements are doubly linked 1.67 + * so that an arbitrary element can be removed without a need to 1.68 + * traverse the list. New elements can be added to the list before 1.69 + * or after an existing element or at the head of the list. A list 1.70 + * may only be traversed in the forward direction. 1.71 + * 1.72 + * A tail queue is headed by a pair of pointers, one to the head of the 1.73 + * list and the other to the tail of the list. The elements are doubly 1.74 + * linked so that an arbitrary element can be removed without a need to 1.75 + * traverse the list. New elements can be added to the list before or 1.76 + * after an existing element, at the head of the list, or at the end of 1.77 + * the list. A tail queue may be traversed in either direction. 1.78 + * 1.79 + * For details on the use of these macros, see the queue(3) manual page. 1.80 + * 1.81 + * 1.82 + * SLIST LIST STAILQ TAILQ 1.83 + * _HEAD + + + + 1.84 + * _HEAD_INITIALIZER + + + + 1.85 + * _ENTRY + + + + 1.86 + * _INIT + + + + 1.87 + * _EMPTY + + + + 1.88 + * _FIRST + + + + 1.89 + * _NEXT + + + + 1.90 + * _PREV - - - + 1.91 + * _LAST - - + + 1.92 + * _FOREACH + + + + 1.93 + * _FOREACH_SAFE + + + + 1.94 + * _FOREACH_REVERSE - - - + 1.95 + * _FOREACH_REVERSE_SAFE - - - + 1.96 + * _INSERT_HEAD + + + + 1.97 + * _INSERT_BEFORE - + - + 1.98 + * _INSERT_AFTER + + + + 1.99 + * _INSERT_TAIL - - + + 1.100 + * _CONCAT - - + + 1.101 + * _REMOVE_AFTER + - + - 1.102 + * _REMOVE_HEAD + - + - 1.103 + * _REMOVE + + + + 1.104 + * _SWAP + + + + 1.105 + * 1.106 + */ 1.107 +#ifdef QUEUE_MACRO_DEBUG 1.108 +/* Store the last 2 places the queue element or head was altered */ 1.109 +struct qm_trace { 1.110 + char * lastfile; 1.111 + int lastline; 1.112 + char * prevfile; 1.113 + int prevline; 1.114 +}; 1.115 + 1.116 +#define TRACEBUF struct qm_trace trace; 1.117 +#define TRASHIT(x) do {(x) = (void *)-1;} while (0) 1.118 +#define QMD_SAVELINK(name, link) void **name = (void *)&(link) 1.119 + 1.120 +#define QMD_TRACE_HEAD(head) do { \ 1.121 + (head)->trace.prevline = (head)->trace.lastline; \ 1.122 + (head)->trace.prevfile = (head)->trace.lastfile; \ 1.123 + (head)->trace.lastline = __LINE__; \ 1.124 + (head)->trace.lastfile = __FILE__; \ 1.125 +} while (0) 1.126 + 1.127 +#define QMD_TRACE_ELEM(elem) do { \ 1.128 + (elem)->trace.prevline = (elem)->trace.lastline; \ 1.129 + (elem)->trace.prevfile = (elem)->trace.lastfile; \ 1.130 + (elem)->trace.lastline = __LINE__; \ 1.131 + (elem)->trace.lastfile = __FILE__; \ 1.132 +} while (0) 1.133 + 1.134 +#else 1.135 +#define QMD_TRACE_ELEM(elem) 1.136 +#define QMD_TRACE_HEAD(head) 1.137 +#define QMD_SAVELINK(name, link) 1.138 +#define TRACEBUF 1.139 +#define TRASHIT(x) 1.140 +#endif /* QUEUE_MACRO_DEBUG */ 1.141 + 1.142 +/* 1.143 + * Singly-linked List declarations. 1.144 + */ 1.145 +#define SLIST_HEAD(name, type) \ 1.146 +struct name { \ 1.147 + struct type *slh_first; /* first element */ \ 1.148 +} 1.149 + 1.150 +#define SLIST_HEAD_INITIALIZER(head) \ 1.151 + { NULL } 1.152 + 1.153 +#if defined (__Userspace_os_Windows) 1.154 +#if defined (SLIST_ENTRY) 1.155 +#undef SLIST_ENTRY 1.156 +#endif 1.157 +#endif 1.158 + 1.159 +#define SLIST_ENTRY(type) \ 1.160 +struct { \ 1.161 + struct type *sle_next; /* next element */ \ 1.162 +} 1.163 + 1.164 +/* 1.165 + * Singly-linked List functions. 1.166 + */ 1.167 +#define SLIST_EMPTY(head) ((head)->slh_first == NULL) 1.168 + 1.169 +#define SLIST_FIRST(head) ((head)->slh_first) 1.170 + 1.171 +#define SLIST_FOREACH(var, head, field) \ 1.172 + for ((var) = SLIST_FIRST((head)); \ 1.173 + (var); \ 1.174 + (var) = SLIST_NEXT((var), field)) 1.175 + 1.176 +#define SLIST_FOREACH_SAFE(var, head, field, tvar) \ 1.177 + for ((var) = SLIST_FIRST((head)); \ 1.178 + (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ 1.179 + (var) = (tvar)) 1.180 + 1.181 +#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \ 1.182 + for ((varp) = &SLIST_FIRST((head)); \ 1.183 + ((var) = *(varp)) != NULL; \ 1.184 + (varp) = &SLIST_NEXT((var), field)) 1.185 + 1.186 +#define SLIST_INIT(head) do { \ 1.187 + SLIST_FIRST((head)) = NULL; \ 1.188 +} while (0) 1.189 + 1.190 +#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ 1.191 + SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \ 1.192 + SLIST_NEXT((slistelm), field) = (elm); \ 1.193 +} while (0) 1.194 + 1.195 +#define SLIST_INSERT_HEAD(head, elm, field) do { \ 1.196 + SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \ 1.197 + SLIST_FIRST((head)) = (elm); \ 1.198 +} while (0) 1.199 + 1.200 +#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) 1.201 + 1.202 +#define SLIST_REMOVE(head, elm, type, field) do { \ 1.203 + QMD_SAVELINK(oldnext, (elm)->field.sle_next); \ 1.204 + if (SLIST_FIRST((head)) == (elm)) { \ 1.205 + SLIST_REMOVE_HEAD((head), field); \ 1.206 + } \ 1.207 + else { \ 1.208 + struct type *curelm = SLIST_FIRST((head)); \ 1.209 + while (SLIST_NEXT(curelm, field) != (elm)) \ 1.210 + curelm = SLIST_NEXT(curelm, field); \ 1.211 + SLIST_REMOVE_AFTER(curelm, field); \ 1.212 + } \ 1.213 + TRASHIT(*oldnext); \ 1.214 +} while (0) 1.215 + 1.216 +#define SLIST_REMOVE_AFTER(elm, field) do { \ 1.217 + SLIST_NEXT(elm, field) = \ 1.218 + SLIST_NEXT(SLIST_NEXT(elm, field), field); \ 1.219 +} while (0) 1.220 + 1.221 +#define SLIST_REMOVE_HEAD(head, field) do { \ 1.222 + SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ 1.223 +} while (0) 1.224 + 1.225 +#define SLIST_SWAP(head1, head2, type) do { \ 1.226 + struct type *swap_first = SLIST_FIRST(head1); \ 1.227 + SLIST_FIRST(head1) = SLIST_FIRST(head2); \ 1.228 + SLIST_FIRST(head2) = swap_first; \ 1.229 +} while (0) 1.230 + 1.231 +/* 1.232 + * Singly-linked Tail queue declarations. 1.233 + */ 1.234 +#define STAILQ_HEAD(name, type) \ 1.235 +struct name { \ 1.236 + struct type *stqh_first;/* first element */ \ 1.237 + struct type **stqh_last;/* addr of last next element */ \ 1.238 +} 1.239 + 1.240 +#define STAILQ_HEAD_INITIALIZER(head) \ 1.241 + { NULL, &(head).stqh_first } 1.242 + 1.243 +#define STAILQ_ENTRY(type) \ 1.244 +struct { \ 1.245 + struct type *stqe_next; /* next element */ \ 1.246 +} 1.247 + 1.248 +/* 1.249 + * Singly-linked Tail queue functions. 1.250 + */ 1.251 +#define STAILQ_CONCAT(head1, head2) do { \ 1.252 + if (!STAILQ_EMPTY((head2))) { \ 1.253 + *(head1)->stqh_last = (head2)->stqh_first; \ 1.254 + (head1)->stqh_last = (head2)->stqh_last; \ 1.255 + STAILQ_INIT((head2)); \ 1.256 + } \ 1.257 +} while (0) 1.258 + 1.259 +#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) 1.260 + 1.261 +#define STAILQ_FIRST(head) ((head)->stqh_first) 1.262 + 1.263 +#define STAILQ_FOREACH(var, head, field) \ 1.264 + for((var) = STAILQ_FIRST((head)); \ 1.265 + (var); \ 1.266 + (var) = STAILQ_NEXT((var), field)) 1.267 + 1.268 + 1.269 +#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \ 1.270 + for ((var) = STAILQ_FIRST((head)); \ 1.271 + (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ 1.272 + (var) = (tvar)) 1.273 + 1.274 +#define STAILQ_INIT(head) do { \ 1.275 + STAILQ_FIRST((head)) = NULL; \ 1.276 + (head)->stqh_last = &STAILQ_FIRST((head)); \ 1.277 +} while (0) 1.278 + 1.279 +#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ 1.280 + if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\ 1.281 + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ 1.282 + STAILQ_NEXT((tqelm), field) = (elm); \ 1.283 +} while (0) 1.284 + 1.285 +#define STAILQ_INSERT_HEAD(head, elm, field) do { \ 1.286 + if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \ 1.287 + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ 1.288 + STAILQ_FIRST((head)) = (elm); \ 1.289 +} while (0) 1.290 + 1.291 +#define STAILQ_INSERT_TAIL(head, elm, field) do { \ 1.292 + STAILQ_NEXT((elm), field) = NULL; \ 1.293 + *(head)->stqh_last = (elm); \ 1.294 + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ 1.295 +} while (0) 1.296 + 1.297 +#define STAILQ_LAST(head, type, field) \ 1.298 + (STAILQ_EMPTY((head)) ? \ 1.299 + NULL : \ 1.300 + ((struct type *)(void *) \ 1.301 + ((char *)((head)->stqh_last) - __offsetof(struct type, field)))) 1.302 + 1.303 +#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) 1.304 + 1.305 +#define STAILQ_REMOVE(head, elm, type, field) do { \ 1.306 + QMD_SAVELINK(oldnext, (elm)->field.stqe_next); \ 1.307 + if (STAILQ_FIRST((head)) == (elm)) { \ 1.308 + STAILQ_REMOVE_HEAD((head), field); \ 1.309 + } \ 1.310 + else { \ 1.311 + struct type *curelm = STAILQ_FIRST((head)); \ 1.312 + while (STAILQ_NEXT(curelm, field) != (elm)) \ 1.313 + curelm = STAILQ_NEXT(curelm, field); \ 1.314 + STAILQ_REMOVE_AFTER(head, curelm, field); \ 1.315 + } \ 1.316 + TRASHIT(*oldnext); \ 1.317 +} while (0) 1.318 + 1.319 +#define STAILQ_REMOVE_AFTER(head, elm, field) do { \ 1.320 + if ((STAILQ_NEXT(elm, field) = \ 1.321 + STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \ 1.322 + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ 1.323 +} while (0) 1.324 + 1.325 +#define STAILQ_REMOVE_HEAD(head, field) do { \ 1.326 + if ((STAILQ_FIRST((head)) = \ 1.327 + STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \ 1.328 + (head)->stqh_last = &STAILQ_FIRST((head)); \ 1.329 +} while (0) 1.330 + 1.331 +#define STAILQ_SWAP(head1, head2, type) do { \ 1.332 + struct type *swap_first = STAILQ_FIRST(head1); \ 1.333 + struct type **swap_last = (head1)->stqh_last; \ 1.334 + STAILQ_FIRST(head1) = STAILQ_FIRST(head2); \ 1.335 + (head1)->stqh_last = (head2)->stqh_last; \ 1.336 + STAILQ_FIRST(head2) = swap_first; \ 1.337 + (head2)->stqh_last = swap_last; \ 1.338 + if (STAILQ_EMPTY(head1)) \ 1.339 + (head1)->stqh_last = &STAILQ_FIRST(head1); \ 1.340 + if (STAILQ_EMPTY(head2)) \ 1.341 + (head2)->stqh_last = &STAILQ_FIRST(head2); \ 1.342 +} while (0) 1.343 + 1.344 + 1.345 +/* 1.346 + * List declarations. 1.347 + */ 1.348 +#define LIST_HEAD(name, type) \ 1.349 +struct name { \ 1.350 + struct type *lh_first; /* first element */ \ 1.351 +} 1.352 + 1.353 +#define LIST_HEAD_INITIALIZER(head) \ 1.354 + { NULL } 1.355 + 1.356 +#define LIST_ENTRY(type) \ 1.357 +struct { \ 1.358 + struct type *le_next; /* next element */ \ 1.359 + struct type **le_prev; /* address of previous next element */ \ 1.360 +} 1.361 + 1.362 +/* 1.363 + * List functions. 1.364 + */ 1.365 + 1.366 +#if defined(INVARIANTS) 1.367 +#define QMD_LIST_CHECK_HEAD(head, field) do { \ 1.368 + if (LIST_FIRST((head)) != NULL && \ 1.369 + LIST_FIRST((head))->field.le_prev != \ 1.370 + &LIST_FIRST((head))) \ 1.371 + panic("Bad list head %p first->prev != head", (void *)(head)); \ 1.372 +} while (0) 1.373 + 1.374 +#define QMD_LIST_CHECK_NEXT(elm, field) do { \ 1.375 + if (LIST_NEXT((elm), field) != NULL && \ 1.376 + LIST_NEXT((elm), field)->field.le_prev != \ 1.377 + &((elm)->field.le_next)) \ 1.378 + panic("Bad link elm %p next->prev != elm", (void *)(elm)); \ 1.379 +} while (0) 1.380 + 1.381 +#define QMD_LIST_CHECK_PREV(elm, field) do { \ 1.382 + if (*(elm)->field.le_prev != (elm)) \ 1.383 + panic("Bad link elm %p prev->next != elm", (void *)(elm)); \ 1.384 +} while (0) 1.385 +#else 1.386 +#define QMD_LIST_CHECK_HEAD(head, field) 1.387 +#define QMD_LIST_CHECK_NEXT(elm, field) 1.388 +#define QMD_LIST_CHECK_PREV(elm, field) 1.389 +#endif /* (INVARIANTS) */ 1.390 + 1.391 +#define LIST_EMPTY(head) ((head)->lh_first == NULL) 1.392 + 1.393 +#define LIST_FIRST(head) ((head)->lh_first) 1.394 + 1.395 +#define LIST_FOREACH(var, head, field) \ 1.396 + for ((var) = LIST_FIRST((head)); \ 1.397 + (var); \ 1.398 + (var) = LIST_NEXT((var), field)) 1.399 + 1.400 +#define LIST_FOREACH_SAFE(var, head, field, tvar) \ 1.401 + for ((var) = LIST_FIRST((head)); \ 1.402 + (var) && ((tvar) = LIST_NEXT((var), field), 1); \ 1.403 + (var) = (tvar)) 1.404 + 1.405 +#define LIST_INIT(head) do { \ 1.406 + LIST_FIRST((head)) = NULL; \ 1.407 +} while (0) 1.408 + 1.409 +#define LIST_INSERT_AFTER(listelm, elm, field) do { \ 1.410 + QMD_LIST_CHECK_NEXT(listelm, field); \ 1.411 + if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\ 1.412 + LIST_NEXT((listelm), field)->field.le_prev = \ 1.413 + &LIST_NEXT((elm), field); \ 1.414 + LIST_NEXT((listelm), field) = (elm); \ 1.415 + (elm)->field.le_prev = &LIST_NEXT((listelm), field); \ 1.416 +} while (0) 1.417 + 1.418 +#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ 1.419 + QMD_LIST_CHECK_PREV(listelm, field); \ 1.420 + (elm)->field.le_prev = (listelm)->field.le_prev; \ 1.421 + LIST_NEXT((elm), field) = (listelm); \ 1.422 + *(listelm)->field.le_prev = (elm); \ 1.423 + (listelm)->field.le_prev = &LIST_NEXT((elm), field); \ 1.424 +} while (0) 1.425 + 1.426 +#define LIST_INSERT_HEAD(head, elm, field) do { \ 1.427 + QMD_LIST_CHECK_HEAD((head), field); \ 1.428 + if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ 1.429 + LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\ 1.430 + LIST_FIRST((head)) = (elm); \ 1.431 + (elm)->field.le_prev = &LIST_FIRST((head)); \ 1.432 +} while (0) 1.433 + 1.434 +#define LIST_NEXT(elm, field) ((elm)->field.le_next) 1.435 + 1.436 +#define LIST_REMOVE(elm, field) do { \ 1.437 + QMD_SAVELINK(oldnext, (elm)->field.le_next); \ 1.438 + QMD_SAVELINK(oldprev, (elm)->field.le_prev); \ 1.439 + QMD_LIST_CHECK_NEXT(elm, field); \ 1.440 + QMD_LIST_CHECK_PREV(elm, field); \ 1.441 + if (LIST_NEXT((elm), field) != NULL) \ 1.442 + LIST_NEXT((elm), field)->field.le_prev = \ 1.443 + (elm)->field.le_prev; \ 1.444 + *(elm)->field.le_prev = LIST_NEXT((elm), field); \ 1.445 + TRASHIT(*oldnext); \ 1.446 + TRASHIT(*oldprev); \ 1.447 +} while (0) 1.448 + 1.449 +#define LIST_SWAP(head1, head2, type, field) do { \ 1.450 + struct type *swap_tmp = LIST_FIRST((head1)); \ 1.451 + LIST_FIRST((head1)) = LIST_FIRST((head2)); \ 1.452 + LIST_FIRST((head2)) = swap_tmp; \ 1.453 + if ((swap_tmp = LIST_FIRST((head1))) != NULL) \ 1.454 + swap_tmp->field.le_prev = &LIST_FIRST((head1)); \ 1.455 + if ((swap_tmp = LIST_FIRST((head2))) != NULL) \ 1.456 + swap_tmp->field.le_prev = &LIST_FIRST((head2)); \ 1.457 +} while (0) 1.458 + 1.459 +/* 1.460 + * Tail queue declarations. 1.461 + */ 1.462 +#define TAILQ_HEAD(name, type) \ 1.463 +struct name { \ 1.464 + struct type *tqh_first; /* first element */ \ 1.465 + struct type **tqh_last; /* addr of last next element */ \ 1.466 + TRACEBUF \ 1.467 +} 1.468 + 1.469 +#define TAILQ_HEAD_INITIALIZER(head) \ 1.470 + { NULL, &(head).tqh_first } 1.471 + 1.472 +#define TAILQ_ENTRY(type) \ 1.473 +struct { \ 1.474 + struct type *tqe_next; /* next element */ \ 1.475 + struct type **tqe_prev; /* address of previous next element */ \ 1.476 + TRACEBUF \ 1.477 +} 1.478 + 1.479 +/* 1.480 + * Tail queue functions. 1.481 + */ 1.482 +#if defined(INVARIANTS) 1.483 +#define QMD_TAILQ_CHECK_HEAD(head, field) do { \ 1.484 + if (!TAILQ_EMPTY(head) && \ 1.485 + TAILQ_FIRST((head))->field.tqe_prev != \ 1.486 + &TAILQ_FIRST((head))) \ 1.487 + panic("Bad tailq head %p first->prev != head", (void *)(head)); \ 1.488 +} while (0) 1.489 + 1.490 +#define QMD_TAILQ_CHECK_TAIL(head, field) do { \ 1.491 + if (*(head)->tqh_last != NULL) \ 1.492 + panic("Bad tailq NEXT(%p->tqh_last) != NULL", (void *)(head)); \ 1.493 +} while (0) 1.494 + 1.495 +#define QMD_TAILQ_CHECK_NEXT(elm, field) do { \ 1.496 + if (TAILQ_NEXT((elm), field) != NULL && \ 1.497 + TAILQ_NEXT((elm), field)->field.tqe_prev != \ 1.498 + &((elm)->field.tqe_next)) \ 1.499 + panic("Bad link elm %p next->prev != elm", (void *)(elm)); \ 1.500 +} while (0) 1.501 + 1.502 +#define QMD_TAILQ_CHECK_PREV(elm, field) do { \ 1.503 + if (*(elm)->field.tqe_prev != (elm)) \ 1.504 + panic("Bad link elm %p prev->next != elm", (void *)(elm)); \ 1.505 +} while (0) 1.506 +#else 1.507 +#define QMD_TAILQ_CHECK_HEAD(head, field) 1.508 +#define QMD_TAILQ_CHECK_TAIL(head, headname) 1.509 +#define QMD_TAILQ_CHECK_NEXT(elm, field) 1.510 +#define QMD_TAILQ_CHECK_PREV(elm, field) 1.511 +#endif /* (INVARIANTS) */ 1.512 + 1.513 +#define TAILQ_CONCAT(head1, head2, field) do { \ 1.514 + if (!TAILQ_EMPTY(head2)) { \ 1.515 + *(head1)->tqh_last = (head2)->tqh_first; \ 1.516 + (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \ 1.517 + (head1)->tqh_last = (head2)->tqh_last; \ 1.518 + TAILQ_INIT((head2)); \ 1.519 + QMD_TRACE_HEAD(head1); \ 1.520 + QMD_TRACE_HEAD(head2); \ 1.521 + } \ 1.522 +} while (0) 1.523 + 1.524 +#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) 1.525 + 1.526 +#define TAILQ_FIRST(head) ((head)->tqh_first) 1.527 + 1.528 +#define TAILQ_FOREACH(var, head, field) \ 1.529 + for ((var) = TAILQ_FIRST((head)); \ 1.530 + (var); \ 1.531 + (var) = TAILQ_NEXT((var), field)) 1.532 + 1.533 +#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ 1.534 + for ((var) = TAILQ_FIRST((head)); \ 1.535 + (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ 1.536 + (var) = (tvar)) 1.537 + 1.538 +#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ 1.539 + for ((var) = TAILQ_LAST((head), headname); \ 1.540 + (var); \ 1.541 + (var) = TAILQ_PREV((var), headname, field)) 1.542 + 1.543 +#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \ 1.544 + for ((var) = TAILQ_LAST((head), headname); \ 1.545 + (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \ 1.546 + (var) = (tvar)) 1.547 + 1.548 +#define TAILQ_INIT(head) do { \ 1.549 + TAILQ_FIRST((head)) = NULL; \ 1.550 + (head)->tqh_last = &TAILQ_FIRST((head)); \ 1.551 + QMD_TRACE_HEAD(head); \ 1.552 +} while (0) 1.553 + 1.554 +#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ 1.555 + QMD_TAILQ_CHECK_NEXT(listelm, field); \ 1.556 + if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\ 1.557 + TAILQ_NEXT((elm), field)->field.tqe_prev = \ 1.558 + &TAILQ_NEXT((elm), field); \ 1.559 + else { \ 1.560 + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ 1.561 + QMD_TRACE_HEAD(head); \ 1.562 + } \ 1.563 + TAILQ_NEXT((listelm), field) = (elm); \ 1.564 + (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \ 1.565 + QMD_TRACE_ELEM(&(elm)->field); \ 1.566 + QMD_TRACE_ELEM(&listelm->field); \ 1.567 +} while (0) 1.568 + 1.569 +#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ 1.570 + QMD_TAILQ_CHECK_PREV(listelm, field); \ 1.571 + (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ 1.572 + TAILQ_NEXT((elm), field) = (listelm); \ 1.573 + *(listelm)->field.tqe_prev = (elm); \ 1.574 + (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \ 1.575 + QMD_TRACE_ELEM(&(elm)->field); \ 1.576 + QMD_TRACE_ELEM(&listelm->field); \ 1.577 +} while (0) 1.578 + 1.579 +#define TAILQ_INSERT_HEAD(head, elm, field) do { \ 1.580 + QMD_TAILQ_CHECK_HEAD(head, field); \ 1.581 + if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \ 1.582 + TAILQ_FIRST((head))->field.tqe_prev = \ 1.583 + &TAILQ_NEXT((elm), field); \ 1.584 + else \ 1.585 + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ 1.586 + TAILQ_FIRST((head)) = (elm); \ 1.587 + (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \ 1.588 + QMD_TRACE_HEAD(head); \ 1.589 + QMD_TRACE_ELEM(&(elm)->field); \ 1.590 +} while (0) 1.591 + 1.592 +#define TAILQ_INSERT_TAIL(head, elm, field) do { \ 1.593 + QMD_TAILQ_CHECK_TAIL(head, field); \ 1.594 + TAILQ_NEXT((elm), field) = NULL; \ 1.595 + (elm)->field.tqe_prev = (head)->tqh_last; \ 1.596 + *(head)->tqh_last = (elm); \ 1.597 + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ 1.598 + QMD_TRACE_HEAD(head); \ 1.599 + QMD_TRACE_ELEM(&(elm)->field); \ 1.600 +} while (0) 1.601 + 1.602 +#define TAILQ_LAST(head, headname) \ 1.603 + (*(((struct headname *)((head)->tqh_last))->tqh_last)) 1.604 + 1.605 +#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) 1.606 + 1.607 +#define TAILQ_PREV(elm, headname, field) \ 1.608 + (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) 1.609 + 1.610 +#define TAILQ_REMOVE(head, elm, field) do { \ 1.611 + QMD_SAVELINK(oldnext, (elm)->field.tqe_next); \ 1.612 + QMD_SAVELINK(oldprev, (elm)->field.tqe_prev); \ 1.613 + QMD_TAILQ_CHECK_NEXT(elm, field); \ 1.614 + QMD_TAILQ_CHECK_PREV(elm, field); \ 1.615 + if ((TAILQ_NEXT((elm), field)) != NULL) \ 1.616 + TAILQ_NEXT((elm), field)->field.tqe_prev = \ 1.617 + (elm)->field.tqe_prev; \ 1.618 + else { \ 1.619 + (head)->tqh_last = (elm)->field.tqe_prev; \ 1.620 + QMD_TRACE_HEAD(head); \ 1.621 + } \ 1.622 + *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ 1.623 + TRASHIT(*oldnext); \ 1.624 + TRASHIT(*oldprev); \ 1.625 + QMD_TRACE_ELEM(&(elm)->field); \ 1.626 +} while (0) 1.627 + 1.628 +#define TAILQ_SWAP(head1, head2, type, field) do { \ 1.629 + struct type *swap_first = (head1)->tqh_first; \ 1.630 + struct type **swap_last = (head1)->tqh_last; \ 1.631 + (head1)->tqh_first = (head2)->tqh_first; \ 1.632 + (head1)->tqh_last = (head2)->tqh_last; \ 1.633 + (head2)->tqh_first = swap_first; \ 1.634 + (head2)->tqh_last = swap_last; \ 1.635 + if ((swap_first = (head1)->tqh_first) != NULL) \ 1.636 + swap_first->field.tqe_prev = &(head1)->tqh_first; \ 1.637 + else \ 1.638 + (head1)->tqh_last = &(head1)->tqh_first; \ 1.639 + if ((swap_first = (head2)->tqh_first) != NULL) \ 1.640 + swap_first->field.tqe_prev = &(head2)->tqh_first; \ 1.641 + else \ 1.642 + (head2)->tqh_last = &(head2)->tqh_first; \ 1.643 +} while (0) 1.644 + 1.645 +#endif /* !_SYS_QUEUE_H_ */