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