1*7f2fe78bSCy Schubert /* 2*7f2fe78bSCy Schubert * This is a copy of NetBSD's sys/queue.h, edited to use a different symbol for 3*7f2fe78bSCy Schubert * multiple inclusion protection and to suppress the include of <sys/null.h>. 4*7f2fe78bSCy Schubert */ 5*7f2fe78bSCy Schubert 6*7f2fe78bSCy Schubert /* $NetBSD: queue.h,v 1.53 2011/11/19 22:51:31 tls Exp $ */ 7*7f2fe78bSCy Schubert 8*7f2fe78bSCy Schubert /* 9*7f2fe78bSCy Schubert * Copyright (c) 1991, 1993 10*7f2fe78bSCy Schubert * The Regents of the University of California. All rights reserved. 11*7f2fe78bSCy Schubert * 12*7f2fe78bSCy Schubert * Redistribution and use in source and binary forms, with or without 13*7f2fe78bSCy Schubert * modification, are permitted provided that the following conditions 14*7f2fe78bSCy Schubert * are met: 15*7f2fe78bSCy Schubert * 1. Redistributions of source code must retain the above copyright 16*7f2fe78bSCy Schubert * notice, this list of conditions and the following disclaimer. 17*7f2fe78bSCy Schubert * 2. Redistributions in binary form must reproduce the above copyright 18*7f2fe78bSCy Schubert * notice, this list of conditions and the following disclaimer in the 19*7f2fe78bSCy Schubert * documentation and/or other materials provided with the distribution. 20*7f2fe78bSCy Schubert * 3. Neither the name of the University nor the names of its contributors 21*7f2fe78bSCy Schubert * may be used to endorse or promote products derived from this software 22*7f2fe78bSCy Schubert * without specific prior written permission. 23*7f2fe78bSCy Schubert * 24*7f2fe78bSCy Schubert * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25*7f2fe78bSCy Schubert * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26*7f2fe78bSCy Schubert * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27*7f2fe78bSCy Schubert * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28*7f2fe78bSCy Schubert * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29*7f2fe78bSCy Schubert * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30*7f2fe78bSCy Schubert * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31*7f2fe78bSCy Schubert * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32*7f2fe78bSCy Schubert * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33*7f2fe78bSCy Schubert * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34*7f2fe78bSCy Schubert * SUCH DAMAGE. 35*7f2fe78bSCy Schubert * 36*7f2fe78bSCy Schubert * @(#)queue.h 8.5 (Berkeley) 8/20/94 37*7f2fe78bSCy Schubert */ 38*7f2fe78bSCy Schubert 39*7f2fe78bSCy Schubert #ifndef K5_QUEUE_H 40*7f2fe78bSCy Schubert #define K5_QUEUE_H 41*7f2fe78bSCy Schubert 42*7f2fe78bSCy Schubert /* #include <sys/null.h> */ 43*7f2fe78bSCy Schubert 44*7f2fe78bSCy Schubert /* 45*7f2fe78bSCy Schubert * This file defines five types of data structures: singly-linked lists, 46*7f2fe78bSCy Schubert * lists, simple queues, tail queues, and circular queues. 47*7f2fe78bSCy Schubert * 48*7f2fe78bSCy Schubert * A singly-linked list is headed by a single forward pointer. The 49*7f2fe78bSCy Schubert * elements are singly linked for minimum space and pointer manipulation 50*7f2fe78bSCy Schubert * overhead at the expense of O(n) removal for arbitrary elements. New 51*7f2fe78bSCy Schubert * elements can be added to the list after an existing element or at the 52*7f2fe78bSCy Schubert * head of the list. Elements being removed from the head of the list 53*7f2fe78bSCy Schubert * should use the explicit macro for this purpose for optimum 54*7f2fe78bSCy Schubert * efficiency. A singly-linked list may only be traversed in the forward 55*7f2fe78bSCy Schubert * direction. Singly-linked lists are ideal for applications with large 56*7f2fe78bSCy Schubert * datasets and few or no removals or for implementing a LIFO queue. 57*7f2fe78bSCy Schubert * 58*7f2fe78bSCy Schubert * A list is headed by a single forward pointer (or an array of forward 59*7f2fe78bSCy Schubert * pointers for a hash table header). The elements are doubly linked 60*7f2fe78bSCy Schubert * so that an arbitrary element can be removed without a need to 61*7f2fe78bSCy Schubert * traverse the list. New elements can be added to the list before 62*7f2fe78bSCy Schubert * or after an existing element or at the head of the list. A list 63*7f2fe78bSCy Schubert * may only be traversed in the forward direction. 64*7f2fe78bSCy Schubert * 65*7f2fe78bSCy Schubert * A simple queue is headed by a pair of pointers, one the head of the 66*7f2fe78bSCy Schubert * list and the other to the tail of the list. The elements are singly 67*7f2fe78bSCy Schubert * linked to save space, so elements can only be removed from the 68*7f2fe78bSCy Schubert * head of the list. New elements can be added to the list after 69*7f2fe78bSCy Schubert * an existing element, at the head of the list, or at the end of the 70*7f2fe78bSCy Schubert * list. A simple queue may only be traversed in the forward direction. 71*7f2fe78bSCy Schubert * 72*7f2fe78bSCy Schubert * A tail queue is headed by a pair of pointers, one to the head of the 73*7f2fe78bSCy Schubert * list and the other to the tail of the list. The elements are doubly 74*7f2fe78bSCy Schubert * linked so that an arbitrary element can be removed without a need to 75*7f2fe78bSCy Schubert * traverse the list. New elements can be added to the list before or 76*7f2fe78bSCy Schubert * after an existing element, at the head of the list, or at the end of 77*7f2fe78bSCy Schubert * the list. A tail queue may be traversed in either direction. 78*7f2fe78bSCy Schubert * 79*7f2fe78bSCy Schubert * A circle queue is headed by a pair of pointers, one to the head of the 80*7f2fe78bSCy Schubert * list and the other to the tail of the list. The elements are doubly 81*7f2fe78bSCy Schubert * linked so that an arbitrary element can be removed without a need to 82*7f2fe78bSCy Schubert * traverse the list. New elements can be added to the list before or after 83*7f2fe78bSCy Schubert * an existing element, at the head of the list, or at the end of the list. 84*7f2fe78bSCy Schubert * A circle queue may be traversed in either direction, but has a more 85*7f2fe78bSCy Schubert * complex end of list detection. 86*7f2fe78bSCy Schubert * 87*7f2fe78bSCy Schubert * For details on the use of these macros, see the queue(3) manual page. 88*7f2fe78bSCy Schubert */ 89*7f2fe78bSCy Schubert 90*7f2fe78bSCy Schubert /* 91*7f2fe78bSCy Schubert * List definitions. 92*7f2fe78bSCy Schubert */ 93*7f2fe78bSCy Schubert #define K5_LIST_HEAD(name, type) \ 94*7f2fe78bSCy Schubert struct name { \ 95*7f2fe78bSCy Schubert struct type *lh_first; /* first element */ \ 96*7f2fe78bSCy Schubert } 97*7f2fe78bSCy Schubert 98*7f2fe78bSCy Schubert #define K5_LIST_HEAD_INITIALIZER(head) \ 99*7f2fe78bSCy Schubert { NULL } 100*7f2fe78bSCy Schubert 101*7f2fe78bSCy Schubert #define K5_LIST_ENTRY(type) \ 102*7f2fe78bSCy Schubert struct { \ 103*7f2fe78bSCy Schubert struct type *le_next; /* next element */ \ 104*7f2fe78bSCy Schubert struct type **le_prev; /* address of previous next element */ \ 105*7f2fe78bSCy Schubert } 106*7f2fe78bSCy Schubert 107*7f2fe78bSCy Schubert /* 108*7f2fe78bSCy Schubert * List functions. 109*7f2fe78bSCy Schubert */ 110*7f2fe78bSCy Schubert #define K5_LIST_INIT(head) do { \ 111*7f2fe78bSCy Schubert (head)->lh_first = NULL; \ 112*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 113*7f2fe78bSCy Schubert 114*7f2fe78bSCy Schubert #define K5_LIST_INSERT_AFTER(listelm, elm, field) do { \ 115*7f2fe78bSCy Schubert if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ 116*7f2fe78bSCy Schubert (listelm)->field.le_next->field.le_prev = \ 117*7f2fe78bSCy Schubert &(elm)->field.le_next; \ 118*7f2fe78bSCy Schubert (listelm)->field.le_next = (elm); \ 119*7f2fe78bSCy Schubert (elm)->field.le_prev = &(listelm)->field.le_next; \ 120*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 121*7f2fe78bSCy Schubert 122*7f2fe78bSCy Schubert #define K5_LIST_INSERT_BEFORE(listelm, elm, field) do { \ 123*7f2fe78bSCy Schubert (elm)->field.le_prev = (listelm)->field.le_prev; \ 124*7f2fe78bSCy Schubert (elm)->field.le_next = (listelm); \ 125*7f2fe78bSCy Schubert *(listelm)->field.le_prev = (elm); \ 126*7f2fe78bSCy Schubert (listelm)->field.le_prev = &(elm)->field.le_next; \ 127*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 128*7f2fe78bSCy Schubert 129*7f2fe78bSCy Schubert #define K5_LIST_INSERT_HEAD(head, elm, field) do { \ 130*7f2fe78bSCy Schubert if (((elm)->field.le_next = (head)->lh_first) != NULL) \ 131*7f2fe78bSCy Schubert (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ 132*7f2fe78bSCy Schubert (head)->lh_first = (elm); \ 133*7f2fe78bSCy Schubert (elm)->field.le_prev = &(head)->lh_first; \ 134*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 135*7f2fe78bSCy Schubert 136*7f2fe78bSCy Schubert #define K5_LIST_REMOVE(elm, field) do { \ 137*7f2fe78bSCy Schubert if ((elm)->field.le_next != NULL) \ 138*7f2fe78bSCy Schubert (elm)->field.le_next->field.le_prev = \ 139*7f2fe78bSCy Schubert (elm)->field.le_prev; \ 140*7f2fe78bSCy Schubert *(elm)->field.le_prev = (elm)->field.le_next; \ 141*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 142*7f2fe78bSCy Schubert 143*7f2fe78bSCy Schubert #define K5_LIST_FOREACH(var, head, field) \ 144*7f2fe78bSCy Schubert for ((var) = ((head)->lh_first); \ 145*7f2fe78bSCy Schubert (var); \ 146*7f2fe78bSCy Schubert (var) = ((var)->field.le_next)) 147*7f2fe78bSCy Schubert 148*7f2fe78bSCy Schubert #define K5_LIST_FOREACH_SAFE(var, head, field, tvar) \ 149*7f2fe78bSCy Schubert for ((var) = K5_LIST_FIRST((head)); \ 150*7f2fe78bSCy Schubert (var) && ((tvar) = K5_LIST_NEXT((var), field), 1); \ 151*7f2fe78bSCy Schubert (var) = (tvar)) 152*7f2fe78bSCy Schubert /* 153*7f2fe78bSCy Schubert * List access methods. 154*7f2fe78bSCy Schubert */ 155*7f2fe78bSCy Schubert #define K5_LIST_EMPTY(head) ((head)->lh_first == NULL) 156*7f2fe78bSCy Schubert #define K5_LIST_FIRST(head) ((head)->lh_first) 157*7f2fe78bSCy Schubert #define K5_LIST_NEXT(elm, field) ((elm)->field.le_next) 158*7f2fe78bSCy Schubert 159*7f2fe78bSCy Schubert 160*7f2fe78bSCy Schubert /* 161*7f2fe78bSCy Schubert * Singly-linked List definitions. 162*7f2fe78bSCy Schubert */ 163*7f2fe78bSCy Schubert #define K5_SLIST_HEAD(name, type) \ 164*7f2fe78bSCy Schubert struct name { \ 165*7f2fe78bSCy Schubert struct type *slh_first; /* first element */ \ 166*7f2fe78bSCy Schubert } 167*7f2fe78bSCy Schubert 168*7f2fe78bSCy Schubert #define K5_SLIST_HEAD_INITIALIZER(head) \ 169*7f2fe78bSCy Schubert { NULL } 170*7f2fe78bSCy Schubert 171*7f2fe78bSCy Schubert #define K5_SLIST_ENTRY(type) \ 172*7f2fe78bSCy Schubert struct { \ 173*7f2fe78bSCy Schubert struct type *sle_next; /* next element */ \ 174*7f2fe78bSCy Schubert } 175*7f2fe78bSCy Schubert 176*7f2fe78bSCy Schubert /* 177*7f2fe78bSCy Schubert * Singly-linked List functions. 178*7f2fe78bSCy Schubert */ 179*7f2fe78bSCy Schubert #define K5_SLIST_INIT(head) do { \ 180*7f2fe78bSCy Schubert (head)->slh_first = NULL; \ 181*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 182*7f2fe78bSCy Schubert 183*7f2fe78bSCy Schubert #define K5_SLIST_INSERT_AFTER(slistelm, elm, field) do { \ 184*7f2fe78bSCy Schubert (elm)->field.sle_next = (slistelm)->field.sle_next; \ 185*7f2fe78bSCy Schubert (slistelm)->field.sle_next = (elm); \ 186*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 187*7f2fe78bSCy Schubert 188*7f2fe78bSCy Schubert #define K5_SLIST_INSERT_HEAD(head, elm, field) do { \ 189*7f2fe78bSCy Schubert (elm)->field.sle_next = (head)->slh_first; \ 190*7f2fe78bSCy Schubert (head)->slh_first = (elm); \ 191*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 192*7f2fe78bSCy Schubert 193*7f2fe78bSCy Schubert #define K5_SLIST_REMOVE_HEAD(head, field) do { \ 194*7f2fe78bSCy Schubert (head)->slh_first = (head)->slh_first->field.sle_next; \ 195*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 196*7f2fe78bSCy Schubert 197*7f2fe78bSCy Schubert #define K5_SLIST_REMOVE(head, elm, type, field) do { \ 198*7f2fe78bSCy Schubert if ((head)->slh_first == (elm)) { \ 199*7f2fe78bSCy Schubert K5_SLIST_REMOVE_HEAD((head), field); \ 200*7f2fe78bSCy Schubert } \ 201*7f2fe78bSCy Schubert else { \ 202*7f2fe78bSCy Schubert struct type *curelm = (head)->slh_first; \ 203*7f2fe78bSCy Schubert while(curelm->field.sle_next != (elm)) \ 204*7f2fe78bSCy Schubert curelm = curelm->field.sle_next; \ 205*7f2fe78bSCy Schubert curelm->field.sle_next = \ 206*7f2fe78bSCy Schubert curelm->field.sle_next->field.sle_next; \ 207*7f2fe78bSCy Schubert } \ 208*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 209*7f2fe78bSCy Schubert 210*7f2fe78bSCy Schubert #define K5_SLIST_REMOVE_AFTER(slistelm, field) do { \ 211*7f2fe78bSCy Schubert (slistelm)->field.sle_next = \ 212*7f2fe78bSCy Schubert K5_SLIST_NEXT(K5_SLIST_NEXT((slistelm), field), field); \ 213*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 214*7f2fe78bSCy Schubert 215*7f2fe78bSCy Schubert #define K5_SLIST_FOREACH(var, head, field) \ 216*7f2fe78bSCy Schubert for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next) 217*7f2fe78bSCy Schubert 218*7f2fe78bSCy Schubert #define K5_SLIST_FOREACH_SAFE(var, head, field, tvar) \ 219*7f2fe78bSCy Schubert for ((var) = K5_SLIST_FIRST((head)); \ 220*7f2fe78bSCy Schubert (var) && ((tvar) = K5_SLIST_NEXT((var), field), 1); \ 221*7f2fe78bSCy Schubert (var) = (tvar)) 222*7f2fe78bSCy Schubert 223*7f2fe78bSCy Schubert /* 224*7f2fe78bSCy Schubert * Singly-linked List access methods. 225*7f2fe78bSCy Schubert */ 226*7f2fe78bSCy Schubert #define K5_SLIST_EMPTY(head) ((head)->slh_first == NULL) 227*7f2fe78bSCy Schubert #define K5_SLIST_FIRST(head) ((head)->slh_first) 228*7f2fe78bSCy Schubert #define K5_SLIST_NEXT(elm, field) ((elm)->field.sle_next) 229*7f2fe78bSCy Schubert 230*7f2fe78bSCy Schubert 231*7f2fe78bSCy Schubert /* 232*7f2fe78bSCy Schubert * Singly-linked Tail queue declarations. 233*7f2fe78bSCy Schubert */ 234*7f2fe78bSCy Schubert #define K5_STAILQ_HEAD(name, type) \ 235*7f2fe78bSCy Schubert struct name { \ 236*7f2fe78bSCy Schubert struct type *stqh_first; /* first element */ \ 237*7f2fe78bSCy Schubert struct type **stqh_last; /* addr of last next element */ \ 238*7f2fe78bSCy Schubert } 239*7f2fe78bSCy Schubert 240*7f2fe78bSCy Schubert #define K5_STAILQ_HEAD_INITIALIZER(head) \ 241*7f2fe78bSCy Schubert { NULL, &(head).stqh_first } 242*7f2fe78bSCy Schubert 243*7f2fe78bSCy Schubert #define K5_STAILQ_ENTRY(type) \ 244*7f2fe78bSCy Schubert struct { \ 245*7f2fe78bSCy Schubert struct type *stqe_next; /* next element */ \ 246*7f2fe78bSCy Schubert } 247*7f2fe78bSCy Schubert 248*7f2fe78bSCy Schubert /* 249*7f2fe78bSCy Schubert * Singly-linked Tail queue functions. 250*7f2fe78bSCy Schubert */ 251*7f2fe78bSCy Schubert #define K5_STAILQ_INIT(head) do { \ 252*7f2fe78bSCy Schubert (head)->stqh_first = NULL; \ 253*7f2fe78bSCy Schubert (head)->stqh_last = &(head)->stqh_first; \ 254*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 255*7f2fe78bSCy Schubert 256*7f2fe78bSCy Schubert #define K5_STAILQ_INSERT_HEAD(head, elm, field) do { \ 257*7f2fe78bSCy Schubert if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \ 258*7f2fe78bSCy Schubert (head)->stqh_last = &(elm)->field.stqe_next; \ 259*7f2fe78bSCy Schubert (head)->stqh_first = (elm); \ 260*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 261*7f2fe78bSCy Schubert 262*7f2fe78bSCy Schubert #define K5_STAILQ_INSERT_TAIL(head, elm, field) do { \ 263*7f2fe78bSCy Schubert (elm)->field.stqe_next = NULL; \ 264*7f2fe78bSCy Schubert *(head)->stqh_last = (elm); \ 265*7f2fe78bSCy Schubert (head)->stqh_last = &(elm)->field.stqe_next; \ 266*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 267*7f2fe78bSCy Schubert 268*7f2fe78bSCy Schubert #define K5_STAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ 269*7f2fe78bSCy Schubert if (((elm)->field.stqe_next = (listelm)->field.stqe_next) == NULL)\ 270*7f2fe78bSCy Schubert (head)->stqh_last = &(elm)->field.stqe_next; \ 271*7f2fe78bSCy Schubert (listelm)->field.stqe_next = (elm); \ 272*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 273*7f2fe78bSCy Schubert 274*7f2fe78bSCy Schubert #define K5_STAILQ_REMOVE_HEAD(head, field) do { \ 275*7f2fe78bSCy Schubert if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == NULL) \ 276*7f2fe78bSCy Schubert (head)->stqh_last = &(head)->stqh_first; \ 277*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 278*7f2fe78bSCy Schubert 279*7f2fe78bSCy Schubert #define K5_STAILQ_REMOVE(head, elm, type, field) do { \ 280*7f2fe78bSCy Schubert if ((head)->stqh_first == (elm)) { \ 281*7f2fe78bSCy Schubert K5_STAILQ_REMOVE_HEAD((head), field); \ 282*7f2fe78bSCy Schubert } else { \ 283*7f2fe78bSCy Schubert struct type *curelm = (head)->stqh_first; \ 284*7f2fe78bSCy Schubert while (curelm->field.stqe_next != (elm)) \ 285*7f2fe78bSCy Schubert curelm = curelm->field.stqe_next; \ 286*7f2fe78bSCy Schubert if ((curelm->field.stqe_next = \ 287*7f2fe78bSCy Schubert curelm->field.stqe_next->field.stqe_next) == NULL) \ 288*7f2fe78bSCy Schubert (head)->stqh_last = &(curelm)->field.stqe_next; \ 289*7f2fe78bSCy Schubert } \ 290*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 291*7f2fe78bSCy Schubert 292*7f2fe78bSCy Schubert #define K5_STAILQ_FOREACH(var, head, field) \ 293*7f2fe78bSCy Schubert for ((var) = ((head)->stqh_first); \ 294*7f2fe78bSCy Schubert (var); \ 295*7f2fe78bSCy Schubert (var) = ((var)->field.stqe_next)) 296*7f2fe78bSCy Schubert 297*7f2fe78bSCy Schubert #define K5_STAILQ_FOREACH_SAFE(var, head, field, tvar) \ 298*7f2fe78bSCy Schubert for ((var) = K5_STAILQ_FIRST((head)); \ 299*7f2fe78bSCy Schubert (var) && ((tvar) = K5_STAILQ_NEXT((var), field), 1); \ 300*7f2fe78bSCy Schubert (var) = (tvar)) 301*7f2fe78bSCy Schubert 302*7f2fe78bSCy Schubert #define K5_STAILQ_CONCAT(head1, head2) do { \ 303*7f2fe78bSCy Schubert if (!K5_STAILQ_EMPTY((head2))) { \ 304*7f2fe78bSCy Schubert *(head1)->stqh_last = (head2)->stqh_first; \ 305*7f2fe78bSCy Schubert (head1)->stqh_last = (head2)->stqh_last; \ 306*7f2fe78bSCy Schubert K5_STAILQ_INIT((head2)); \ 307*7f2fe78bSCy Schubert } \ 308*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 309*7f2fe78bSCy Schubert 310*7f2fe78bSCy Schubert #define K5_STAILQ_LAST(head, type, field) \ 311*7f2fe78bSCy Schubert (K5_STAILQ_EMPTY((head)) ? \ 312*7f2fe78bSCy Schubert NULL : \ 313*7f2fe78bSCy Schubert ((struct type *)(void *) \ 314*7f2fe78bSCy Schubert ((char *)((head)->stqh_last) - offsetof(struct type, field)))) 315*7f2fe78bSCy Schubert 316*7f2fe78bSCy Schubert /* 317*7f2fe78bSCy Schubert * Singly-linked Tail queue access methods. 318*7f2fe78bSCy Schubert */ 319*7f2fe78bSCy Schubert #define K5_STAILQ_EMPTY(head) ((head)->stqh_first == NULL) 320*7f2fe78bSCy Schubert #define K5_STAILQ_FIRST(head) ((head)->stqh_first) 321*7f2fe78bSCy Schubert #define K5_STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) 322*7f2fe78bSCy Schubert 323*7f2fe78bSCy Schubert 324*7f2fe78bSCy Schubert /* 325*7f2fe78bSCy Schubert * Simple queue definitions. 326*7f2fe78bSCy Schubert */ 327*7f2fe78bSCy Schubert #define K5_SIMPLEQ_HEAD(name, type) \ 328*7f2fe78bSCy Schubert struct name { \ 329*7f2fe78bSCy Schubert struct type *sqh_first; /* first element */ \ 330*7f2fe78bSCy Schubert struct type **sqh_last; /* addr of last next element */ \ 331*7f2fe78bSCy Schubert } 332*7f2fe78bSCy Schubert 333*7f2fe78bSCy Schubert #define K5_SIMPLEQ_HEAD_INITIALIZER(head) \ 334*7f2fe78bSCy Schubert { NULL, &(head).sqh_first } 335*7f2fe78bSCy Schubert 336*7f2fe78bSCy Schubert #define K5_SIMPLEQ_ENTRY(type) \ 337*7f2fe78bSCy Schubert struct { \ 338*7f2fe78bSCy Schubert struct type *sqe_next; /* next element */ \ 339*7f2fe78bSCy Schubert } 340*7f2fe78bSCy Schubert 341*7f2fe78bSCy Schubert /* 342*7f2fe78bSCy Schubert * Simple queue functions. 343*7f2fe78bSCy Schubert */ 344*7f2fe78bSCy Schubert #define K5_SIMPLEQ_INIT(head) do { \ 345*7f2fe78bSCy Schubert (head)->sqh_first = NULL; \ 346*7f2fe78bSCy Schubert (head)->sqh_last = &(head)->sqh_first; \ 347*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 348*7f2fe78bSCy Schubert 349*7f2fe78bSCy Schubert #define K5_SIMPLEQ_INSERT_HEAD(head, elm, field) do { \ 350*7f2fe78bSCy Schubert if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \ 351*7f2fe78bSCy Schubert (head)->sqh_last = &(elm)->field.sqe_next; \ 352*7f2fe78bSCy Schubert (head)->sqh_first = (elm); \ 353*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 354*7f2fe78bSCy Schubert 355*7f2fe78bSCy Schubert #define K5_SIMPLEQ_INSERT_TAIL(head, elm, field) do { \ 356*7f2fe78bSCy Schubert (elm)->field.sqe_next = NULL; \ 357*7f2fe78bSCy Schubert *(head)->sqh_last = (elm); \ 358*7f2fe78bSCy Schubert (head)->sqh_last = &(elm)->field.sqe_next; \ 359*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 360*7f2fe78bSCy Schubert 361*7f2fe78bSCy Schubert #define K5_SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ 362*7f2fe78bSCy Schubert if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\ 363*7f2fe78bSCy Schubert (head)->sqh_last = &(elm)->field.sqe_next; \ 364*7f2fe78bSCy Schubert (listelm)->field.sqe_next = (elm); \ 365*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 366*7f2fe78bSCy Schubert 367*7f2fe78bSCy Schubert #define K5_SIMPLEQ_REMOVE_HEAD(head, field) do { \ 368*7f2fe78bSCy Schubert if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \ 369*7f2fe78bSCy Schubert (head)->sqh_last = &(head)->sqh_first; \ 370*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 371*7f2fe78bSCy Schubert 372*7f2fe78bSCy Schubert #define K5_SIMPLEQ_REMOVE(head, elm, type, field) do { \ 373*7f2fe78bSCy Schubert if ((head)->sqh_first == (elm)) { \ 374*7f2fe78bSCy Schubert K5_SIMPLEQ_REMOVE_HEAD((head), field); \ 375*7f2fe78bSCy Schubert } else { \ 376*7f2fe78bSCy Schubert struct type *curelm = (head)->sqh_first; \ 377*7f2fe78bSCy Schubert while (curelm->field.sqe_next != (elm)) \ 378*7f2fe78bSCy Schubert curelm = curelm->field.sqe_next; \ 379*7f2fe78bSCy Schubert if ((curelm->field.sqe_next = \ 380*7f2fe78bSCy Schubert curelm->field.sqe_next->field.sqe_next) == NULL) \ 381*7f2fe78bSCy Schubert (head)->sqh_last = &(curelm)->field.sqe_next; \ 382*7f2fe78bSCy Schubert } \ 383*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 384*7f2fe78bSCy Schubert 385*7f2fe78bSCy Schubert #define K5_SIMPLEQ_FOREACH(var, head, field) \ 386*7f2fe78bSCy Schubert for ((var) = ((head)->sqh_first); \ 387*7f2fe78bSCy Schubert (var); \ 388*7f2fe78bSCy Schubert (var) = ((var)->field.sqe_next)) 389*7f2fe78bSCy Schubert 390*7f2fe78bSCy Schubert #define K5_SIMPLEQ_FOREACH_SAFE(var, head, field, next) \ 391*7f2fe78bSCy Schubert for ((var) = ((head)->sqh_first); \ 392*7f2fe78bSCy Schubert (var) && ((next = ((var)->field.sqe_next)), 1); \ 393*7f2fe78bSCy Schubert (var) = (next)) 394*7f2fe78bSCy Schubert 395*7f2fe78bSCy Schubert #define K5_SIMPLEQ_CONCAT(head1, head2) do { \ 396*7f2fe78bSCy Schubert if (!K5_SIMPLEQ_EMPTY((head2))) { \ 397*7f2fe78bSCy Schubert *(head1)->sqh_last = (head2)->sqh_first; \ 398*7f2fe78bSCy Schubert (head1)->sqh_last = (head2)->sqh_last; \ 399*7f2fe78bSCy Schubert K5_SIMPLEQ_INIT((head2)); \ 400*7f2fe78bSCy Schubert } \ 401*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 402*7f2fe78bSCy Schubert 403*7f2fe78bSCy Schubert #define K5_SIMPLEQ_LAST(head, type, field) \ 404*7f2fe78bSCy Schubert (K5_SIMPLEQ_EMPTY((head)) ? \ 405*7f2fe78bSCy Schubert NULL : \ 406*7f2fe78bSCy Schubert ((struct type *)(void *) \ 407*7f2fe78bSCy Schubert ((char *)((head)->sqh_last) - offsetof(struct type, field)))) 408*7f2fe78bSCy Schubert 409*7f2fe78bSCy Schubert /* 410*7f2fe78bSCy Schubert * Simple queue access methods. 411*7f2fe78bSCy Schubert */ 412*7f2fe78bSCy Schubert #define K5_SIMPLEQ_EMPTY(head) ((head)->sqh_first == NULL) 413*7f2fe78bSCy Schubert #define K5_SIMPLEQ_FIRST(head) ((head)->sqh_first) 414*7f2fe78bSCy Schubert #define K5_SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) 415*7f2fe78bSCy Schubert 416*7f2fe78bSCy Schubert 417*7f2fe78bSCy Schubert /* 418*7f2fe78bSCy Schubert * Tail queue definitions. 419*7f2fe78bSCy Schubert */ 420*7f2fe78bSCy Schubert #define _K5_TAILQ_HEAD(name, type, qual) \ 421*7f2fe78bSCy Schubert struct name { \ 422*7f2fe78bSCy Schubert qual type *tqh_first; /* first element */ \ 423*7f2fe78bSCy Schubert qual type *qual *tqh_last; /* addr of last next element */ \ 424*7f2fe78bSCy Schubert } 425*7f2fe78bSCy Schubert #define K5_TAILQ_HEAD(name, type) _K5_TAILQ_HEAD(name, struct type,) 426*7f2fe78bSCy Schubert 427*7f2fe78bSCy Schubert #define K5_TAILQ_HEAD_INITIALIZER(head) \ 428*7f2fe78bSCy Schubert { NULL, &(head).tqh_first } 429*7f2fe78bSCy Schubert 430*7f2fe78bSCy Schubert #define _K5_TAILQ_ENTRY(type, qual) \ 431*7f2fe78bSCy Schubert struct { \ 432*7f2fe78bSCy Schubert qual type *tqe_next; /* next element */ \ 433*7f2fe78bSCy Schubert qual type *qual *tqe_prev; /* address of previous next element */\ 434*7f2fe78bSCy Schubert } 435*7f2fe78bSCy Schubert #define K5_TAILQ_ENTRY(type) _K5_TAILQ_ENTRY(struct type,) 436*7f2fe78bSCy Schubert 437*7f2fe78bSCy Schubert /* 438*7f2fe78bSCy Schubert * Tail queue functions. 439*7f2fe78bSCy Schubert */ 440*7f2fe78bSCy Schubert #define K5_TAILQ_INIT(head) do { \ 441*7f2fe78bSCy Schubert (head)->tqh_first = NULL; \ 442*7f2fe78bSCy Schubert (head)->tqh_last = &(head)->tqh_first; \ 443*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 444*7f2fe78bSCy Schubert 445*7f2fe78bSCy Schubert #define K5_TAILQ_INSERT_HEAD(head, elm, field) do { \ 446*7f2fe78bSCy Schubert if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ 447*7f2fe78bSCy Schubert (head)->tqh_first->field.tqe_prev = \ 448*7f2fe78bSCy Schubert &(elm)->field.tqe_next; \ 449*7f2fe78bSCy Schubert else \ 450*7f2fe78bSCy Schubert (head)->tqh_last = &(elm)->field.tqe_next; \ 451*7f2fe78bSCy Schubert (head)->tqh_first = (elm); \ 452*7f2fe78bSCy Schubert (elm)->field.tqe_prev = &(head)->tqh_first; \ 453*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 454*7f2fe78bSCy Schubert 455*7f2fe78bSCy Schubert #define K5_TAILQ_INSERT_TAIL(head, elm, field) do { \ 456*7f2fe78bSCy Schubert (elm)->field.tqe_next = NULL; \ 457*7f2fe78bSCy Schubert (elm)->field.tqe_prev = (head)->tqh_last; \ 458*7f2fe78bSCy Schubert *(head)->tqh_last = (elm); \ 459*7f2fe78bSCy Schubert (head)->tqh_last = &(elm)->field.tqe_next; \ 460*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 461*7f2fe78bSCy Schubert 462*7f2fe78bSCy Schubert #define K5_TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ 463*7f2fe78bSCy Schubert if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ 464*7f2fe78bSCy Schubert (elm)->field.tqe_next->field.tqe_prev = \ 465*7f2fe78bSCy Schubert &(elm)->field.tqe_next; \ 466*7f2fe78bSCy Schubert else \ 467*7f2fe78bSCy Schubert (head)->tqh_last = &(elm)->field.tqe_next; \ 468*7f2fe78bSCy Schubert (listelm)->field.tqe_next = (elm); \ 469*7f2fe78bSCy Schubert (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ 470*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 471*7f2fe78bSCy Schubert 472*7f2fe78bSCy Schubert #define K5_TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ 473*7f2fe78bSCy Schubert (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ 474*7f2fe78bSCy Schubert (elm)->field.tqe_next = (listelm); \ 475*7f2fe78bSCy Schubert *(listelm)->field.tqe_prev = (elm); \ 476*7f2fe78bSCy Schubert (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ 477*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 478*7f2fe78bSCy Schubert 479*7f2fe78bSCy Schubert #define K5_TAILQ_REMOVE(head, elm, field) do { \ 480*7f2fe78bSCy Schubert if (((elm)->field.tqe_next) != NULL) \ 481*7f2fe78bSCy Schubert (elm)->field.tqe_next->field.tqe_prev = \ 482*7f2fe78bSCy Schubert (elm)->field.tqe_prev; \ 483*7f2fe78bSCy Schubert else \ 484*7f2fe78bSCy Schubert (head)->tqh_last = (elm)->field.tqe_prev; \ 485*7f2fe78bSCy Schubert *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ 486*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 487*7f2fe78bSCy Schubert 488*7f2fe78bSCy Schubert #define K5_TAILQ_FOREACH(var, head, field) \ 489*7f2fe78bSCy Schubert for ((var) = ((head)->tqh_first); \ 490*7f2fe78bSCy Schubert (var); \ 491*7f2fe78bSCy Schubert (var) = ((var)->field.tqe_next)) 492*7f2fe78bSCy Schubert 493*7f2fe78bSCy Schubert #define K5_TAILQ_FOREACH_SAFE(var, head, field, next) \ 494*7f2fe78bSCy Schubert for ((var) = ((head)->tqh_first); \ 495*7f2fe78bSCy Schubert (var) != NULL && ((next) = K5_TAILQ_NEXT(var, field), 1); \ 496*7f2fe78bSCy Schubert (var) = (next)) 497*7f2fe78bSCy Schubert 498*7f2fe78bSCy Schubert #define K5_TAILQ_FOREACH_REVERSE(var, head, headname, field) \ 499*7f2fe78bSCy Schubert for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \ 500*7f2fe78bSCy Schubert (var); \ 501*7f2fe78bSCy Schubert (var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last))) 502*7f2fe78bSCy Schubert 503*7f2fe78bSCy Schubert #define K5_TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, prev) \ 504*7f2fe78bSCy Schubert for ((var) = K5_TAILQ_LAST((head), headname); \ 505*7f2fe78bSCy Schubert (var) && ((prev) = K5_TAILQ_PREV((var), headname, field), 1);\ 506*7f2fe78bSCy Schubert (var) = (prev)) 507*7f2fe78bSCy Schubert 508*7f2fe78bSCy Schubert #define K5_TAILQ_CONCAT(head1, head2, field) do { \ 509*7f2fe78bSCy Schubert if (!K5_TAILQ_EMPTY(head2)) { \ 510*7f2fe78bSCy Schubert *(head1)->tqh_last = (head2)->tqh_first; \ 511*7f2fe78bSCy Schubert (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \ 512*7f2fe78bSCy Schubert (head1)->tqh_last = (head2)->tqh_last; \ 513*7f2fe78bSCy Schubert K5_TAILQ_INIT((head2)); \ 514*7f2fe78bSCy Schubert } \ 515*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 516*7f2fe78bSCy Schubert 517*7f2fe78bSCy Schubert /* 518*7f2fe78bSCy Schubert * Tail queue access methods. 519*7f2fe78bSCy Schubert */ 520*7f2fe78bSCy Schubert #define K5_TAILQ_EMPTY(head) ((head)->tqh_first == NULL) 521*7f2fe78bSCy Schubert #define K5_TAILQ_FIRST(head) ((head)->tqh_first) 522*7f2fe78bSCy Schubert #define K5_TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) 523*7f2fe78bSCy Schubert 524*7f2fe78bSCy Schubert #define K5_TAILQ_LAST(head, headname) \ 525*7f2fe78bSCy Schubert (*(((struct headname *)((head)->tqh_last))->tqh_last)) 526*7f2fe78bSCy Schubert #define K5_TAILQ_PREV(elm, headname, field) \ 527*7f2fe78bSCy Schubert (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) 528*7f2fe78bSCy Schubert 529*7f2fe78bSCy Schubert 530*7f2fe78bSCy Schubert /* 531*7f2fe78bSCy Schubert * Circular queue definitions. 532*7f2fe78bSCy Schubert */ 533*7f2fe78bSCy Schubert #define K5_CIRCLEQ_HEAD(name, type) \ 534*7f2fe78bSCy Schubert struct name { \ 535*7f2fe78bSCy Schubert struct type *cqh_first; /* first element */ \ 536*7f2fe78bSCy Schubert struct type *cqh_last; /* last element */ \ 537*7f2fe78bSCy Schubert } 538*7f2fe78bSCy Schubert 539*7f2fe78bSCy Schubert #define K5_CIRCLEQ_HEAD_INITIALIZER(head) \ 540*7f2fe78bSCy Schubert { (void *)&head, (void *)&head } 541*7f2fe78bSCy Schubert 542*7f2fe78bSCy Schubert #define K5_CIRCLEQ_ENTRY(type) \ 543*7f2fe78bSCy Schubert struct { \ 544*7f2fe78bSCy Schubert struct type *cqe_next; /* next element */ \ 545*7f2fe78bSCy Schubert struct type *cqe_prev; /* previous element */ \ 546*7f2fe78bSCy Schubert } 547*7f2fe78bSCy Schubert 548*7f2fe78bSCy Schubert /* 549*7f2fe78bSCy Schubert * Circular queue functions. 550*7f2fe78bSCy Schubert */ 551*7f2fe78bSCy Schubert #define K5_CIRCLEQ_INIT(head) do { \ 552*7f2fe78bSCy Schubert (head)->cqh_first = (void *)(head); \ 553*7f2fe78bSCy Schubert (head)->cqh_last = (void *)(head); \ 554*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 555*7f2fe78bSCy Schubert 556*7f2fe78bSCy Schubert #define K5_CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ 557*7f2fe78bSCy Schubert (elm)->field.cqe_next = (listelm)->field.cqe_next; \ 558*7f2fe78bSCy Schubert (elm)->field.cqe_prev = (listelm); \ 559*7f2fe78bSCy Schubert if ((listelm)->field.cqe_next == (void *)(head)) \ 560*7f2fe78bSCy Schubert (head)->cqh_last = (elm); \ 561*7f2fe78bSCy Schubert else \ 562*7f2fe78bSCy Schubert (listelm)->field.cqe_next->field.cqe_prev = (elm); \ 563*7f2fe78bSCy Schubert (listelm)->field.cqe_next = (elm); \ 564*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 565*7f2fe78bSCy Schubert 566*7f2fe78bSCy Schubert #define K5_CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ 567*7f2fe78bSCy Schubert (elm)->field.cqe_next = (listelm); \ 568*7f2fe78bSCy Schubert (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \ 569*7f2fe78bSCy Schubert if ((listelm)->field.cqe_prev == (void *)(head)) \ 570*7f2fe78bSCy Schubert (head)->cqh_first = (elm); \ 571*7f2fe78bSCy Schubert else \ 572*7f2fe78bSCy Schubert (listelm)->field.cqe_prev->field.cqe_next = (elm); \ 573*7f2fe78bSCy Schubert (listelm)->field.cqe_prev = (elm); \ 574*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 575*7f2fe78bSCy Schubert 576*7f2fe78bSCy Schubert #define K5_CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ 577*7f2fe78bSCy Schubert (elm)->field.cqe_next = (head)->cqh_first; \ 578*7f2fe78bSCy Schubert (elm)->field.cqe_prev = (void *)(head); \ 579*7f2fe78bSCy Schubert if ((head)->cqh_last == (void *)(head)) \ 580*7f2fe78bSCy Schubert (head)->cqh_last = (elm); \ 581*7f2fe78bSCy Schubert else \ 582*7f2fe78bSCy Schubert (head)->cqh_first->field.cqe_prev = (elm); \ 583*7f2fe78bSCy Schubert (head)->cqh_first = (elm); \ 584*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 585*7f2fe78bSCy Schubert 586*7f2fe78bSCy Schubert #define K5_CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ 587*7f2fe78bSCy Schubert (elm)->field.cqe_next = (void *)(head); \ 588*7f2fe78bSCy Schubert (elm)->field.cqe_prev = (head)->cqh_last; \ 589*7f2fe78bSCy Schubert if ((head)->cqh_first == (void *)(head)) \ 590*7f2fe78bSCy Schubert (head)->cqh_first = (elm); \ 591*7f2fe78bSCy Schubert else \ 592*7f2fe78bSCy Schubert (head)->cqh_last->field.cqe_next = (elm); \ 593*7f2fe78bSCy Schubert (head)->cqh_last = (elm); \ 594*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 595*7f2fe78bSCy Schubert 596*7f2fe78bSCy Schubert #define K5_CIRCLEQ_REMOVE(head, elm, field) do { \ 597*7f2fe78bSCy Schubert if ((elm)->field.cqe_next == (void *)(head)) \ 598*7f2fe78bSCy Schubert (head)->cqh_last = (elm)->field.cqe_prev; \ 599*7f2fe78bSCy Schubert else \ 600*7f2fe78bSCy Schubert (elm)->field.cqe_next->field.cqe_prev = \ 601*7f2fe78bSCy Schubert (elm)->field.cqe_prev; \ 602*7f2fe78bSCy Schubert if ((elm)->field.cqe_prev == (void *)(head)) \ 603*7f2fe78bSCy Schubert (head)->cqh_first = (elm)->field.cqe_next; \ 604*7f2fe78bSCy Schubert else \ 605*7f2fe78bSCy Schubert (elm)->field.cqe_prev->field.cqe_next = \ 606*7f2fe78bSCy Schubert (elm)->field.cqe_next; \ 607*7f2fe78bSCy Schubert } while (/*CONSTCOND*/0) 608*7f2fe78bSCy Schubert 609*7f2fe78bSCy Schubert #define K5_CIRCLEQ_FOREACH(var, head, field) \ 610*7f2fe78bSCy Schubert for ((var) = ((head)->cqh_first); \ 611*7f2fe78bSCy Schubert (var) != (const void *)(head); \ 612*7f2fe78bSCy Schubert (var) = ((var)->field.cqe_next)) 613*7f2fe78bSCy Schubert 614*7f2fe78bSCy Schubert #define K5_CIRCLEQ_FOREACH_REVERSE(var, head, field) \ 615*7f2fe78bSCy Schubert for ((var) = ((head)->cqh_last); \ 616*7f2fe78bSCy Schubert (var) != (const void *)(head); \ 617*7f2fe78bSCy Schubert (var) = ((var)->field.cqe_prev)) 618*7f2fe78bSCy Schubert 619*7f2fe78bSCy Schubert /* 620*7f2fe78bSCy Schubert * Circular queue access methods. 621*7f2fe78bSCy Schubert */ 622*7f2fe78bSCy Schubert #define K5_CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head)) 623*7f2fe78bSCy Schubert #define K5_CIRCLEQ_FIRST(head) ((head)->cqh_first) 624*7f2fe78bSCy Schubert #define K5_CIRCLEQ_LAST(head) ((head)->cqh_last) 625*7f2fe78bSCy Schubert #define K5_CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next) 626*7f2fe78bSCy Schubert #define K5_CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev) 627*7f2fe78bSCy Schubert 628*7f2fe78bSCy Schubert #define K5_CIRCLEQ_LOOP_NEXT(head, elm, field) \ 629*7f2fe78bSCy Schubert (((elm)->field.cqe_next == (void *)(head)) \ 630*7f2fe78bSCy Schubert ? ((head)->cqh_first) \ 631*7f2fe78bSCy Schubert : (elm->field.cqe_next)) 632*7f2fe78bSCy Schubert #define K5_CIRCLEQ_LOOP_PREV(head, elm, field) \ 633*7f2fe78bSCy Schubert (((elm)->field.cqe_prev == (void *)(head)) \ 634*7f2fe78bSCy Schubert ? ((head)->cqh_last) \ 635*7f2fe78bSCy Schubert : (elm->field.cqe_prev)) 636*7f2fe78bSCy Schubert 637*7f2fe78bSCy Schubert #endif /* !K5_QUEUE_H */ 638