1*d0b3c59bSPatrick Mooney /*- 2*d0b3c59bSPatrick Mooney * Copyright (c) 1991, 1993 3*d0b3c59bSPatrick Mooney * The Regents of the University of California. All rights reserved. 4*d0b3c59bSPatrick Mooney * 5*d0b3c59bSPatrick Mooney * Redistribution and use in source and binary forms, with or without 6*d0b3c59bSPatrick Mooney * modification, are permitted provided that the following conditions 7*d0b3c59bSPatrick Mooney * are met: 8*d0b3c59bSPatrick Mooney * 1. Redistributions of source code must retain the above copyright 9*d0b3c59bSPatrick Mooney * notice, this list of conditions and the following disclaimer. 10*d0b3c59bSPatrick Mooney * 2. Redistributions in binary form must reproduce the above copyright 11*d0b3c59bSPatrick Mooney * notice, this list of conditions and the following disclaimer in the 12*d0b3c59bSPatrick Mooney * documentation and/or other materials provided with the distribution. 13*d0b3c59bSPatrick Mooney * 4. Neither the name of the University nor the names of its contributors 14*d0b3c59bSPatrick Mooney * may be used to endorse or promote products derived from this software 15*d0b3c59bSPatrick Mooney * without specific prior written permission. 16*d0b3c59bSPatrick Mooney * 17*d0b3c59bSPatrick Mooney * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18*d0b3c59bSPatrick Mooney * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19*d0b3c59bSPatrick Mooney * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20*d0b3c59bSPatrick Mooney * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21*d0b3c59bSPatrick Mooney * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22*d0b3c59bSPatrick Mooney * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23*d0b3c59bSPatrick Mooney * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24*d0b3c59bSPatrick Mooney * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25*d0b3c59bSPatrick Mooney * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26*d0b3c59bSPatrick Mooney * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27*d0b3c59bSPatrick Mooney * SUCH DAMAGE. 28*d0b3c59bSPatrick Mooney * 29*d0b3c59bSPatrick Mooney * @(#)queue.h 8.5 (Berkeley) 8/20/94 30*d0b3c59bSPatrick Mooney * $FreeBSD$ 31*d0b3c59bSPatrick Mooney */ 32*d0b3c59bSPatrick Mooney 33*d0b3c59bSPatrick Mooney #ifndef _SYS_QUEUE_H_ 34*d0b3c59bSPatrick Mooney #define _SYS_QUEUE_H_ 35*d0b3c59bSPatrick Mooney 36*d0b3c59bSPatrick Mooney #include <sys/cdefs.h> 37*d0b3c59bSPatrick Mooney 38*d0b3c59bSPatrick Mooney /* 39*d0b3c59bSPatrick Mooney * This file defines four types of data structures: singly-linked lists, 40*d0b3c59bSPatrick Mooney * singly-linked tail queues, lists and tail queues. 41*d0b3c59bSPatrick Mooney * 42*d0b3c59bSPatrick Mooney * A singly-linked list is headed by a single forward pointer. The elements 43*d0b3c59bSPatrick Mooney * are singly linked for minimum space and pointer manipulation overhead at 44*d0b3c59bSPatrick Mooney * the expense of O(n) removal for arbitrary elements. New elements can be 45*d0b3c59bSPatrick Mooney * added to the list after an existing element or at the head of the list. 46*d0b3c59bSPatrick Mooney * Elements being removed from the head of the list should use the explicit 47*d0b3c59bSPatrick Mooney * macro for this purpose for optimum efficiency. A singly-linked list may 48*d0b3c59bSPatrick Mooney * only be traversed in the forward direction. Singly-linked lists are ideal 49*d0b3c59bSPatrick Mooney * for applications with large datasets and few or no removals or for 50*d0b3c59bSPatrick Mooney * implementing a LIFO queue. 51*d0b3c59bSPatrick Mooney * 52*d0b3c59bSPatrick Mooney * A singly-linked tail queue is headed by a pair of pointers, one to the 53*d0b3c59bSPatrick Mooney * head of the list and the other to the tail of the list. The elements are 54*d0b3c59bSPatrick Mooney * singly linked for minimum space and pointer manipulation overhead at the 55*d0b3c59bSPatrick Mooney * expense of O(n) removal for arbitrary elements. New elements can be added 56*d0b3c59bSPatrick Mooney * to the list after an existing element, at the head of the list, or at the 57*d0b3c59bSPatrick Mooney * end of the list. Elements being removed from the head of the tail queue 58*d0b3c59bSPatrick Mooney * should use the explicit macro for this purpose for optimum efficiency. 59*d0b3c59bSPatrick Mooney * A singly-linked tail queue may only be traversed in the forward direction. 60*d0b3c59bSPatrick Mooney * Singly-linked tail queues are ideal for applications with large datasets 61*d0b3c59bSPatrick Mooney * and few or no removals or for implementing a FIFO queue. 62*d0b3c59bSPatrick Mooney * 63*d0b3c59bSPatrick Mooney * A list is headed by a single forward pointer (or an array of forward 64*d0b3c59bSPatrick Mooney * pointers for a hash table header). The elements are doubly linked 65*d0b3c59bSPatrick Mooney * so that an arbitrary element can be removed without a need to 66*d0b3c59bSPatrick Mooney * traverse the list. New elements can be added to the list before 67*d0b3c59bSPatrick Mooney * or after an existing element or at the head of the list. A list 68*d0b3c59bSPatrick Mooney * may be traversed in either direction. 69*d0b3c59bSPatrick Mooney * 70*d0b3c59bSPatrick Mooney * A tail queue is headed by a pair of pointers, one to the head of the 71*d0b3c59bSPatrick Mooney * list and the other to the tail of the list. The elements are doubly 72*d0b3c59bSPatrick Mooney * linked so that an arbitrary element can be removed without a need to 73*d0b3c59bSPatrick Mooney * traverse the list. New elements can be added to the list before or 74*d0b3c59bSPatrick Mooney * after an existing element, at the head of the list, or at the end of 75*d0b3c59bSPatrick Mooney * the list. A tail queue may be traversed in either direction. 76*d0b3c59bSPatrick Mooney * 77*d0b3c59bSPatrick Mooney * For details on the use of these macros, see the queue(3) manual page. 78*d0b3c59bSPatrick Mooney * 79*d0b3c59bSPatrick Mooney * Below is a summary of implemented functions where: 80*d0b3c59bSPatrick Mooney * + means the macro is available 81*d0b3c59bSPatrick Mooney * - means the macro is not available 82*d0b3c59bSPatrick Mooney * s means the macro is available but is slow (runs in O(n) time) 83*d0b3c59bSPatrick Mooney * 84*d0b3c59bSPatrick Mooney * SLIST LIST STAILQ TAILQ 85*d0b3c59bSPatrick Mooney * _HEAD + + + + 86*d0b3c59bSPatrick Mooney * _CLASS_HEAD + + + + 87*d0b3c59bSPatrick Mooney * _HEAD_INITIALIZER + + + + 88*d0b3c59bSPatrick Mooney * _ENTRY + + + + 89*d0b3c59bSPatrick Mooney * _CLASS_ENTRY + + + + 90*d0b3c59bSPatrick Mooney * _INIT + + + + 91*d0b3c59bSPatrick Mooney * _EMPTY + + + + 92*d0b3c59bSPatrick Mooney * _FIRST + + + + 93*d0b3c59bSPatrick Mooney * _NEXT + + + + 94*d0b3c59bSPatrick Mooney * _PREV - + - + 95*d0b3c59bSPatrick Mooney * _LAST - - + + 96*d0b3c59bSPatrick Mooney * _FOREACH + + + + 97*d0b3c59bSPatrick Mooney * _FOREACH_FROM + + + + 98*d0b3c59bSPatrick Mooney * _FOREACH_SAFE + + + + 99*d0b3c59bSPatrick Mooney * _FOREACH_FROM_SAFE + + + + 100*d0b3c59bSPatrick Mooney * _FOREACH_REVERSE - - - + 101*d0b3c59bSPatrick Mooney * _FOREACH_REVERSE_FROM - - - + 102*d0b3c59bSPatrick Mooney * _FOREACH_REVERSE_SAFE - - - + 103*d0b3c59bSPatrick Mooney * _FOREACH_REVERSE_FROM_SAFE - - - + 104*d0b3c59bSPatrick Mooney * _INSERT_HEAD + + + + 105*d0b3c59bSPatrick Mooney * _INSERT_BEFORE - + - + 106*d0b3c59bSPatrick Mooney * _INSERT_AFTER + + + + 107*d0b3c59bSPatrick Mooney * _INSERT_TAIL - - + + 108*d0b3c59bSPatrick Mooney * _CONCAT s s + + 109*d0b3c59bSPatrick Mooney * _REMOVE_AFTER + - + - 110*d0b3c59bSPatrick Mooney * _REMOVE_HEAD + - + - 111*d0b3c59bSPatrick Mooney * _REMOVE s + s + 112*d0b3c59bSPatrick Mooney * _SWAP + + + + 113*d0b3c59bSPatrick Mooney * 114*d0b3c59bSPatrick Mooney */ 115*d0b3c59bSPatrick Mooney #ifdef QUEUE_MACRO_DEBUG 116*d0b3c59bSPatrick Mooney /* Store the last 2 places the queue element or head was altered */ 117*d0b3c59bSPatrick Mooney struct qm_trace { 118*d0b3c59bSPatrick Mooney unsigned long lastline; 119*d0b3c59bSPatrick Mooney unsigned long prevline; 120*d0b3c59bSPatrick Mooney const char *lastfile; 121*d0b3c59bSPatrick Mooney const char *prevfile; 122*d0b3c59bSPatrick Mooney }; 123*d0b3c59bSPatrick Mooney 124*d0b3c59bSPatrick Mooney #define TRACEBUF struct qm_trace trace; 125*d0b3c59bSPatrick Mooney #define TRACEBUF_INITIALIZER { __LINE__, 0, __FILE__, NULL } , 126*d0b3c59bSPatrick Mooney #define TRASHIT(x) do {(x) = (void *)-1;} while (0) 127*d0b3c59bSPatrick Mooney #define QMD_SAVELINK(name, link) void **name = (void *)&(link) 128*d0b3c59bSPatrick Mooney 129*d0b3c59bSPatrick Mooney #define QMD_TRACE_HEAD(head) do { \ 130*d0b3c59bSPatrick Mooney (head)->trace.prevline = (head)->trace.lastline; \ 131*d0b3c59bSPatrick Mooney (head)->trace.prevfile = (head)->trace.lastfile; \ 132*d0b3c59bSPatrick Mooney (head)->trace.lastline = __LINE__; \ 133*d0b3c59bSPatrick Mooney (head)->trace.lastfile = __FILE__; \ 134*d0b3c59bSPatrick Mooney } while (0) 135*d0b3c59bSPatrick Mooney 136*d0b3c59bSPatrick Mooney #define QMD_TRACE_ELEM(elem) do { \ 137*d0b3c59bSPatrick Mooney (elem)->trace.prevline = (elem)->trace.lastline; \ 138*d0b3c59bSPatrick Mooney (elem)->trace.prevfile = (elem)->trace.lastfile; \ 139*d0b3c59bSPatrick Mooney (elem)->trace.lastline = __LINE__; \ 140*d0b3c59bSPatrick Mooney (elem)->trace.lastfile = __FILE__; \ 141*d0b3c59bSPatrick Mooney } while (0) 142*d0b3c59bSPatrick Mooney 143*d0b3c59bSPatrick Mooney #else 144*d0b3c59bSPatrick Mooney #define QMD_TRACE_ELEM(elem) 145*d0b3c59bSPatrick Mooney #define QMD_TRACE_HEAD(head) 146*d0b3c59bSPatrick Mooney #define QMD_SAVELINK(name, link) 147*d0b3c59bSPatrick Mooney #define TRACEBUF 148*d0b3c59bSPatrick Mooney #define TRACEBUF_INITIALIZER 149*d0b3c59bSPatrick Mooney #define TRASHIT(x) 150*d0b3c59bSPatrick Mooney #endif /* QUEUE_MACRO_DEBUG */ 151*d0b3c59bSPatrick Mooney 152*d0b3c59bSPatrick Mooney #ifdef __cplusplus 153*d0b3c59bSPatrick Mooney /* 154*d0b3c59bSPatrick Mooney * In C++ there can be structure lists and class lists: 155*d0b3c59bSPatrick Mooney */ 156*d0b3c59bSPatrick Mooney #define QUEUE_TYPEOF(type) type 157*d0b3c59bSPatrick Mooney #else 158*d0b3c59bSPatrick Mooney #define QUEUE_TYPEOF(type) struct type 159*d0b3c59bSPatrick Mooney #endif 160*d0b3c59bSPatrick Mooney 161*d0b3c59bSPatrick Mooney /* 162*d0b3c59bSPatrick Mooney * Singly-linked List declarations. 163*d0b3c59bSPatrick Mooney */ 164*d0b3c59bSPatrick Mooney #define SLIST_HEAD(name, type) \ 165*d0b3c59bSPatrick Mooney struct name { \ 166*d0b3c59bSPatrick Mooney struct type *slh_first; /* first element */ \ 167*d0b3c59bSPatrick Mooney } 168*d0b3c59bSPatrick Mooney 169*d0b3c59bSPatrick Mooney #define SLIST_CLASS_HEAD(name, type) \ 170*d0b3c59bSPatrick Mooney struct name { \ 171*d0b3c59bSPatrick Mooney class type *slh_first; /* first element */ \ 172*d0b3c59bSPatrick Mooney } 173*d0b3c59bSPatrick Mooney 174*d0b3c59bSPatrick Mooney #define SLIST_HEAD_INITIALIZER(head) \ 175*d0b3c59bSPatrick Mooney { NULL } 176*d0b3c59bSPatrick Mooney 177*d0b3c59bSPatrick Mooney #define SLIST_ENTRY(type) \ 178*d0b3c59bSPatrick Mooney struct { \ 179*d0b3c59bSPatrick Mooney struct type *sle_next; /* next element */ \ 180*d0b3c59bSPatrick Mooney } 181*d0b3c59bSPatrick Mooney 182*d0b3c59bSPatrick Mooney #define SLIST_CLASS_ENTRY(type) \ 183*d0b3c59bSPatrick Mooney struct { \ 184*d0b3c59bSPatrick Mooney class type *sle_next; /* next element */ \ 185*d0b3c59bSPatrick Mooney } 186*d0b3c59bSPatrick Mooney 187*d0b3c59bSPatrick Mooney /* 188*d0b3c59bSPatrick Mooney * Singly-linked List functions. 189*d0b3c59bSPatrick Mooney */ 190*d0b3c59bSPatrick Mooney #define SLIST_CONCAT(head1, head2, type, field) do { \ 191*d0b3c59bSPatrick Mooney QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head1); \ 192*d0b3c59bSPatrick Mooney if (curelm == NULL) { \ 193*d0b3c59bSPatrick Mooney if ((SLIST_FIRST(head1) = SLIST_FIRST(head2)) != NULL) \ 194*d0b3c59bSPatrick Mooney SLIST_INIT(head2); \ 195*d0b3c59bSPatrick Mooney } else if (SLIST_FIRST(head2) != NULL) { \ 196*d0b3c59bSPatrick Mooney while (SLIST_NEXT(curelm, field) != NULL) \ 197*d0b3c59bSPatrick Mooney curelm = SLIST_NEXT(curelm, field); \ 198*d0b3c59bSPatrick Mooney SLIST_NEXT(curelm, field) = SLIST_FIRST(head2); \ 199*d0b3c59bSPatrick Mooney SLIST_INIT(head2); \ 200*d0b3c59bSPatrick Mooney } \ 201*d0b3c59bSPatrick Mooney } while (0) 202*d0b3c59bSPatrick Mooney 203*d0b3c59bSPatrick Mooney #define SLIST_EMPTY(head) ((head)->slh_first == NULL) 204*d0b3c59bSPatrick Mooney 205*d0b3c59bSPatrick Mooney #define SLIST_FIRST(head) ((head)->slh_first) 206*d0b3c59bSPatrick Mooney 207*d0b3c59bSPatrick Mooney #define SLIST_FOREACH(var, head, field) \ 208*d0b3c59bSPatrick Mooney for ((var) = SLIST_FIRST((head)); \ 209*d0b3c59bSPatrick Mooney (var); \ 210*d0b3c59bSPatrick Mooney (var) = SLIST_NEXT((var), field)) 211*d0b3c59bSPatrick Mooney 212*d0b3c59bSPatrick Mooney #define SLIST_FOREACH_FROM(var, head, field) \ 213*d0b3c59bSPatrick Mooney for ((var) = ((var) ? (var) : SLIST_FIRST((head))); \ 214*d0b3c59bSPatrick Mooney (var); \ 215*d0b3c59bSPatrick Mooney (var) = SLIST_NEXT((var), field)) 216*d0b3c59bSPatrick Mooney 217*d0b3c59bSPatrick Mooney #define SLIST_FOREACH_SAFE(var, head, field, tvar) \ 218*d0b3c59bSPatrick Mooney for ((var) = SLIST_FIRST((head)); \ 219*d0b3c59bSPatrick Mooney (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ 220*d0b3c59bSPatrick Mooney (var) = (tvar)) 221*d0b3c59bSPatrick Mooney 222*d0b3c59bSPatrick Mooney #define SLIST_FOREACH_FROM_SAFE(var, head, field, tvar) \ 223*d0b3c59bSPatrick Mooney for ((var) = ((var) ? (var) : SLIST_FIRST((head))); \ 224*d0b3c59bSPatrick Mooney (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ 225*d0b3c59bSPatrick Mooney (var) = (tvar)) 226*d0b3c59bSPatrick Mooney 227*d0b3c59bSPatrick Mooney #define SLIST_FOREACH_PREVPTR(var, varp, head, field) \ 228*d0b3c59bSPatrick Mooney for ((varp) = &SLIST_FIRST((head)); \ 229*d0b3c59bSPatrick Mooney ((var) = *(varp)) != NULL; \ 230*d0b3c59bSPatrick Mooney (varp) = &SLIST_NEXT((var), field)) 231*d0b3c59bSPatrick Mooney 232*d0b3c59bSPatrick Mooney #define SLIST_INIT(head) do { \ 233*d0b3c59bSPatrick Mooney SLIST_FIRST((head)) = NULL; \ 234*d0b3c59bSPatrick Mooney } while (0) 235*d0b3c59bSPatrick Mooney 236*d0b3c59bSPatrick Mooney #define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ 237*d0b3c59bSPatrick Mooney SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \ 238*d0b3c59bSPatrick Mooney SLIST_NEXT((slistelm), field) = (elm); \ 239*d0b3c59bSPatrick Mooney } while (0) 240*d0b3c59bSPatrick Mooney 241*d0b3c59bSPatrick Mooney #define SLIST_INSERT_HEAD(head, elm, field) do { \ 242*d0b3c59bSPatrick Mooney SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \ 243*d0b3c59bSPatrick Mooney SLIST_FIRST((head)) = (elm); \ 244*d0b3c59bSPatrick Mooney } while (0) 245*d0b3c59bSPatrick Mooney 246*d0b3c59bSPatrick Mooney #define SLIST_NEXT(elm, field) ((elm)->field.sle_next) 247*d0b3c59bSPatrick Mooney 248*d0b3c59bSPatrick Mooney #define SLIST_REMOVE(head, elm, type, field) do { \ 249*d0b3c59bSPatrick Mooney QMD_SAVELINK(oldnext, (elm)->field.sle_next); \ 250*d0b3c59bSPatrick Mooney if (SLIST_FIRST((head)) == (elm)) { \ 251*d0b3c59bSPatrick Mooney SLIST_REMOVE_HEAD((head), field); \ 252*d0b3c59bSPatrick Mooney } \ 253*d0b3c59bSPatrick Mooney else { \ 254*d0b3c59bSPatrick Mooney QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head); \ 255*d0b3c59bSPatrick Mooney while (SLIST_NEXT(curelm, field) != (elm)) \ 256*d0b3c59bSPatrick Mooney curelm = SLIST_NEXT(curelm, field); \ 257*d0b3c59bSPatrick Mooney SLIST_REMOVE_AFTER(curelm, field); \ 258*d0b3c59bSPatrick Mooney } \ 259*d0b3c59bSPatrick Mooney TRASHIT(*oldnext); \ 260*d0b3c59bSPatrick Mooney } while (0) 261*d0b3c59bSPatrick Mooney 262*d0b3c59bSPatrick Mooney #define SLIST_REMOVE_AFTER(elm, field) do { \ 263*d0b3c59bSPatrick Mooney SLIST_NEXT(elm, field) = \ 264*d0b3c59bSPatrick Mooney SLIST_NEXT(SLIST_NEXT(elm, field), field); \ 265*d0b3c59bSPatrick Mooney } while (0) 266*d0b3c59bSPatrick Mooney 267*d0b3c59bSPatrick Mooney #define SLIST_REMOVE_HEAD(head, field) do { \ 268*d0b3c59bSPatrick Mooney SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ 269*d0b3c59bSPatrick Mooney } while (0) 270*d0b3c59bSPatrick Mooney 271*d0b3c59bSPatrick Mooney #define SLIST_SWAP(head1, head2, type) do { \ 272*d0b3c59bSPatrick Mooney QUEUE_TYPEOF(type) *swap_first = SLIST_FIRST(head1); \ 273*d0b3c59bSPatrick Mooney SLIST_FIRST(head1) = SLIST_FIRST(head2); \ 274*d0b3c59bSPatrick Mooney SLIST_FIRST(head2) = swap_first; \ 275*d0b3c59bSPatrick Mooney } while (0) 276*d0b3c59bSPatrick Mooney 277*d0b3c59bSPatrick Mooney /* 278*d0b3c59bSPatrick Mooney * Singly-linked Tail queue declarations. 279*d0b3c59bSPatrick Mooney */ 280*d0b3c59bSPatrick Mooney #define STAILQ_HEAD(name, type) \ 281*d0b3c59bSPatrick Mooney struct name { \ 282*d0b3c59bSPatrick Mooney struct type *stqh_first;/* first element */ \ 283*d0b3c59bSPatrick Mooney struct type **stqh_last;/* addr of last next element */ \ 284*d0b3c59bSPatrick Mooney } 285*d0b3c59bSPatrick Mooney 286*d0b3c59bSPatrick Mooney #define STAILQ_CLASS_HEAD(name, type) \ 287*d0b3c59bSPatrick Mooney struct name { \ 288*d0b3c59bSPatrick Mooney class type *stqh_first; /* first element */ \ 289*d0b3c59bSPatrick Mooney class type **stqh_last; /* addr of last next element */ \ 290*d0b3c59bSPatrick Mooney } 291*d0b3c59bSPatrick Mooney 292*d0b3c59bSPatrick Mooney #define STAILQ_HEAD_INITIALIZER(head) \ 293*d0b3c59bSPatrick Mooney { NULL, &(head).stqh_first } 294*d0b3c59bSPatrick Mooney 295*d0b3c59bSPatrick Mooney #define STAILQ_ENTRY(type) \ 296*d0b3c59bSPatrick Mooney struct { \ 297*d0b3c59bSPatrick Mooney struct type *stqe_next; /* next element */ \ 298*d0b3c59bSPatrick Mooney } 299*d0b3c59bSPatrick Mooney 300*d0b3c59bSPatrick Mooney #define STAILQ_CLASS_ENTRY(type) \ 301*d0b3c59bSPatrick Mooney struct { \ 302*d0b3c59bSPatrick Mooney class type *stqe_next; /* next element */ \ 303*d0b3c59bSPatrick Mooney } 304*d0b3c59bSPatrick Mooney 305*d0b3c59bSPatrick Mooney /* 306*d0b3c59bSPatrick Mooney * Singly-linked Tail queue functions. 307*d0b3c59bSPatrick Mooney */ 308*d0b3c59bSPatrick Mooney #define STAILQ_CONCAT(head1, head2) do { \ 309*d0b3c59bSPatrick Mooney if (!STAILQ_EMPTY((head2))) { \ 310*d0b3c59bSPatrick Mooney *(head1)->stqh_last = (head2)->stqh_first; \ 311*d0b3c59bSPatrick Mooney (head1)->stqh_last = (head2)->stqh_last; \ 312*d0b3c59bSPatrick Mooney STAILQ_INIT((head2)); \ 313*d0b3c59bSPatrick Mooney } \ 314*d0b3c59bSPatrick Mooney } while (0) 315*d0b3c59bSPatrick Mooney 316*d0b3c59bSPatrick Mooney #define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) 317*d0b3c59bSPatrick Mooney 318*d0b3c59bSPatrick Mooney #define STAILQ_FIRST(head) ((head)->stqh_first) 319*d0b3c59bSPatrick Mooney 320*d0b3c59bSPatrick Mooney #define STAILQ_FOREACH(var, head, field) \ 321*d0b3c59bSPatrick Mooney for((var) = STAILQ_FIRST((head)); \ 322*d0b3c59bSPatrick Mooney (var); \ 323*d0b3c59bSPatrick Mooney (var) = STAILQ_NEXT((var), field)) 324*d0b3c59bSPatrick Mooney 325*d0b3c59bSPatrick Mooney #define STAILQ_FOREACH_FROM(var, head, field) \ 326*d0b3c59bSPatrick Mooney for ((var) = ((var) ? (var) : STAILQ_FIRST((head))); \ 327*d0b3c59bSPatrick Mooney (var); \ 328*d0b3c59bSPatrick Mooney (var) = STAILQ_NEXT((var), field)) 329*d0b3c59bSPatrick Mooney 330*d0b3c59bSPatrick Mooney #define STAILQ_FOREACH_SAFE(var, head, field, tvar) \ 331*d0b3c59bSPatrick Mooney for ((var) = STAILQ_FIRST((head)); \ 332*d0b3c59bSPatrick Mooney (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ 333*d0b3c59bSPatrick Mooney (var) = (tvar)) 334*d0b3c59bSPatrick Mooney 335*d0b3c59bSPatrick Mooney #define STAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \ 336*d0b3c59bSPatrick Mooney for ((var) = ((var) ? (var) : STAILQ_FIRST((head))); \ 337*d0b3c59bSPatrick Mooney (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ 338*d0b3c59bSPatrick Mooney (var) = (tvar)) 339*d0b3c59bSPatrick Mooney 340*d0b3c59bSPatrick Mooney #define STAILQ_INIT(head) do { \ 341*d0b3c59bSPatrick Mooney STAILQ_FIRST((head)) = NULL; \ 342*d0b3c59bSPatrick Mooney (head)->stqh_last = &STAILQ_FIRST((head)); \ 343*d0b3c59bSPatrick Mooney } while (0) 344*d0b3c59bSPatrick Mooney 345*d0b3c59bSPatrick Mooney #define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ 346*d0b3c59bSPatrick Mooney if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\ 347*d0b3c59bSPatrick Mooney (head)->stqh_last = &STAILQ_NEXT((elm), field); \ 348*d0b3c59bSPatrick Mooney STAILQ_NEXT((tqelm), field) = (elm); \ 349*d0b3c59bSPatrick Mooney } while (0) 350*d0b3c59bSPatrick Mooney 351*d0b3c59bSPatrick Mooney #define STAILQ_INSERT_HEAD(head, elm, field) do { \ 352*d0b3c59bSPatrick Mooney if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \ 353*d0b3c59bSPatrick Mooney (head)->stqh_last = &STAILQ_NEXT((elm), field); \ 354*d0b3c59bSPatrick Mooney STAILQ_FIRST((head)) = (elm); \ 355*d0b3c59bSPatrick Mooney } while (0) 356*d0b3c59bSPatrick Mooney 357*d0b3c59bSPatrick Mooney #define STAILQ_INSERT_TAIL(head, elm, field) do { \ 358*d0b3c59bSPatrick Mooney STAILQ_NEXT((elm), field) = NULL; \ 359*d0b3c59bSPatrick Mooney *(head)->stqh_last = (elm); \ 360*d0b3c59bSPatrick Mooney (head)->stqh_last = &STAILQ_NEXT((elm), field); \ 361*d0b3c59bSPatrick Mooney } while (0) 362*d0b3c59bSPatrick Mooney 363*d0b3c59bSPatrick Mooney #define STAILQ_LAST(head, type, field) \ 364*d0b3c59bSPatrick Mooney (STAILQ_EMPTY((head)) ? NULL : \ 365*d0b3c59bSPatrick Mooney __containerof((head)->stqh_last, \ 366*d0b3c59bSPatrick Mooney QUEUE_TYPEOF(type), field.stqe_next)) 367*d0b3c59bSPatrick Mooney 368*d0b3c59bSPatrick Mooney #define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) 369*d0b3c59bSPatrick Mooney 370*d0b3c59bSPatrick Mooney #define STAILQ_REMOVE(head, elm, type, field) do { \ 371*d0b3c59bSPatrick Mooney QMD_SAVELINK(oldnext, (elm)->field.stqe_next); \ 372*d0b3c59bSPatrick Mooney if (STAILQ_FIRST((head)) == (elm)) { \ 373*d0b3c59bSPatrick Mooney STAILQ_REMOVE_HEAD((head), field); \ 374*d0b3c59bSPatrick Mooney } \ 375*d0b3c59bSPatrick Mooney else { \ 376*d0b3c59bSPatrick Mooney QUEUE_TYPEOF(type) *curelm = STAILQ_FIRST(head); \ 377*d0b3c59bSPatrick Mooney while (STAILQ_NEXT(curelm, field) != (elm)) \ 378*d0b3c59bSPatrick Mooney curelm = STAILQ_NEXT(curelm, field); \ 379*d0b3c59bSPatrick Mooney STAILQ_REMOVE_AFTER(head, curelm, field); \ 380*d0b3c59bSPatrick Mooney } \ 381*d0b3c59bSPatrick Mooney TRASHIT(*oldnext); \ 382*d0b3c59bSPatrick Mooney } while (0) 383*d0b3c59bSPatrick Mooney 384*d0b3c59bSPatrick Mooney #define STAILQ_REMOVE_AFTER(head, elm, field) do { \ 385*d0b3c59bSPatrick Mooney if ((STAILQ_NEXT(elm, field) = \ 386*d0b3c59bSPatrick Mooney STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \ 387*d0b3c59bSPatrick Mooney (head)->stqh_last = &STAILQ_NEXT((elm), field); \ 388*d0b3c59bSPatrick Mooney } while (0) 389*d0b3c59bSPatrick Mooney 390*d0b3c59bSPatrick Mooney #define STAILQ_REMOVE_HEAD(head, field) do { \ 391*d0b3c59bSPatrick Mooney if ((STAILQ_FIRST((head)) = \ 392*d0b3c59bSPatrick Mooney STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \ 393*d0b3c59bSPatrick Mooney (head)->stqh_last = &STAILQ_FIRST((head)); \ 394*d0b3c59bSPatrick Mooney } while (0) 395*d0b3c59bSPatrick Mooney 396*d0b3c59bSPatrick Mooney #define STAILQ_SWAP(head1, head2, type) do { \ 397*d0b3c59bSPatrick Mooney QUEUE_TYPEOF(type) *swap_first = STAILQ_FIRST(head1); \ 398*d0b3c59bSPatrick Mooney QUEUE_TYPEOF(type) **swap_last = (head1)->stqh_last; \ 399*d0b3c59bSPatrick Mooney STAILQ_FIRST(head1) = STAILQ_FIRST(head2); \ 400*d0b3c59bSPatrick Mooney (head1)->stqh_last = (head2)->stqh_last; \ 401*d0b3c59bSPatrick Mooney STAILQ_FIRST(head2) = swap_first; \ 402*d0b3c59bSPatrick Mooney (head2)->stqh_last = swap_last; \ 403*d0b3c59bSPatrick Mooney if (STAILQ_EMPTY(head1)) \ 404*d0b3c59bSPatrick Mooney (head1)->stqh_last = &STAILQ_FIRST(head1); \ 405*d0b3c59bSPatrick Mooney if (STAILQ_EMPTY(head2)) \ 406*d0b3c59bSPatrick Mooney (head2)->stqh_last = &STAILQ_FIRST(head2); \ 407*d0b3c59bSPatrick Mooney } while (0) 408*d0b3c59bSPatrick Mooney 409*d0b3c59bSPatrick Mooney 410*d0b3c59bSPatrick Mooney /* 411*d0b3c59bSPatrick Mooney * List declarations. 412*d0b3c59bSPatrick Mooney */ 413*d0b3c59bSPatrick Mooney #define LIST_HEAD(name, type) \ 414*d0b3c59bSPatrick Mooney struct name { \ 415*d0b3c59bSPatrick Mooney struct type *lh_first; /* first element */ \ 416*d0b3c59bSPatrick Mooney } 417*d0b3c59bSPatrick Mooney 418*d0b3c59bSPatrick Mooney #define LIST_CLASS_HEAD(name, type) \ 419*d0b3c59bSPatrick Mooney struct name { \ 420*d0b3c59bSPatrick Mooney class type *lh_first; /* first element */ \ 421*d0b3c59bSPatrick Mooney } 422*d0b3c59bSPatrick Mooney 423*d0b3c59bSPatrick Mooney #define LIST_HEAD_INITIALIZER(head) \ 424*d0b3c59bSPatrick Mooney { NULL } 425*d0b3c59bSPatrick Mooney 426*d0b3c59bSPatrick Mooney #define LIST_ENTRY(type) \ 427*d0b3c59bSPatrick Mooney struct { \ 428*d0b3c59bSPatrick Mooney struct type *le_next; /* next element */ \ 429*d0b3c59bSPatrick Mooney struct type **le_prev; /* address of previous next element */ \ 430*d0b3c59bSPatrick Mooney } 431*d0b3c59bSPatrick Mooney 432*d0b3c59bSPatrick Mooney #define LIST_CLASS_ENTRY(type) \ 433*d0b3c59bSPatrick Mooney struct { \ 434*d0b3c59bSPatrick Mooney class type *le_next; /* next element */ \ 435*d0b3c59bSPatrick Mooney class type **le_prev; /* address of previous next element */ \ 436*d0b3c59bSPatrick Mooney } 437*d0b3c59bSPatrick Mooney 438*d0b3c59bSPatrick Mooney /* 439*d0b3c59bSPatrick Mooney * List functions. 440*d0b3c59bSPatrick Mooney */ 441*d0b3c59bSPatrick Mooney 442*d0b3c59bSPatrick Mooney #if (defined(_KERNEL) && defined(INVARIANTS)) 443*d0b3c59bSPatrick Mooney #define QMD_LIST_CHECK_HEAD(head, field) do { \ 444*d0b3c59bSPatrick Mooney if (LIST_FIRST((head)) != NULL && \ 445*d0b3c59bSPatrick Mooney LIST_FIRST((head))->field.le_prev != \ 446*d0b3c59bSPatrick Mooney &LIST_FIRST((head))) \ 447*d0b3c59bSPatrick Mooney panic("Bad list head %p first->prev != head", (head)); \ 448*d0b3c59bSPatrick Mooney } while (0) 449*d0b3c59bSPatrick Mooney 450*d0b3c59bSPatrick Mooney #define QMD_LIST_CHECK_NEXT(elm, field) do { \ 451*d0b3c59bSPatrick Mooney if (LIST_NEXT((elm), field) != NULL && \ 452*d0b3c59bSPatrick Mooney LIST_NEXT((elm), field)->field.le_prev != \ 453*d0b3c59bSPatrick Mooney &((elm)->field.le_next)) \ 454*d0b3c59bSPatrick Mooney panic("Bad link elm %p next->prev != elm", (elm)); \ 455*d0b3c59bSPatrick Mooney } while (0) 456*d0b3c59bSPatrick Mooney 457*d0b3c59bSPatrick Mooney #define QMD_LIST_CHECK_PREV(elm, field) do { \ 458*d0b3c59bSPatrick Mooney if (*(elm)->field.le_prev != (elm)) \ 459*d0b3c59bSPatrick Mooney panic("Bad link elm %p prev->next != elm", (elm)); \ 460*d0b3c59bSPatrick Mooney } while (0) 461*d0b3c59bSPatrick Mooney #else 462*d0b3c59bSPatrick Mooney #define QMD_LIST_CHECK_HEAD(head, field) 463*d0b3c59bSPatrick Mooney #define QMD_LIST_CHECK_NEXT(elm, field) 464*d0b3c59bSPatrick Mooney #define QMD_LIST_CHECK_PREV(elm, field) 465*d0b3c59bSPatrick Mooney #endif /* (_KERNEL && INVARIANTS) */ 466*d0b3c59bSPatrick Mooney 467*d0b3c59bSPatrick Mooney #define LIST_CONCAT(head1, head2, type, field) do { \ 468*d0b3c59bSPatrick Mooney QUEUE_TYPEOF(type) *curelm = LIST_FIRST(head1); \ 469*d0b3c59bSPatrick Mooney if (curelm == NULL) { \ 470*d0b3c59bSPatrick Mooney if ((LIST_FIRST(head1) = LIST_FIRST(head2)) != NULL) { \ 471*d0b3c59bSPatrick Mooney LIST_FIRST(head2)->field.le_prev = \ 472*d0b3c59bSPatrick Mooney &LIST_FIRST((head1)); \ 473*d0b3c59bSPatrick Mooney LIST_INIT(head2); \ 474*d0b3c59bSPatrick Mooney } \ 475*d0b3c59bSPatrick Mooney } else if (LIST_FIRST(head2) != NULL) { \ 476*d0b3c59bSPatrick Mooney while (LIST_NEXT(curelm, field) != NULL) \ 477*d0b3c59bSPatrick Mooney curelm = LIST_NEXT(curelm, field); \ 478*d0b3c59bSPatrick Mooney LIST_NEXT(curelm, field) = LIST_FIRST(head2); \ 479*d0b3c59bSPatrick Mooney LIST_FIRST(head2)->field.le_prev = &LIST_NEXT(curelm, field); \ 480*d0b3c59bSPatrick Mooney LIST_INIT(head2); \ 481*d0b3c59bSPatrick Mooney } \ 482*d0b3c59bSPatrick Mooney } while (0) 483*d0b3c59bSPatrick Mooney 484*d0b3c59bSPatrick Mooney #define LIST_EMPTY(head) ((head)->lh_first == NULL) 485*d0b3c59bSPatrick Mooney 486*d0b3c59bSPatrick Mooney #define LIST_FIRST(head) ((head)->lh_first) 487*d0b3c59bSPatrick Mooney 488*d0b3c59bSPatrick Mooney #define LIST_FOREACH(var, head, field) \ 489*d0b3c59bSPatrick Mooney for ((var) = LIST_FIRST((head)); \ 490*d0b3c59bSPatrick Mooney (var); \ 491*d0b3c59bSPatrick Mooney (var) = LIST_NEXT((var), field)) 492*d0b3c59bSPatrick Mooney 493*d0b3c59bSPatrick Mooney #define LIST_FOREACH_FROM(var, head, field) \ 494*d0b3c59bSPatrick Mooney for ((var) = ((var) ? (var) : LIST_FIRST((head))); \ 495*d0b3c59bSPatrick Mooney (var); \ 496*d0b3c59bSPatrick Mooney (var) = LIST_NEXT((var), field)) 497*d0b3c59bSPatrick Mooney 498*d0b3c59bSPatrick Mooney #define LIST_FOREACH_SAFE(var, head, field, tvar) \ 499*d0b3c59bSPatrick Mooney for ((var) = LIST_FIRST((head)); \ 500*d0b3c59bSPatrick Mooney (var) && ((tvar) = LIST_NEXT((var), field), 1); \ 501*d0b3c59bSPatrick Mooney (var) = (tvar)) 502*d0b3c59bSPatrick Mooney 503*d0b3c59bSPatrick Mooney #define LIST_FOREACH_FROM_SAFE(var, head, field, tvar) \ 504*d0b3c59bSPatrick Mooney for ((var) = ((var) ? (var) : LIST_FIRST((head))); \ 505*d0b3c59bSPatrick Mooney (var) && ((tvar) = LIST_NEXT((var), field), 1); \ 506*d0b3c59bSPatrick Mooney (var) = (tvar)) 507*d0b3c59bSPatrick Mooney 508*d0b3c59bSPatrick Mooney #define LIST_INIT(head) do { \ 509*d0b3c59bSPatrick Mooney LIST_FIRST((head)) = NULL; \ 510*d0b3c59bSPatrick Mooney } while (0) 511*d0b3c59bSPatrick Mooney 512*d0b3c59bSPatrick Mooney #define LIST_INSERT_AFTER(listelm, elm, field) do { \ 513*d0b3c59bSPatrick Mooney QMD_LIST_CHECK_NEXT(listelm, field); \ 514*d0b3c59bSPatrick Mooney if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\ 515*d0b3c59bSPatrick Mooney LIST_NEXT((listelm), field)->field.le_prev = \ 516*d0b3c59bSPatrick Mooney &LIST_NEXT((elm), field); \ 517*d0b3c59bSPatrick Mooney LIST_NEXT((listelm), field) = (elm); \ 518*d0b3c59bSPatrick Mooney (elm)->field.le_prev = &LIST_NEXT((listelm), field); \ 519*d0b3c59bSPatrick Mooney } while (0) 520*d0b3c59bSPatrick Mooney 521*d0b3c59bSPatrick Mooney #define LIST_INSERT_BEFORE(listelm, elm, field) do { \ 522*d0b3c59bSPatrick Mooney QMD_LIST_CHECK_PREV(listelm, field); \ 523*d0b3c59bSPatrick Mooney (elm)->field.le_prev = (listelm)->field.le_prev; \ 524*d0b3c59bSPatrick Mooney LIST_NEXT((elm), field) = (listelm); \ 525*d0b3c59bSPatrick Mooney *(listelm)->field.le_prev = (elm); \ 526*d0b3c59bSPatrick Mooney (listelm)->field.le_prev = &LIST_NEXT((elm), field); \ 527*d0b3c59bSPatrick Mooney } while (0) 528*d0b3c59bSPatrick Mooney 529*d0b3c59bSPatrick Mooney #define LIST_INSERT_HEAD(head, elm, field) do { \ 530*d0b3c59bSPatrick Mooney QMD_LIST_CHECK_HEAD((head), field); \ 531*d0b3c59bSPatrick Mooney if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ 532*d0b3c59bSPatrick Mooney LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\ 533*d0b3c59bSPatrick Mooney LIST_FIRST((head)) = (elm); \ 534*d0b3c59bSPatrick Mooney (elm)->field.le_prev = &LIST_FIRST((head)); \ 535*d0b3c59bSPatrick Mooney } while (0) 536*d0b3c59bSPatrick Mooney 537*d0b3c59bSPatrick Mooney #define LIST_NEXT(elm, field) ((elm)->field.le_next) 538*d0b3c59bSPatrick Mooney 539*d0b3c59bSPatrick Mooney #define LIST_PREV(elm, head, type, field) \ 540*d0b3c59bSPatrick Mooney ((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL : \ 541*d0b3c59bSPatrick Mooney __containerof((elm)->field.le_prev, \ 542*d0b3c59bSPatrick Mooney QUEUE_TYPEOF(type), field.le_next)) 543*d0b3c59bSPatrick Mooney 544*d0b3c59bSPatrick Mooney #define LIST_REMOVE(elm, field) do { \ 545*d0b3c59bSPatrick Mooney QMD_SAVELINK(oldnext, (elm)->field.le_next); \ 546*d0b3c59bSPatrick Mooney QMD_SAVELINK(oldprev, (elm)->field.le_prev); \ 547*d0b3c59bSPatrick Mooney QMD_LIST_CHECK_NEXT(elm, field); \ 548*d0b3c59bSPatrick Mooney QMD_LIST_CHECK_PREV(elm, field); \ 549*d0b3c59bSPatrick Mooney if (LIST_NEXT((elm), field) != NULL) \ 550*d0b3c59bSPatrick Mooney LIST_NEXT((elm), field)->field.le_prev = \ 551*d0b3c59bSPatrick Mooney (elm)->field.le_prev; \ 552*d0b3c59bSPatrick Mooney *(elm)->field.le_prev = LIST_NEXT((elm), field); \ 553*d0b3c59bSPatrick Mooney TRASHIT(*oldnext); \ 554*d0b3c59bSPatrick Mooney TRASHIT(*oldprev); \ 555*d0b3c59bSPatrick Mooney } while (0) 556*d0b3c59bSPatrick Mooney 557*d0b3c59bSPatrick Mooney #define LIST_SWAP(head1, head2, type, field) do { \ 558*d0b3c59bSPatrick Mooney QUEUE_TYPEOF(type) *swap_tmp = LIST_FIRST(head1); \ 559*d0b3c59bSPatrick Mooney LIST_FIRST((head1)) = LIST_FIRST((head2)); \ 560*d0b3c59bSPatrick Mooney LIST_FIRST((head2)) = swap_tmp; \ 561*d0b3c59bSPatrick Mooney if ((swap_tmp = LIST_FIRST((head1))) != NULL) \ 562*d0b3c59bSPatrick Mooney swap_tmp->field.le_prev = &LIST_FIRST((head1)); \ 563*d0b3c59bSPatrick Mooney if ((swap_tmp = LIST_FIRST((head2))) != NULL) \ 564*d0b3c59bSPatrick Mooney swap_tmp->field.le_prev = &LIST_FIRST((head2)); \ 565*d0b3c59bSPatrick Mooney } while (0) 566*d0b3c59bSPatrick Mooney 567*d0b3c59bSPatrick Mooney /* 568*d0b3c59bSPatrick Mooney * Tail queue declarations. 569*d0b3c59bSPatrick Mooney */ 570*d0b3c59bSPatrick Mooney #define TAILQ_HEAD(name, type) \ 571*d0b3c59bSPatrick Mooney struct name { \ 572*d0b3c59bSPatrick Mooney struct type *tqh_first; /* first element */ \ 573*d0b3c59bSPatrick Mooney struct type **tqh_last; /* addr of last next element */ \ 574*d0b3c59bSPatrick Mooney TRACEBUF \ 575*d0b3c59bSPatrick Mooney } 576*d0b3c59bSPatrick Mooney 577*d0b3c59bSPatrick Mooney #define TAILQ_CLASS_HEAD(name, type) \ 578*d0b3c59bSPatrick Mooney struct name { \ 579*d0b3c59bSPatrick Mooney class type *tqh_first; /* first element */ \ 580*d0b3c59bSPatrick Mooney class type **tqh_last; /* addr of last next element */ \ 581*d0b3c59bSPatrick Mooney TRACEBUF \ 582*d0b3c59bSPatrick Mooney } 583*d0b3c59bSPatrick Mooney 584*d0b3c59bSPatrick Mooney #define TAILQ_HEAD_INITIALIZER(head) \ 585*d0b3c59bSPatrick Mooney { NULL, &(head).tqh_first, TRACEBUF_INITIALIZER } 586*d0b3c59bSPatrick Mooney 587*d0b3c59bSPatrick Mooney #define TAILQ_ENTRY(type) \ 588*d0b3c59bSPatrick Mooney struct { \ 589*d0b3c59bSPatrick Mooney struct type *tqe_next; /* next element */ \ 590*d0b3c59bSPatrick Mooney struct type **tqe_prev; /* address of previous next element */ \ 591*d0b3c59bSPatrick Mooney TRACEBUF \ 592*d0b3c59bSPatrick Mooney } 593*d0b3c59bSPatrick Mooney 594*d0b3c59bSPatrick Mooney #define TAILQ_CLASS_ENTRY(type) \ 595*d0b3c59bSPatrick Mooney struct { \ 596*d0b3c59bSPatrick Mooney class type *tqe_next; /* next element */ \ 597*d0b3c59bSPatrick Mooney class type **tqe_prev; /* address of previous next element */ \ 598*d0b3c59bSPatrick Mooney TRACEBUF \ 599*d0b3c59bSPatrick Mooney } 600*d0b3c59bSPatrick Mooney 601*d0b3c59bSPatrick Mooney /* 602*d0b3c59bSPatrick Mooney * Tail queue functions. 603*d0b3c59bSPatrick Mooney */ 604*d0b3c59bSPatrick Mooney #if (defined(_KERNEL) && defined(INVARIANTS)) 605*d0b3c59bSPatrick Mooney #define QMD_TAILQ_CHECK_HEAD(head, field) do { \ 606*d0b3c59bSPatrick Mooney if (!TAILQ_EMPTY(head) && \ 607*d0b3c59bSPatrick Mooney TAILQ_FIRST((head))->field.tqe_prev != \ 608*d0b3c59bSPatrick Mooney &TAILQ_FIRST((head))) \ 609*d0b3c59bSPatrick Mooney panic("Bad tailq head %p first->prev != head", (head)); \ 610*d0b3c59bSPatrick Mooney } while (0) 611*d0b3c59bSPatrick Mooney 612*d0b3c59bSPatrick Mooney #define QMD_TAILQ_CHECK_TAIL(head, field) do { \ 613*d0b3c59bSPatrick Mooney if (*(head)->tqh_last != NULL) \ 614*d0b3c59bSPatrick Mooney panic("Bad tailq NEXT(%p->tqh_last) != NULL", (head)); \ 615*d0b3c59bSPatrick Mooney } while (0) 616*d0b3c59bSPatrick Mooney 617*d0b3c59bSPatrick Mooney #define QMD_TAILQ_CHECK_NEXT(elm, field) do { \ 618*d0b3c59bSPatrick Mooney if (TAILQ_NEXT((elm), field) != NULL && \ 619*d0b3c59bSPatrick Mooney TAILQ_NEXT((elm), field)->field.tqe_prev != \ 620*d0b3c59bSPatrick Mooney &((elm)->field.tqe_next)) \ 621*d0b3c59bSPatrick Mooney panic("Bad link elm %p next->prev != elm", (elm)); \ 622*d0b3c59bSPatrick Mooney } while (0) 623*d0b3c59bSPatrick Mooney 624*d0b3c59bSPatrick Mooney #define QMD_TAILQ_CHECK_PREV(elm, field) do { \ 625*d0b3c59bSPatrick Mooney if (*(elm)->field.tqe_prev != (elm)) \ 626*d0b3c59bSPatrick Mooney panic("Bad link elm %p prev->next != elm", (elm)); \ 627*d0b3c59bSPatrick Mooney } while (0) 628*d0b3c59bSPatrick Mooney #else 629*d0b3c59bSPatrick Mooney #define QMD_TAILQ_CHECK_HEAD(head, field) 630*d0b3c59bSPatrick Mooney #define QMD_TAILQ_CHECK_TAIL(head, headname) 631*d0b3c59bSPatrick Mooney #define QMD_TAILQ_CHECK_NEXT(elm, field) 632*d0b3c59bSPatrick Mooney #define QMD_TAILQ_CHECK_PREV(elm, field) 633*d0b3c59bSPatrick Mooney #endif /* (_KERNEL && INVARIANTS) */ 634*d0b3c59bSPatrick Mooney 635*d0b3c59bSPatrick Mooney #define TAILQ_CONCAT(head1, head2, field) do { \ 636*d0b3c59bSPatrick Mooney if (!TAILQ_EMPTY(head2)) { \ 637*d0b3c59bSPatrick Mooney *(head1)->tqh_last = (head2)->tqh_first; \ 638*d0b3c59bSPatrick Mooney (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \ 639*d0b3c59bSPatrick Mooney (head1)->tqh_last = (head2)->tqh_last; \ 640*d0b3c59bSPatrick Mooney TAILQ_INIT((head2)); \ 641*d0b3c59bSPatrick Mooney QMD_TRACE_HEAD(head1); \ 642*d0b3c59bSPatrick Mooney QMD_TRACE_HEAD(head2); \ 643*d0b3c59bSPatrick Mooney } \ 644*d0b3c59bSPatrick Mooney } while (0) 645*d0b3c59bSPatrick Mooney 646*d0b3c59bSPatrick Mooney #define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) 647*d0b3c59bSPatrick Mooney 648*d0b3c59bSPatrick Mooney #define TAILQ_FIRST(head) ((head)->tqh_first) 649*d0b3c59bSPatrick Mooney 650*d0b3c59bSPatrick Mooney #define TAILQ_FOREACH(var, head, field) \ 651*d0b3c59bSPatrick Mooney for ((var) = TAILQ_FIRST((head)); \ 652*d0b3c59bSPatrick Mooney (var); \ 653*d0b3c59bSPatrick Mooney (var) = TAILQ_NEXT((var), field)) 654*d0b3c59bSPatrick Mooney 655*d0b3c59bSPatrick Mooney #define TAILQ_FOREACH_FROM(var, head, field) \ 656*d0b3c59bSPatrick Mooney for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); \ 657*d0b3c59bSPatrick Mooney (var); \ 658*d0b3c59bSPatrick Mooney (var) = TAILQ_NEXT((var), field)) 659*d0b3c59bSPatrick Mooney 660*d0b3c59bSPatrick Mooney #define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ 661*d0b3c59bSPatrick Mooney for ((var) = TAILQ_FIRST((head)); \ 662*d0b3c59bSPatrick Mooney (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ 663*d0b3c59bSPatrick Mooney (var) = (tvar)) 664*d0b3c59bSPatrick Mooney 665*d0b3c59bSPatrick Mooney #define TAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \ 666*d0b3c59bSPatrick Mooney for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); \ 667*d0b3c59bSPatrick Mooney (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ 668*d0b3c59bSPatrick Mooney (var) = (tvar)) 669*d0b3c59bSPatrick Mooney 670*d0b3c59bSPatrick Mooney #define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ 671*d0b3c59bSPatrick Mooney for ((var) = TAILQ_LAST((head), headname); \ 672*d0b3c59bSPatrick Mooney (var); \ 673*d0b3c59bSPatrick Mooney (var) = TAILQ_PREV((var), headname, field)) 674*d0b3c59bSPatrick Mooney 675*d0b3c59bSPatrick Mooney #define TAILQ_FOREACH_REVERSE_FROM(var, head, headname, field) \ 676*d0b3c59bSPatrick Mooney for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); \ 677*d0b3c59bSPatrick Mooney (var); \ 678*d0b3c59bSPatrick Mooney (var) = TAILQ_PREV((var), headname, field)) 679*d0b3c59bSPatrick Mooney 680*d0b3c59bSPatrick Mooney #define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \ 681*d0b3c59bSPatrick Mooney for ((var) = TAILQ_LAST((head), headname); \ 682*d0b3c59bSPatrick Mooney (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \ 683*d0b3c59bSPatrick Mooney (var) = (tvar)) 684*d0b3c59bSPatrick Mooney 685*d0b3c59bSPatrick Mooney #define TAILQ_FOREACH_REVERSE_FROM_SAFE(var, head, headname, field, tvar) \ 686*d0b3c59bSPatrick Mooney for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); \ 687*d0b3c59bSPatrick Mooney (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \ 688*d0b3c59bSPatrick Mooney (var) = (tvar)) 689*d0b3c59bSPatrick Mooney 690*d0b3c59bSPatrick Mooney #define TAILQ_INIT(head) do { \ 691*d0b3c59bSPatrick Mooney TAILQ_FIRST((head)) = NULL; \ 692*d0b3c59bSPatrick Mooney (head)->tqh_last = &TAILQ_FIRST((head)); \ 693*d0b3c59bSPatrick Mooney QMD_TRACE_HEAD(head); \ 694*d0b3c59bSPatrick Mooney } while (0) 695*d0b3c59bSPatrick Mooney 696*d0b3c59bSPatrick Mooney #define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ 697*d0b3c59bSPatrick Mooney QMD_TAILQ_CHECK_NEXT(listelm, field); \ 698*d0b3c59bSPatrick Mooney if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\ 699*d0b3c59bSPatrick Mooney TAILQ_NEXT((elm), field)->field.tqe_prev = \ 700*d0b3c59bSPatrick Mooney &TAILQ_NEXT((elm), field); \ 701*d0b3c59bSPatrick Mooney else { \ 702*d0b3c59bSPatrick Mooney (head)->tqh_last = &TAILQ_NEXT((elm), field); \ 703*d0b3c59bSPatrick Mooney QMD_TRACE_HEAD(head); \ 704*d0b3c59bSPatrick Mooney } \ 705*d0b3c59bSPatrick Mooney TAILQ_NEXT((listelm), field) = (elm); \ 706*d0b3c59bSPatrick Mooney (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \ 707*d0b3c59bSPatrick Mooney QMD_TRACE_ELEM(&(elm)->field); \ 708*d0b3c59bSPatrick Mooney QMD_TRACE_ELEM(&(listelm)->field); \ 709*d0b3c59bSPatrick Mooney } while (0) 710*d0b3c59bSPatrick Mooney 711*d0b3c59bSPatrick Mooney #define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ 712*d0b3c59bSPatrick Mooney QMD_TAILQ_CHECK_PREV(listelm, field); \ 713*d0b3c59bSPatrick Mooney (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ 714*d0b3c59bSPatrick Mooney TAILQ_NEXT((elm), field) = (listelm); \ 715*d0b3c59bSPatrick Mooney *(listelm)->field.tqe_prev = (elm); \ 716*d0b3c59bSPatrick Mooney (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \ 717*d0b3c59bSPatrick Mooney QMD_TRACE_ELEM(&(elm)->field); \ 718*d0b3c59bSPatrick Mooney QMD_TRACE_ELEM(&(listelm)->field); \ 719*d0b3c59bSPatrick Mooney } while (0) 720*d0b3c59bSPatrick Mooney 721*d0b3c59bSPatrick Mooney #define TAILQ_INSERT_HEAD(head, elm, field) do { \ 722*d0b3c59bSPatrick Mooney QMD_TAILQ_CHECK_HEAD(head, field); \ 723*d0b3c59bSPatrick Mooney if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \ 724*d0b3c59bSPatrick Mooney TAILQ_FIRST((head))->field.tqe_prev = \ 725*d0b3c59bSPatrick Mooney &TAILQ_NEXT((elm), field); \ 726*d0b3c59bSPatrick Mooney else \ 727*d0b3c59bSPatrick Mooney (head)->tqh_last = &TAILQ_NEXT((elm), field); \ 728*d0b3c59bSPatrick Mooney TAILQ_FIRST((head)) = (elm); \ 729*d0b3c59bSPatrick Mooney (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \ 730*d0b3c59bSPatrick Mooney QMD_TRACE_HEAD(head); \ 731*d0b3c59bSPatrick Mooney QMD_TRACE_ELEM(&(elm)->field); \ 732*d0b3c59bSPatrick Mooney } while (0) 733*d0b3c59bSPatrick Mooney 734*d0b3c59bSPatrick Mooney #define TAILQ_INSERT_TAIL(head, elm, field) do { \ 735*d0b3c59bSPatrick Mooney QMD_TAILQ_CHECK_TAIL(head, field); \ 736*d0b3c59bSPatrick Mooney TAILQ_NEXT((elm), field) = NULL; \ 737*d0b3c59bSPatrick Mooney (elm)->field.tqe_prev = (head)->tqh_last; \ 738*d0b3c59bSPatrick Mooney *(head)->tqh_last = (elm); \ 739*d0b3c59bSPatrick Mooney (head)->tqh_last = &TAILQ_NEXT((elm), field); \ 740*d0b3c59bSPatrick Mooney QMD_TRACE_HEAD(head); \ 741*d0b3c59bSPatrick Mooney QMD_TRACE_ELEM(&(elm)->field); \ 742*d0b3c59bSPatrick Mooney } while (0) 743*d0b3c59bSPatrick Mooney 744*d0b3c59bSPatrick Mooney #define TAILQ_LAST(head, headname) \ 745*d0b3c59bSPatrick Mooney (*(((struct headname *)((head)->tqh_last))->tqh_last)) 746*d0b3c59bSPatrick Mooney 747*d0b3c59bSPatrick Mooney #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) 748*d0b3c59bSPatrick Mooney 749*d0b3c59bSPatrick Mooney #define TAILQ_PREV(elm, headname, field) \ 750*d0b3c59bSPatrick Mooney (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) 751*d0b3c59bSPatrick Mooney 752*d0b3c59bSPatrick Mooney #define TAILQ_REMOVE(head, elm, field) do { \ 753*d0b3c59bSPatrick Mooney QMD_SAVELINK(oldnext, (elm)->field.tqe_next); \ 754*d0b3c59bSPatrick Mooney QMD_SAVELINK(oldprev, (elm)->field.tqe_prev); \ 755*d0b3c59bSPatrick Mooney QMD_TAILQ_CHECK_NEXT(elm, field); \ 756*d0b3c59bSPatrick Mooney QMD_TAILQ_CHECK_PREV(elm, field); \ 757*d0b3c59bSPatrick Mooney if ((TAILQ_NEXT((elm), field)) != NULL) \ 758*d0b3c59bSPatrick Mooney TAILQ_NEXT((elm), field)->field.tqe_prev = \ 759*d0b3c59bSPatrick Mooney (elm)->field.tqe_prev; \ 760*d0b3c59bSPatrick Mooney else { \ 761*d0b3c59bSPatrick Mooney (head)->tqh_last = (elm)->field.tqe_prev; \ 762*d0b3c59bSPatrick Mooney QMD_TRACE_HEAD(head); \ 763*d0b3c59bSPatrick Mooney } \ 764*d0b3c59bSPatrick Mooney *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ 765*d0b3c59bSPatrick Mooney TRASHIT(*oldnext); \ 766*d0b3c59bSPatrick Mooney TRASHIT(*oldprev); \ 767*d0b3c59bSPatrick Mooney QMD_TRACE_ELEM(&(elm)->field); \ 768*d0b3c59bSPatrick Mooney } while (0) 769*d0b3c59bSPatrick Mooney 770*d0b3c59bSPatrick Mooney #define TAILQ_SWAP(head1, head2, type, field) do { \ 771*d0b3c59bSPatrick Mooney QUEUE_TYPEOF(type) *swap_first = (head1)->tqh_first; \ 772*d0b3c59bSPatrick Mooney QUEUE_TYPEOF(type) **swap_last = (head1)->tqh_last; \ 773*d0b3c59bSPatrick Mooney (head1)->tqh_first = (head2)->tqh_first; \ 774*d0b3c59bSPatrick Mooney (head1)->tqh_last = (head2)->tqh_last; \ 775*d0b3c59bSPatrick Mooney (head2)->tqh_first = swap_first; \ 776*d0b3c59bSPatrick Mooney (head2)->tqh_last = swap_last; \ 777*d0b3c59bSPatrick Mooney if ((swap_first = (head1)->tqh_first) != NULL) \ 778*d0b3c59bSPatrick Mooney swap_first->field.tqe_prev = &(head1)->tqh_first; \ 779*d0b3c59bSPatrick Mooney else \ 780*d0b3c59bSPatrick Mooney (head1)->tqh_last = &(head1)->tqh_first; \ 781*d0b3c59bSPatrick Mooney if ((swap_first = (head2)->tqh_first) != NULL) \ 782*d0b3c59bSPatrick Mooney swap_first->field.tqe_prev = &(head2)->tqh_first; \ 783*d0b3c59bSPatrick Mooney else \ 784*d0b3c59bSPatrick Mooney (head2)->tqh_last = &(head2)->tqh_first; \ 785*d0b3c59bSPatrick Mooney } while (0) 786*d0b3c59bSPatrick Mooney 787*d0b3c59bSPatrick Mooney #endif /* !_SYS_QUEUE_H_ */ 788