1*042d53a7SEvalZero /* 2*042d53a7SEvalZero * Copyright (c) 1991, 1993 3*042d53a7SEvalZero * The Regents of the University of California. All rights reserved. 4*042d53a7SEvalZero * 5*042d53a7SEvalZero * Redistribution and use in source and binary forms, with or without 6*042d53a7SEvalZero * modification, are permitted provided that the following conditions 7*042d53a7SEvalZero * are met: 8*042d53a7SEvalZero * 1. Redistributions of source code must retain the above copyright 9*042d53a7SEvalZero * notice, this list of conditions and the following disclaimer. 10*042d53a7SEvalZero * 2. Redistributions in binary form must reproduce the above copyright 11*042d53a7SEvalZero * notice, this list of conditions and the following disclaimer in the 12*042d53a7SEvalZero * documentation and/or other materials provided with the distribution. 13*042d53a7SEvalZero * 4. Neither the name of the University nor the names of its contributors 14*042d53a7SEvalZero * may be used to endorse or promote products derived from this software 15*042d53a7SEvalZero * without specific prior written permission. 16*042d53a7SEvalZero * 17*042d53a7SEvalZero * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18*042d53a7SEvalZero * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19*042d53a7SEvalZero * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20*042d53a7SEvalZero * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21*042d53a7SEvalZero * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22*042d53a7SEvalZero * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23*042d53a7SEvalZero * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24*042d53a7SEvalZero * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25*042d53a7SEvalZero * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26*042d53a7SEvalZero * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27*042d53a7SEvalZero * SUCH DAMAGE. 28*042d53a7SEvalZero * 29*042d53a7SEvalZero * @(#)queue.h 8.5 (Berkeley) 8/20/94 30*042d53a7SEvalZero * $FreeBSD: src/sys/sys/queue.h,v 1.32.2.7 2002/04/17 14:21:02 des Exp $ 31*042d53a7SEvalZero */ 32*042d53a7SEvalZero 33*042d53a7SEvalZero #ifndef _QUEUE_H_ 34*042d53a7SEvalZero #define _QUEUE_H_ 35*042d53a7SEvalZero 36*042d53a7SEvalZero #ifdef __cplusplus 37*042d53a7SEvalZero extern "C" { 38*042d53a7SEvalZero #endif 39*042d53a7SEvalZero 40*042d53a7SEvalZero /* 41*042d53a7SEvalZero * This file defines five types of data structures: singly-linked lists, 42*042d53a7SEvalZero * singly-linked tail queues, lists, tail queues, and circular queues. 43*042d53a7SEvalZero * 44*042d53a7SEvalZero * A singly-linked list is headed by a single forward pointer. The elements 45*042d53a7SEvalZero * are singly linked for minimum space and pointer manipulation overhead at 46*042d53a7SEvalZero * the expense of O(n) removal for arbitrary elements. New elements can be 47*042d53a7SEvalZero * added to the list after an existing element or at the head of the list. 48*042d53a7SEvalZero * Elements being removed from the head of the list should use the explicit 49*042d53a7SEvalZero * macro for this purpose for optimum efficiency. A singly-linked list may 50*042d53a7SEvalZero * only be traversed in the forward direction. Singly-linked lists are ideal 51*042d53a7SEvalZero * for applications with large datasets and few or no removals or for 52*042d53a7SEvalZero * implementing a LIFO queue. 53*042d53a7SEvalZero * 54*042d53a7SEvalZero * A singly-linked tail queue is headed by a pair of pointers, one to the 55*042d53a7SEvalZero * head of the list and the other to the tail of the list. The elements are 56*042d53a7SEvalZero * singly linked for minimum space and pointer manipulation overhead at the 57*042d53a7SEvalZero * expense of O(n) removal for arbitrary elements. New elements can be added 58*042d53a7SEvalZero * to the list after an existing element, at the head of the list, or at the 59*042d53a7SEvalZero * end of the list. Elements being removed from the head of the tail queue 60*042d53a7SEvalZero * should use the explicit macro for this purpose for optimum efficiency. 61*042d53a7SEvalZero * A singly-linked tail queue may only be traversed in the forward direction. 62*042d53a7SEvalZero * Singly-linked tail queues are ideal for applications with large datasets 63*042d53a7SEvalZero * and few or no removals or for implementing a FIFO queue. 64*042d53a7SEvalZero * 65*042d53a7SEvalZero * A list is headed by a single forward pointer (or an array of forward 66*042d53a7SEvalZero * pointers for a hash table header). The elements are doubly linked 67*042d53a7SEvalZero * so that an arbitrary element can be removed without a need to 68*042d53a7SEvalZero * traverse the list. New elements can be added to the list before 69*042d53a7SEvalZero * or after an existing element or at the head of the list. A list 70*042d53a7SEvalZero * may only be traversed in the forward direction. 71*042d53a7SEvalZero * 72*042d53a7SEvalZero * A tail queue is headed by a pair of pointers, one to the head of the 73*042d53a7SEvalZero * list and the other to the tail of the list. The elements are doubly 74*042d53a7SEvalZero * linked so that an arbitrary element can be removed without a need to 75*042d53a7SEvalZero * traverse the list. New elements can be added to the list before or 76*042d53a7SEvalZero * after an existing element, at the head of the list, or at the end of 77*042d53a7SEvalZero * the list. A tail queue may be traversed in either direction. 78*042d53a7SEvalZero * 79*042d53a7SEvalZero * A circle queue is headed by a pair of pointers, one to the head of the 80*042d53a7SEvalZero * list and the other to the tail of the list. The elements are doubly 81*042d53a7SEvalZero * linked so that an arbitrary element can be removed without a need to 82*042d53a7SEvalZero * traverse the list. New elements can be added to the list before or after 83*042d53a7SEvalZero * an existing element, at the head of the list, or at the end of the list. 84*042d53a7SEvalZero * A circle queue may be traversed in either direction, but has a more 85*042d53a7SEvalZero * complex end of list detection. 86*042d53a7SEvalZero * 87*042d53a7SEvalZero * For details on the use of these macros, see the queue(3) manual page. 88*042d53a7SEvalZero * 89*042d53a7SEvalZero * 90*042d53a7SEvalZero * SLIST LIST STAILQ TAILQ CIRCLEQ 91*042d53a7SEvalZero * _HEAD + + + + + 92*042d53a7SEvalZero * _HEAD_INITIALIZER + + + + + 93*042d53a7SEvalZero * _ENTRY + + + + + 94*042d53a7SEvalZero * _INIT + + + + + 95*042d53a7SEvalZero * _EMPTY + + + + + 96*042d53a7SEvalZero * _FIRST + + + + + 97*042d53a7SEvalZero * _NEXT + + + + + 98*042d53a7SEvalZero * _PREV - - - + + 99*042d53a7SEvalZero * _LAST - - + + + 100*042d53a7SEvalZero * _FOREACH + + + + + 101*042d53a7SEvalZero * _FOREACH_REVERSE - - - + + 102*042d53a7SEvalZero * _INSERT_HEAD + + + + + 103*042d53a7SEvalZero * _INSERT_BEFORE - + - + + 104*042d53a7SEvalZero * _INSERT_AFTER + + + + + 105*042d53a7SEvalZero * _INSERT_TAIL - - + + + 106*042d53a7SEvalZero * _REMOVE_HEAD + - + - - 107*042d53a7SEvalZero * _REMOVE + + + + + 108*042d53a7SEvalZero * 109*042d53a7SEvalZero */ 110*042d53a7SEvalZero 111*042d53a7SEvalZero /* 112*042d53a7SEvalZero * Singly-linked List declarations. 113*042d53a7SEvalZero */ 114*042d53a7SEvalZero #define SLIST_HEAD(name, type) \ 115*042d53a7SEvalZero struct name { \ 116*042d53a7SEvalZero struct type *slh_first; /* first element */ \ 117*042d53a7SEvalZero } 118*042d53a7SEvalZero 119*042d53a7SEvalZero #define SLIST_HEAD_INITIALIZER(head) \ 120*042d53a7SEvalZero { NULL } 121*042d53a7SEvalZero 122*042d53a7SEvalZero #define SLIST_ENTRY(type) \ 123*042d53a7SEvalZero struct { \ 124*042d53a7SEvalZero struct type *sle_next; /* next element */ \ 125*042d53a7SEvalZero } 126*042d53a7SEvalZero 127*042d53a7SEvalZero /* 128*042d53a7SEvalZero * Singly-linked List functions. 129*042d53a7SEvalZero */ 130*042d53a7SEvalZero #define SLIST_EMPTY(head) ((head)->slh_first == NULL) 131*042d53a7SEvalZero 132*042d53a7SEvalZero #define SLIST_FIRST(head) ((head)->slh_first) 133*042d53a7SEvalZero 134*042d53a7SEvalZero #define SLIST_FOREACH(var, head, field) \ 135*042d53a7SEvalZero for ((var) = SLIST_FIRST((head)); \ 136*042d53a7SEvalZero (var); \ 137*042d53a7SEvalZero (var) = SLIST_NEXT((var), field)) 138*042d53a7SEvalZero 139*042d53a7SEvalZero #define SLIST_INIT(head) do { \ 140*042d53a7SEvalZero SLIST_FIRST((head)) = NULL; \ 141*042d53a7SEvalZero } while (0) 142*042d53a7SEvalZero 143*042d53a7SEvalZero #define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ 144*042d53a7SEvalZero SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \ 145*042d53a7SEvalZero SLIST_NEXT((slistelm), field) = (elm); \ 146*042d53a7SEvalZero } while (0) 147*042d53a7SEvalZero 148*042d53a7SEvalZero #define SLIST_INSERT_HEAD(head, elm, field) do { \ 149*042d53a7SEvalZero SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \ 150*042d53a7SEvalZero SLIST_FIRST((head)) = (elm); \ 151*042d53a7SEvalZero } while (0) 152*042d53a7SEvalZero 153*042d53a7SEvalZero #define SLIST_NEXT(elm, field) ((elm)->field.sle_next) 154*042d53a7SEvalZero 155*042d53a7SEvalZero #define SLIST_REMOVE(head, elm, type, field) do { \ 156*042d53a7SEvalZero if (SLIST_FIRST((head)) == (elm)) { \ 157*042d53a7SEvalZero SLIST_REMOVE_HEAD((head), field); \ 158*042d53a7SEvalZero } \ 159*042d53a7SEvalZero else { \ 160*042d53a7SEvalZero struct type *curelm = SLIST_FIRST((head)); \ 161*042d53a7SEvalZero while (SLIST_NEXT(curelm, field) != (elm)) \ 162*042d53a7SEvalZero curelm = SLIST_NEXT(curelm, field); \ 163*042d53a7SEvalZero SLIST_NEXT(curelm, field) = \ 164*042d53a7SEvalZero SLIST_NEXT(SLIST_NEXT(curelm, field), field); \ 165*042d53a7SEvalZero } \ 166*042d53a7SEvalZero } while (0) 167*042d53a7SEvalZero 168*042d53a7SEvalZero #define SLIST_REMOVE_HEAD(head, field) do { \ 169*042d53a7SEvalZero SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ 170*042d53a7SEvalZero } while (0) 171*042d53a7SEvalZero 172*042d53a7SEvalZero /* 173*042d53a7SEvalZero * Singly-linked Tail queue declarations. 174*042d53a7SEvalZero */ 175*042d53a7SEvalZero #define STAILQ_HEAD(name, type) \ 176*042d53a7SEvalZero struct name { \ 177*042d53a7SEvalZero struct type *stqh_first;/* first element */ \ 178*042d53a7SEvalZero struct type **stqh_last;/* addr of last next element */ \ 179*042d53a7SEvalZero } 180*042d53a7SEvalZero 181*042d53a7SEvalZero #define STAILQ_HEAD_INITIALIZER(head) \ 182*042d53a7SEvalZero { NULL, &(head).stqh_first } 183*042d53a7SEvalZero 184*042d53a7SEvalZero #define STAILQ_ENTRY(type) \ 185*042d53a7SEvalZero struct { \ 186*042d53a7SEvalZero struct type *stqe_next; /* next element */ \ 187*042d53a7SEvalZero } 188*042d53a7SEvalZero 189*042d53a7SEvalZero /* 190*042d53a7SEvalZero * Singly-linked Tail queue functions. 191*042d53a7SEvalZero */ 192*042d53a7SEvalZero #define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) 193*042d53a7SEvalZero 194*042d53a7SEvalZero #define STAILQ_FIRST(head) ((head)->stqh_first) 195*042d53a7SEvalZero 196*042d53a7SEvalZero #define STAILQ_FOREACH(var, head, field) \ 197*042d53a7SEvalZero for((var) = STAILQ_FIRST((head)); \ 198*042d53a7SEvalZero (var); \ 199*042d53a7SEvalZero (var) = STAILQ_NEXT((var), field)) 200*042d53a7SEvalZero 201*042d53a7SEvalZero #define STAILQ_INIT(head) do { \ 202*042d53a7SEvalZero STAILQ_FIRST((head)) = NULL; \ 203*042d53a7SEvalZero (head)->stqh_last = &STAILQ_FIRST((head)); \ 204*042d53a7SEvalZero } while (0) 205*042d53a7SEvalZero 206*042d53a7SEvalZero #define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ 207*042d53a7SEvalZero if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\ 208*042d53a7SEvalZero (head)->stqh_last = &STAILQ_NEXT((elm), field); \ 209*042d53a7SEvalZero STAILQ_NEXT((tqelm), field) = (elm); \ 210*042d53a7SEvalZero } while (0) 211*042d53a7SEvalZero 212*042d53a7SEvalZero #define STAILQ_INSERT_HEAD(head, elm, field) do { \ 213*042d53a7SEvalZero if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \ 214*042d53a7SEvalZero (head)->stqh_last = &STAILQ_NEXT((elm), field); \ 215*042d53a7SEvalZero STAILQ_FIRST((head)) = (elm); \ 216*042d53a7SEvalZero } while (0) 217*042d53a7SEvalZero 218*042d53a7SEvalZero #define STAILQ_INSERT_TAIL(head, elm, field) do { \ 219*042d53a7SEvalZero STAILQ_NEXT((elm), field) = NULL; \ 220*042d53a7SEvalZero *(head)->stqh_last = (elm); \ 221*042d53a7SEvalZero (head)->stqh_last = &STAILQ_NEXT((elm), field); \ 222*042d53a7SEvalZero } while (0) 223*042d53a7SEvalZero 224*042d53a7SEvalZero #define STAILQ_LAST(head, type, field) \ 225*042d53a7SEvalZero (STAILQ_EMPTY(head) ? \ 226*042d53a7SEvalZero NULL : \ 227*042d53a7SEvalZero ((struct type *) \ 228*042d53a7SEvalZero ((char *)((head)->stqh_last) - offsetof(struct type, field)))) 229*042d53a7SEvalZero 230*042d53a7SEvalZero #define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) 231*042d53a7SEvalZero 232*042d53a7SEvalZero #define STAILQ_REMOVE(head, elm, type, field) do { \ 233*042d53a7SEvalZero if (STAILQ_FIRST((head)) == (elm)) { \ 234*042d53a7SEvalZero STAILQ_REMOVE_HEAD(head, field); \ 235*042d53a7SEvalZero } \ 236*042d53a7SEvalZero else { \ 237*042d53a7SEvalZero struct type *curelm = STAILQ_FIRST((head)); \ 238*042d53a7SEvalZero while (STAILQ_NEXT(curelm, field) != (elm)) \ 239*042d53a7SEvalZero curelm = STAILQ_NEXT(curelm, field); \ 240*042d53a7SEvalZero if ((STAILQ_NEXT(curelm, field) = \ 241*042d53a7SEvalZero STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\ 242*042d53a7SEvalZero (head)->stqh_last = &STAILQ_NEXT((curelm), field);\ 243*042d53a7SEvalZero } \ 244*042d53a7SEvalZero } while (0) 245*042d53a7SEvalZero 246*042d53a7SEvalZero #define STAILQ_REMOVE_HEAD(head, field) do { \ 247*042d53a7SEvalZero if ((STAILQ_FIRST((head)) = \ 248*042d53a7SEvalZero STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \ 249*042d53a7SEvalZero (head)->stqh_last = &STAILQ_FIRST((head)); \ 250*042d53a7SEvalZero } while (0) 251*042d53a7SEvalZero 252*042d53a7SEvalZero #define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \ 253*042d53a7SEvalZero if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \ 254*042d53a7SEvalZero (head)->stqh_last = &STAILQ_FIRST((head)); \ 255*042d53a7SEvalZero } while (0) 256*042d53a7SEvalZero 257*042d53a7SEvalZero #define STAILQ_REMOVE_AFTER(head, elm, field) do { \ 258*042d53a7SEvalZero if ((STAILQ_NEXT(elm, field) = \ 259*042d53a7SEvalZero STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \ 260*042d53a7SEvalZero (head)->stqh_last = &STAILQ_NEXT((elm), field); \ 261*042d53a7SEvalZero } while (0) 262*042d53a7SEvalZero 263*042d53a7SEvalZero /* 264*042d53a7SEvalZero * List declarations. 265*042d53a7SEvalZero */ 266*042d53a7SEvalZero #define LIST_HEAD(name, type) \ 267*042d53a7SEvalZero struct name { \ 268*042d53a7SEvalZero struct type *lh_first; /* first element */ \ 269*042d53a7SEvalZero } 270*042d53a7SEvalZero 271*042d53a7SEvalZero #define LIST_HEAD_INITIALIZER(head) \ 272*042d53a7SEvalZero { NULL } 273*042d53a7SEvalZero 274*042d53a7SEvalZero #define LIST_ENTRY(type) \ 275*042d53a7SEvalZero struct { \ 276*042d53a7SEvalZero struct type *le_next; /* next element */ \ 277*042d53a7SEvalZero struct type **le_prev; /* address of previous next element */ \ 278*042d53a7SEvalZero } 279*042d53a7SEvalZero 280*042d53a7SEvalZero /* 281*042d53a7SEvalZero * List functions. 282*042d53a7SEvalZero */ 283*042d53a7SEvalZero 284*042d53a7SEvalZero #define LIST_EMPTY(head) ((head)->lh_first == NULL) 285*042d53a7SEvalZero 286*042d53a7SEvalZero #define LIST_FIRST(head) ((head)->lh_first) 287*042d53a7SEvalZero 288*042d53a7SEvalZero #define LIST_FOREACH(var, head, field) \ 289*042d53a7SEvalZero for ((var) = LIST_FIRST((head)); \ 290*042d53a7SEvalZero (var); \ 291*042d53a7SEvalZero (var) = LIST_NEXT((var), field)) 292*042d53a7SEvalZero 293*042d53a7SEvalZero #define LIST_INIT(head) do { \ 294*042d53a7SEvalZero LIST_FIRST((head)) = NULL; \ 295*042d53a7SEvalZero } while (0) 296*042d53a7SEvalZero 297*042d53a7SEvalZero #define LIST_INSERT_AFTER(listelm, elm, field) do { \ 298*042d53a7SEvalZero if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\ 299*042d53a7SEvalZero LIST_NEXT((listelm), field)->field.le_prev = \ 300*042d53a7SEvalZero &LIST_NEXT((elm), field); \ 301*042d53a7SEvalZero LIST_NEXT((listelm), field) = (elm); \ 302*042d53a7SEvalZero (elm)->field.le_prev = &LIST_NEXT((listelm), field); \ 303*042d53a7SEvalZero } while (0) 304*042d53a7SEvalZero 305*042d53a7SEvalZero #define LIST_INSERT_BEFORE(listelm, elm, field) do { \ 306*042d53a7SEvalZero (elm)->field.le_prev = (listelm)->field.le_prev; \ 307*042d53a7SEvalZero LIST_NEXT((elm), field) = (listelm); \ 308*042d53a7SEvalZero *(listelm)->field.le_prev = (elm); \ 309*042d53a7SEvalZero (listelm)->field.le_prev = &LIST_NEXT((elm), field); \ 310*042d53a7SEvalZero } while (0) 311*042d53a7SEvalZero 312*042d53a7SEvalZero #define LIST_INSERT_HEAD(head, elm, field) do { \ 313*042d53a7SEvalZero if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ 314*042d53a7SEvalZero LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\ 315*042d53a7SEvalZero LIST_FIRST((head)) = (elm); \ 316*042d53a7SEvalZero (elm)->field.le_prev = &LIST_FIRST((head)); \ 317*042d53a7SEvalZero } while (0) 318*042d53a7SEvalZero 319*042d53a7SEvalZero #define LIST_NEXT(elm, field) ((elm)->field.le_next) 320*042d53a7SEvalZero 321*042d53a7SEvalZero #define LIST_REMOVE(elm, field) do { \ 322*042d53a7SEvalZero if (LIST_NEXT((elm), field) != NULL) \ 323*042d53a7SEvalZero LIST_NEXT((elm), field)->field.le_prev = \ 324*042d53a7SEvalZero (elm)->field.le_prev; \ 325*042d53a7SEvalZero *(elm)->field.le_prev = LIST_NEXT((elm), field); \ 326*042d53a7SEvalZero } while (0) 327*042d53a7SEvalZero 328*042d53a7SEvalZero /* 329*042d53a7SEvalZero * Tail queue declarations. 330*042d53a7SEvalZero */ 331*042d53a7SEvalZero #define TAILQ_HEAD(name, type) \ 332*042d53a7SEvalZero struct name { \ 333*042d53a7SEvalZero struct type *tqh_first; /* first element */ \ 334*042d53a7SEvalZero struct type **tqh_last; /* addr of last next element */ \ 335*042d53a7SEvalZero } 336*042d53a7SEvalZero 337*042d53a7SEvalZero #define TAILQ_HEAD_INITIALIZER(head) \ 338*042d53a7SEvalZero { NULL, &(head).tqh_first } 339*042d53a7SEvalZero 340*042d53a7SEvalZero #define TAILQ_ENTRY(type) \ 341*042d53a7SEvalZero struct { \ 342*042d53a7SEvalZero struct type *tqe_next; /* next element */ \ 343*042d53a7SEvalZero struct type **tqe_prev; /* address of previous next element */ \ 344*042d53a7SEvalZero } 345*042d53a7SEvalZero 346*042d53a7SEvalZero /* 347*042d53a7SEvalZero * Tail queue functions. 348*042d53a7SEvalZero */ 349*042d53a7SEvalZero #define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) 350*042d53a7SEvalZero 351*042d53a7SEvalZero #define TAILQ_FIRST(head) ((head)->tqh_first) 352*042d53a7SEvalZero 353*042d53a7SEvalZero #define TAILQ_FOREACH(var, head, field) \ 354*042d53a7SEvalZero for ((var) = TAILQ_FIRST((head)); \ 355*042d53a7SEvalZero (var); \ 356*042d53a7SEvalZero (var) = TAILQ_NEXT((var), field)) 357*042d53a7SEvalZero 358*042d53a7SEvalZero #define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ 359*042d53a7SEvalZero for ((var) = TAILQ_LAST((head), headname); \ 360*042d53a7SEvalZero (var); \ 361*042d53a7SEvalZero (var) = TAILQ_PREV((var), headname, field)) 362*042d53a7SEvalZero 363*042d53a7SEvalZero #define TAILQ_INIT(head) do { \ 364*042d53a7SEvalZero TAILQ_FIRST((head)) = NULL; \ 365*042d53a7SEvalZero (head)->tqh_last = &TAILQ_FIRST((head)); \ 366*042d53a7SEvalZero } while (0) 367*042d53a7SEvalZero 368*042d53a7SEvalZero #define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ 369*042d53a7SEvalZero if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\ 370*042d53a7SEvalZero TAILQ_NEXT((elm), field)->field.tqe_prev = \ 371*042d53a7SEvalZero &TAILQ_NEXT((elm), field); \ 372*042d53a7SEvalZero else \ 373*042d53a7SEvalZero (head)->tqh_last = &TAILQ_NEXT((elm), field); \ 374*042d53a7SEvalZero TAILQ_NEXT((listelm), field) = (elm); \ 375*042d53a7SEvalZero (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \ 376*042d53a7SEvalZero } while (0) 377*042d53a7SEvalZero 378*042d53a7SEvalZero #define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ 379*042d53a7SEvalZero (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ 380*042d53a7SEvalZero TAILQ_NEXT((elm), field) = (listelm); \ 381*042d53a7SEvalZero *(listelm)->field.tqe_prev = (elm); \ 382*042d53a7SEvalZero (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \ 383*042d53a7SEvalZero } while (0) 384*042d53a7SEvalZero 385*042d53a7SEvalZero #define TAILQ_INSERT_HEAD(head, elm, field) do { \ 386*042d53a7SEvalZero if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \ 387*042d53a7SEvalZero TAILQ_FIRST((head))->field.tqe_prev = \ 388*042d53a7SEvalZero &TAILQ_NEXT((elm), field); \ 389*042d53a7SEvalZero else \ 390*042d53a7SEvalZero (head)->tqh_last = &TAILQ_NEXT((elm), field); \ 391*042d53a7SEvalZero TAILQ_FIRST((head)) = (elm); \ 392*042d53a7SEvalZero (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \ 393*042d53a7SEvalZero } while (0) 394*042d53a7SEvalZero 395*042d53a7SEvalZero #define TAILQ_INSERT_TAIL(head, elm, field) do { \ 396*042d53a7SEvalZero TAILQ_NEXT((elm), field) = NULL; \ 397*042d53a7SEvalZero (elm)->field.tqe_prev = (head)->tqh_last; \ 398*042d53a7SEvalZero *(head)->tqh_last = (elm); \ 399*042d53a7SEvalZero (head)->tqh_last = &TAILQ_NEXT((elm), field); \ 400*042d53a7SEvalZero } while (0) 401*042d53a7SEvalZero 402*042d53a7SEvalZero #define TAILQ_LAST(head, headname) \ 403*042d53a7SEvalZero (*(((struct headname *)((head)->tqh_last))->tqh_last)) 404*042d53a7SEvalZero 405*042d53a7SEvalZero #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) 406*042d53a7SEvalZero 407*042d53a7SEvalZero #define TAILQ_PREV(elm, headname, field) \ 408*042d53a7SEvalZero (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) 409*042d53a7SEvalZero 410*042d53a7SEvalZero #define TAILQ_REMOVE(head, elm, field) do { \ 411*042d53a7SEvalZero if ((TAILQ_NEXT((elm), field)) != NULL) \ 412*042d53a7SEvalZero TAILQ_NEXT((elm), field)->field.tqe_prev = \ 413*042d53a7SEvalZero (elm)->field.tqe_prev; \ 414*042d53a7SEvalZero else \ 415*042d53a7SEvalZero (head)->tqh_last = (elm)->field.tqe_prev; \ 416*042d53a7SEvalZero *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ 417*042d53a7SEvalZero } while (0) 418*042d53a7SEvalZero 419*042d53a7SEvalZero /* 420*042d53a7SEvalZero * Circular queue declarations. 421*042d53a7SEvalZero */ 422*042d53a7SEvalZero #define CIRCLEQ_HEAD(name, type) \ 423*042d53a7SEvalZero struct name { \ 424*042d53a7SEvalZero struct type *cqh_first; /* first element */ \ 425*042d53a7SEvalZero struct type *cqh_last; /* last element */ \ 426*042d53a7SEvalZero } 427*042d53a7SEvalZero 428*042d53a7SEvalZero #define CIRCLEQ_HEAD_INITIALIZER(head) \ 429*042d53a7SEvalZero { (void *)&(head), (void *)&(head) } 430*042d53a7SEvalZero 431*042d53a7SEvalZero #define CIRCLEQ_ENTRY(type) \ 432*042d53a7SEvalZero struct { \ 433*042d53a7SEvalZero struct type *cqe_next; /* next element */ \ 434*042d53a7SEvalZero struct type *cqe_prev; /* previous element */ \ 435*042d53a7SEvalZero } 436*042d53a7SEvalZero 437*042d53a7SEvalZero /* 438*042d53a7SEvalZero * Circular queue functions. 439*042d53a7SEvalZero */ 440*042d53a7SEvalZero #define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head)) 441*042d53a7SEvalZero 442*042d53a7SEvalZero #define CIRCLEQ_FIRST(head) ((head)->cqh_first) 443*042d53a7SEvalZero 444*042d53a7SEvalZero #define CIRCLEQ_FOREACH(var, head, field) \ 445*042d53a7SEvalZero for ((var) = CIRCLEQ_FIRST((head)); \ 446*042d53a7SEvalZero (var) != (void *)(head) || ((var) = NULL); \ 447*042d53a7SEvalZero (var) = CIRCLEQ_NEXT((var), field)) 448*042d53a7SEvalZero 449*042d53a7SEvalZero #define CIRCLEQ_FOREACH_REVERSE(var, head, field) \ 450*042d53a7SEvalZero for ((var) = CIRCLEQ_LAST((head)); \ 451*042d53a7SEvalZero (var) != (void *)(head) || ((var) = NULL); \ 452*042d53a7SEvalZero (var) = CIRCLEQ_PREV((var), field)) 453*042d53a7SEvalZero 454*042d53a7SEvalZero #define CIRCLEQ_INIT(head) do { \ 455*042d53a7SEvalZero CIRCLEQ_FIRST((head)) = (void *)(head); \ 456*042d53a7SEvalZero CIRCLEQ_LAST((head)) = (void *)(head); \ 457*042d53a7SEvalZero } while (0) 458*042d53a7SEvalZero 459*042d53a7SEvalZero #define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ 460*042d53a7SEvalZero CIRCLEQ_NEXT((elm), field) = CIRCLEQ_NEXT((listelm), field); \ 461*042d53a7SEvalZero CIRCLEQ_PREV((elm), field) = (listelm); \ 462*042d53a7SEvalZero if (CIRCLEQ_NEXT((listelm), field) == (void *)(head)) \ 463*042d53a7SEvalZero CIRCLEQ_LAST((head)) = (elm); \ 464*042d53a7SEvalZero else \ 465*042d53a7SEvalZero CIRCLEQ_PREV(CIRCLEQ_NEXT((listelm), field), field) = (elm);\ 466*042d53a7SEvalZero CIRCLEQ_NEXT((listelm), field) = (elm); \ 467*042d53a7SEvalZero } while (0) 468*042d53a7SEvalZero 469*042d53a7SEvalZero #define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ 470*042d53a7SEvalZero CIRCLEQ_NEXT((elm), field) = (listelm); \ 471*042d53a7SEvalZero CIRCLEQ_PREV((elm), field) = CIRCLEQ_PREV((listelm), field); \ 472*042d53a7SEvalZero if (CIRCLEQ_PREV((listelm), field) == (void *)(head)) \ 473*042d53a7SEvalZero CIRCLEQ_FIRST((head)) = (elm); \ 474*042d53a7SEvalZero else \ 475*042d53a7SEvalZero CIRCLEQ_NEXT(CIRCLEQ_PREV((listelm), field), field) = (elm);\ 476*042d53a7SEvalZero CIRCLEQ_PREV((listelm), field) = (elm); \ 477*042d53a7SEvalZero } while (0) 478*042d53a7SEvalZero 479*042d53a7SEvalZero #define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ 480*042d53a7SEvalZero CIRCLEQ_NEXT((elm), field) = CIRCLEQ_FIRST((head)); \ 481*042d53a7SEvalZero CIRCLEQ_PREV((elm), field) = (void *)(head); \ 482*042d53a7SEvalZero if (CIRCLEQ_LAST((head)) == (void *)(head)) \ 483*042d53a7SEvalZero CIRCLEQ_LAST((head)) = (elm); \ 484*042d53a7SEvalZero else \ 485*042d53a7SEvalZero CIRCLEQ_PREV(CIRCLEQ_FIRST((head)), field) = (elm); \ 486*042d53a7SEvalZero CIRCLEQ_FIRST((head)) = (elm); \ 487*042d53a7SEvalZero } while (0) 488*042d53a7SEvalZero 489*042d53a7SEvalZero #define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ 490*042d53a7SEvalZero CIRCLEQ_NEXT((elm), field) = (void *)(head); \ 491*042d53a7SEvalZero CIRCLEQ_PREV((elm), field) = CIRCLEQ_LAST((head)); \ 492*042d53a7SEvalZero if (CIRCLEQ_FIRST((head)) == (void *)(head)) \ 493*042d53a7SEvalZero CIRCLEQ_FIRST((head)) = (elm); \ 494*042d53a7SEvalZero else \ 495*042d53a7SEvalZero CIRCLEQ_NEXT(CIRCLEQ_LAST((head)), field) = (elm); \ 496*042d53a7SEvalZero CIRCLEQ_LAST((head)) = (elm); \ 497*042d53a7SEvalZero } while (0) 498*042d53a7SEvalZero 499*042d53a7SEvalZero #define CIRCLEQ_LAST(head) ((head)->cqh_last) 500*042d53a7SEvalZero 501*042d53a7SEvalZero #define CIRCLEQ_NEXT(elm,field) ((elm)->field.cqe_next) 502*042d53a7SEvalZero 503*042d53a7SEvalZero #define CIRCLEQ_PREV(elm,field) ((elm)->field.cqe_prev) 504*042d53a7SEvalZero 505*042d53a7SEvalZero #define CIRCLEQ_REMOVE(head, elm, field) do { \ 506*042d53a7SEvalZero if (CIRCLEQ_NEXT((elm), field) == (void *)(head)) \ 507*042d53a7SEvalZero CIRCLEQ_LAST((head)) = CIRCLEQ_PREV((elm), field); \ 508*042d53a7SEvalZero else \ 509*042d53a7SEvalZero CIRCLEQ_PREV(CIRCLEQ_NEXT((elm), field), field) = \ 510*042d53a7SEvalZero CIRCLEQ_PREV((elm), field); \ 511*042d53a7SEvalZero if (CIRCLEQ_PREV((elm), field) == (void *)(head)) \ 512*042d53a7SEvalZero CIRCLEQ_FIRST((head)) = CIRCLEQ_NEXT((elm), field); \ 513*042d53a7SEvalZero else \ 514*042d53a7SEvalZero CIRCLEQ_NEXT(CIRCLEQ_PREV((elm), field), field) = \ 515*042d53a7SEvalZero CIRCLEQ_NEXT((elm), field); \ 516*042d53a7SEvalZero } while (0) 517*042d53a7SEvalZero 518*042d53a7SEvalZero #ifdef __cplusplus 519*042d53a7SEvalZero } 520*042d53a7SEvalZero #endif 521*042d53a7SEvalZero 522*042d53a7SEvalZero #endif /* !_QUEUE_H_ */ 523