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