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