11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * Copyright (c) 1991, 1993 31da177e4SLinus Torvalds * The Regents of the University of California. All rights reserved. 41da177e4SLinus Torvalds * 51da177e4SLinus Torvalds * Redistribution and use in source and binary forms, with or without 61da177e4SLinus Torvalds * modification, are permitted provided that the following conditions 71da177e4SLinus Torvalds * are met: 81da177e4SLinus Torvalds * 1. Redistributions of source code must retain the above copyright 91da177e4SLinus Torvalds * notice, this list of conditions and the following disclaimer. 101da177e4SLinus Torvalds * 2. Redistributions in binary form must reproduce the above copyright 111da177e4SLinus Torvalds * notice, this list of conditions and the following disclaimer in the 121da177e4SLinus Torvalds * documentation and/or other materials provided with the distribution. 131da177e4SLinus Torvalds * 141da177e4SLinus Torvalds * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 151da177e4SLinus Torvalds * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 161da177e4SLinus Torvalds * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 171da177e4SLinus Torvalds * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 181da177e4SLinus Torvalds * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 191da177e4SLinus Torvalds * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 201da177e4SLinus Torvalds * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 211da177e4SLinus Torvalds * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 221da177e4SLinus Torvalds * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 231da177e4SLinus Torvalds * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 241da177e4SLinus Torvalds * SUCH DAMAGE. 251da177e4SLinus Torvalds * 261da177e4SLinus Torvalds * @(#)queue.h 8.5 (Berkeley) 8/20/94 271da177e4SLinus Torvalds * $FreeBSD: src/sys/sys/queue.h,v 1.38 2000/05/26 02:06:56 jake Exp $ 281da177e4SLinus Torvalds */ 291da177e4SLinus Torvalds 301da177e4SLinus Torvalds #ifndef _SYS_QUEUE_H_ 311da177e4SLinus Torvalds #define _SYS_QUEUE_H_ 321da177e4SLinus Torvalds 331da177e4SLinus Torvalds /* 341da177e4SLinus Torvalds * This file defines five types of data structures: singly-linked lists, 351da177e4SLinus Torvalds * singly-linked tail queues, lists, tail queues, and circular queues. 361da177e4SLinus Torvalds * 371da177e4SLinus Torvalds * A singly-linked list is headed by a single forward pointer. The elements 381da177e4SLinus Torvalds * are singly linked for minimum space and pointer manipulation overhead at 391da177e4SLinus Torvalds * the expense of O(n) removal for arbitrary elements. New elements can be 401da177e4SLinus Torvalds * added to the list after an existing element or at the head of the list. 411da177e4SLinus Torvalds * Elements being removed from the head of the list should use the explicit 421da177e4SLinus Torvalds * macro for this purpose for optimum efficiency. A singly-linked list may 431da177e4SLinus Torvalds * only be traversed in the forward direction. Singly-linked lists are ideal 441da177e4SLinus Torvalds * for applications with large datasets and few or no removals or for 451da177e4SLinus Torvalds * implementing a LIFO queue. 461da177e4SLinus Torvalds * 471da177e4SLinus Torvalds * A singly-linked tail queue is headed by a pair of pointers, one to the 481da177e4SLinus Torvalds * head of the list and the other to the tail of the list. The elements are 491da177e4SLinus Torvalds * singly linked for minimum space and pointer manipulation overhead at the 501da177e4SLinus Torvalds * expense of O(n) removal for arbitrary elements. New elements can be added 511da177e4SLinus Torvalds * to the list after an existing element, at the head of the list, or at the 521da177e4SLinus Torvalds * end of the list. Elements being removed from the head of the tail queue 531da177e4SLinus Torvalds * should use the explicit macro for this purpose for optimum efficiency. 541da177e4SLinus Torvalds * A singly-linked tail queue may only be traversed in the forward direction. 551da177e4SLinus Torvalds * Singly-linked tail queues are ideal for applications with large datasets 561da177e4SLinus Torvalds * and few or no removals or for implementing a FIFO queue. 571da177e4SLinus Torvalds * 581da177e4SLinus Torvalds * A list is headed by a single forward pointer (or an array of forward 591da177e4SLinus Torvalds * pointers for a hash table header). The elements are doubly linked 601da177e4SLinus Torvalds * so that an arbitrary element can be removed without a need to 611da177e4SLinus Torvalds * traverse the list. New elements can be added to the list before 621da177e4SLinus Torvalds * or after an existing element or at the head of the list. A list 631da177e4SLinus Torvalds * may only be traversed in the forward direction. 641da177e4SLinus Torvalds * 651da177e4SLinus Torvalds * A tail queue is headed by a pair of pointers, one to the head of the 661da177e4SLinus Torvalds * list and the other to the tail of the list. The elements are doubly 671da177e4SLinus Torvalds * linked so that an arbitrary element can be removed without a need to 681da177e4SLinus Torvalds * traverse the list. New elements can be added to the list before or 691da177e4SLinus Torvalds * after an existing element, at the head of the list, or at the end of 701da177e4SLinus Torvalds * the list. A tail queue may be traversed in either direction. 711da177e4SLinus Torvalds * 721da177e4SLinus Torvalds * A circle queue is headed by a pair of pointers, one to the head of the 731da177e4SLinus Torvalds * list and the other to the tail of the list. The elements are doubly 741da177e4SLinus Torvalds * linked so that an arbitrary element can be removed without a need to 751da177e4SLinus Torvalds * traverse the list. New elements can be added to the list before or after 761da177e4SLinus Torvalds * an existing element, at the head of the list, or at the end of the list. 771da177e4SLinus Torvalds * A circle queue may be traversed in either direction, but has a more 781da177e4SLinus Torvalds * complex end of list detection. 791da177e4SLinus Torvalds * 801da177e4SLinus Torvalds * For details on the use of these macros, see the queue(3) manual page. 811da177e4SLinus Torvalds * 821da177e4SLinus Torvalds * 831da177e4SLinus Torvalds * SLIST LIST STAILQ TAILQ CIRCLEQ 841da177e4SLinus Torvalds * _HEAD + + + + + 851da177e4SLinus Torvalds * _HEAD_INITIALIZER + + + + + 861da177e4SLinus Torvalds * _ENTRY + + + + + 871da177e4SLinus Torvalds * _INIT + + + + + 881da177e4SLinus Torvalds * _EMPTY + + + + + 891da177e4SLinus Torvalds * _FIRST + + + + + 901da177e4SLinus Torvalds * _NEXT + + + + + 911da177e4SLinus Torvalds * _PREV - - - + + 921da177e4SLinus Torvalds * _LAST - - + + + 931da177e4SLinus Torvalds * _FOREACH + + + + + 941da177e4SLinus Torvalds * _FOREACH_REVERSE - - - + + 951da177e4SLinus Torvalds * _INSERT_HEAD + + + + + 961da177e4SLinus Torvalds * _INSERT_BEFORE - + - + + 971da177e4SLinus Torvalds * _INSERT_AFTER + + + + + 981da177e4SLinus Torvalds * _INSERT_TAIL - - + + + 991da177e4SLinus Torvalds * _REMOVE_HEAD + - + - - 1001da177e4SLinus Torvalds * _REMOVE + + + + + 1011da177e4SLinus Torvalds * 1021da177e4SLinus Torvalds */ 1031da177e4SLinus Torvalds 1041da177e4SLinus Torvalds /* 1051da177e4SLinus Torvalds * Singly-linked List declarations. 1061da177e4SLinus Torvalds */ 1071da177e4SLinus Torvalds #define SLIST_HEAD(name, type) \ 1081da177e4SLinus Torvalds struct name { \ 1091da177e4SLinus Torvalds struct type *slh_first; /* first element */ \ 1101da177e4SLinus Torvalds } 1111da177e4SLinus Torvalds 1121da177e4SLinus Torvalds #define SLIST_HEAD_INITIALIZER(head) \ 1131da177e4SLinus Torvalds { NULL } 1141da177e4SLinus Torvalds 1151da177e4SLinus Torvalds #define SLIST_ENTRY(type) \ 1161da177e4SLinus Torvalds struct { \ 1171da177e4SLinus Torvalds struct type *sle_next; /* next element */ \ 1181da177e4SLinus Torvalds } 1191da177e4SLinus Torvalds 1201da177e4SLinus Torvalds /* 1211da177e4SLinus Torvalds * Singly-linked List functions. 1221da177e4SLinus Torvalds */ 1231da177e4SLinus Torvalds #define SLIST_EMPTY(head) ((head)->slh_first == NULL) 1241da177e4SLinus Torvalds 1251da177e4SLinus Torvalds #define SLIST_FIRST(head) ((head)->slh_first) 1261da177e4SLinus Torvalds 1271da177e4SLinus Torvalds #define SLIST_FOREACH(var, head, field) \ 1281da177e4SLinus Torvalds for ((var) = SLIST_FIRST((head)); \ 1291da177e4SLinus Torvalds (var); \ 1301da177e4SLinus Torvalds (var) = SLIST_NEXT((var), field)) 1311da177e4SLinus Torvalds 1321da177e4SLinus Torvalds #define SLIST_INIT(head) do { \ 1331da177e4SLinus Torvalds SLIST_FIRST((head)) = NULL; \ 1341da177e4SLinus Torvalds } while (0) 1351da177e4SLinus Torvalds 1361da177e4SLinus Torvalds #define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ 1371da177e4SLinus Torvalds SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \ 1381da177e4SLinus Torvalds SLIST_NEXT((slistelm), field) = (elm); \ 1391da177e4SLinus Torvalds } while (0) 1401da177e4SLinus Torvalds 1411da177e4SLinus Torvalds #define SLIST_INSERT_HEAD(head, elm, field) do { \ 1421da177e4SLinus Torvalds SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \ 1431da177e4SLinus Torvalds SLIST_FIRST((head)) = (elm); \ 1441da177e4SLinus Torvalds } while (0) 1451da177e4SLinus Torvalds 1461da177e4SLinus Torvalds #define SLIST_NEXT(elm, field) ((elm)->field.sle_next) 1471da177e4SLinus Torvalds 1481da177e4SLinus Torvalds #define SLIST_REMOVE(head, elm, type, field) do { \ 1491da177e4SLinus Torvalds if (SLIST_FIRST((head)) == (elm)) { \ 1501da177e4SLinus Torvalds SLIST_REMOVE_HEAD((head), field); \ 1511da177e4SLinus Torvalds } \ 1521da177e4SLinus Torvalds else { \ 1531da177e4SLinus Torvalds struct type *curelm = SLIST_FIRST((head)); \ 1541da177e4SLinus Torvalds while (SLIST_NEXT(curelm, field) != (elm)) \ 1551da177e4SLinus Torvalds curelm = SLIST_NEXT(curelm, field); \ 1561da177e4SLinus Torvalds SLIST_NEXT(curelm, field) = \ 1571da177e4SLinus Torvalds SLIST_NEXT(SLIST_NEXT(curelm, field), field); \ 1581da177e4SLinus Torvalds } \ 1591da177e4SLinus Torvalds } while (0) 1601da177e4SLinus Torvalds 1611da177e4SLinus Torvalds #define SLIST_REMOVE_HEAD(head, field) do { \ 1621da177e4SLinus Torvalds SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ 1631da177e4SLinus Torvalds } while (0) 1641da177e4SLinus Torvalds 1651da177e4SLinus Torvalds /* 1661da177e4SLinus Torvalds * Singly-linked Tail queue declarations. 1671da177e4SLinus Torvalds */ 1681da177e4SLinus Torvalds #define STAILQ_HEAD(name, type) \ 1691da177e4SLinus Torvalds struct name { \ 1701da177e4SLinus Torvalds struct type *stqh_first;/* first element */ \ 1711da177e4SLinus Torvalds struct type **stqh_last;/* addr of last next element */ \ 1721da177e4SLinus Torvalds } 1731da177e4SLinus Torvalds 1741da177e4SLinus Torvalds #define STAILQ_HEAD_INITIALIZER(head) \ 1751da177e4SLinus Torvalds { NULL, &(head).stqh_first } 1761da177e4SLinus Torvalds 1771da177e4SLinus Torvalds #define STAILQ_ENTRY(type) \ 1781da177e4SLinus Torvalds struct { \ 1791da177e4SLinus Torvalds struct type *stqe_next; /* next element */ \ 1801da177e4SLinus Torvalds } 1811da177e4SLinus Torvalds 1821da177e4SLinus Torvalds /* 1831da177e4SLinus Torvalds * Singly-linked Tail queue functions. 1841da177e4SLinus Torvalds */ 1851da177e4SLinus Torvalds #define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) 1861da177e4SLinus Torvalds 1871da177e4SLinus Torvalds #define STAILQ_FIRST(head) ((head)->stqh_first) 1881da177e4SLinus Torvalds 1891da177e4SLinus Torvalds #define STAILQ_FOREACH(var, head, field) \ 1901da177e4SLinus Torvalds for((var) = STAILQ_FIRST((head)); \ 1911da177e4SLinus Torvalds (var); \ 1921da177e4SLinus Torvalds (var) = STAILQ_NEXT((var), field)) 1931da177e4SLinus Torvalds 1941da177e4SLinus Torvalds #define STAILQ_INIT(head) do { \ 1951da177e4SLinus Torvalds STAILQ_FIRST((head)) = NULL; \ 1961da177e4SLinus Torvalds (head)->stqh_last = &STAILQ_FIRST((head)); \ 1971da177e4SLinus Torvalds } while (0) 1981da177e4SLinus Torvalds 1991da177e4SLinus Torvalds #define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ 2001da177e4SLinus Torvalds if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\ 2011da177e4SLinus Torvalds (head)->stqh_last = &STAILQ_NEXT((elm), field); \ 2021da177e4SLinus Torvalds STAILQ_NEXT((tqelm), field) = (elm); \ 2031da177e4SLinus Torvalds } while (0) 2041da177e4SLinus Torvalds 2051da177e4SLinus Torvalds #define STAILQ_INSERT_HEAD(head, elm, field) do { \ 2061da177e4SLinus Torvalds if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \ 2071da177e4SLinus Torvalds (head)->stqh_last = &STAILQ_NEXT((elm), field); \ 2081da177e4SLinus Torvalds STAILQ_FIRST((head)) = (elm); \ 2091da177e4SLinus Torvalds } while (0) 2101da177e4SLinus Torvalds 2111da177e4SLinus Torvalds #define STAILQ_INSERT_TAIL(head, elm, field) do { \ 2121da177e4SLinus Torvalds STAILQ_NEXT((elm), field) = NULL; \ 2131da177e4SLinus Torvalds STAILQ_LAST((head)) = (elm); \ 2141da177e4SLinus Torvalds (head)->stqh_last = &STAILQ_NEXT((elm), field); \ 2151da177e4SLinus Torvalds } while (0) 2161da177e4SLinus Torvalds 2171da177e4SLinus Torvalds #define STAILQ_LAST(head) (*(head)->stqh_last) 2181da177e4SLinus Torvalds 2191da177e4SLinus Torvalds #define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) 2201da177e4SLinus Torvalds 2211da177e4SLinus Torvalds #define STAILQ_REMOVE(head, elm, type, field) do { \ 2221da177e4SLinus Torvalds if (STAILQ_FIRST((head)) == (elm)) { \ 2231da177e4SLinus Torvalds STAILQ_REMOVE_HEAD(head, field); \ 2241da177e4SLinus Torvalds } \ 2251da177e4SLinus Torvalds else { \ 2261da177e4SLinus Torvalds struct type *curelm = STAILQ_FIRST((head)); \ 2271da177e4SLinus Torvalds while (STAILQ_NEXT(curelm, field) != (elm)) \ 2281da177e4SLinus Torvalds curelm = STAILQ_NEXT(curelm, field); \ 2291da177e4SLinus Torvalds if ((STAILQ_NEXT(curelm, field) = \ 2301da177e4SLinus Torvalds STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\ 2311da177e4SLinus Torvalds (head)->stqh_last = &STAILQ_NEXT((curelm), field);\ 2321da177e4SLinus Torvalds } \ 2331da177e4SLinus Torvalds } while (0) 2341da177e4SLinus Torvalds 2351da177e4SLinus Torvalds #define STAILQ_REMOVE_HEAD(head, field) do { \ 2361da177e4SLinus Torvalds if ((STAILQ_FIRST((head)) = \ 2371da177e4SLinus Torvalds STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \ 2381da177e4SLinus Torvalds (head)->stqh_last = &STAILQ_FIRST((head)); \ 2391da177e4SLinus Torvalds } while (0) 2401da177e4SLinus Torvalds 2411da177e4SLinus Torvalds #define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \ 2421da177e4SLinus Torvalds if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \ 2431da177e4SLinus Torvalds (head)->stqh_last = &STAILQ_FIRST((head)); \ 2441da177e4SLinus Torvalds } while (0) 2451da177e4SLinus Torvalds 2461da177e4SLinus Torvalds /* 2471da177e4SLinus Torvalds * List declarations. 2481da177e4SLinus Torvalds */ 249*e594a178SMichal Marek #define BSD_LIST_HEAD(name, type) \ 2501da177e4SLinus Torvalds struct name { \ 2511da177e4SLinus Torvalds struct type *lh_first; /* first element */ \ 2521da177e4SLinus Torvalds } 2531da177e4SLinus Torvalds 2541da177e4SLinus Torvalds #define LIST_HEAD_INITIALIZER(head) \ 2551da177e4SLinus Torvalds { NULL } 2561da177e4SLinus Torvalds 2571da177e4SLinus Torvalds #define LIST_ENTRY(type) \ 2581da177e4SLinus Torvalds struct { \ 2591da177e4SLinus Torvalds struct type *le_next; /* next element */ \ 2601da177e4SLinus Torvalds struct type **le_prev; /* address of previous next element */ \ 2611da177e4SLinus Torvalds } 2621da177e4SLinus Torvalds 2631da177e4SLinus Torvalds /* 2641da177e4SLinus Torvalds * List functions. 2651da177e4SLinus Torvalds */ 2661da177e4SLinus Torvalds 2671da177e4SLinus Torvalds #define LIST_EMPTY(head) ((head)->lh_first == NULL) 2681da177e4SLinus Torvalds 2691da177e4SLinus Torvalds #define LIST_FIRST(head) ((head)->lh_first) 2701da177e4SLinus Torvalds 2711da177e4SLinus Torvalds #define LIST_FOREACH(var, head, field) \ 2721da177e4SLinus Torvalds for ((var) = LIST_FIRST((head)); \ 2731da177e4SLinus Torvalds (var); \ 2741da177e4SLinus Torvalds (var) = LIST_NEXT((var), field)) 2751da177e4SLinus Torvalds 2761da177e4SLinus Torvalds #define LIST_INIT(head) do { \ 2771da177e4SLinus Torvalds LIST_FIRST((head)) = NULL; \ 2781da177e4SLinus Torvalds } while (0) 2791da177e4SLinus Torvalds 2801da177e4SLinus Torvalds #define LIST_INSERT_AFTER(listelm, elm, field) do { \ 2811da177e4SLinus Torvalds if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\ 2821da177e4SLinus Torvalds LIST_NEXT((listelm), field)->field.le_prev = \ 2831da177e4SLinus Torvalds &LIST_NEXT((elm), field); \ 2841da177e4SLinus Torvalds LIST_NEXT((listelm), field) = (elm); \ 2851da177e4SLinus Torvalds (elm)->field.le_prev = &LIST_NEXT((listelm), field); \ 2861da177e4SLinus Torvalds } while (0) 2871da177e4SLinus Torvalds 2881da177e4SLinus Torvalds #define LIST_INSERT_BEFORE(listelm, elm, field) do { \ 2891da177e4SLinus Torvalds (elm)->field.le_prev = (listelm)->field.le_prev; \ 2901da177e4SLinus Torvalds LIST_NEXT((elm), field) = (listelm); \ 2911da177e4SLinus Torvalds *(listelm)->field.le_prev = (elm); \ 2921da177e4SLinus Torvalds (listelm)->field.le_prev = &LIST_NEXT((elm), field); \ 2931da177e4SLinus Torvalds } while (0) 2941da177e4SLinus Torvalds 2951da177e4SLinus Torvalds #define LIST_INSERT_HEAD(head, elm, field) do { \ 2961da177e4SLinus Torvalds if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ 2971da177e4SLinus Torvalds LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\ 2981da177e4SLinus Torvalds LIST_FIRST((head)) = (elm); \ 2991da177e4SLinus Torvalds (elm)->field.le_prev = &LIST_FIRST((head)); \ 3001da177e4SLinus Torvalds } while (0) 3011da177e4SLinus Torvalds 3021da177e4SLinus Torvalds #define LIST_NEXT(elm, field) ((elm)->field.le_next) 3031da177e4SLinus Torvalds 3041da177e4SLinus Torvalds #define LIST_REMOVE(elm, field) do { \ 3051da177e4SLinus Torvalds if (LIST_NEXT((elm), field) != NULL) \ 3061da177e4SLinus Torvalds LIST_NEXT((elm), field)->field.le_prev = \ 3071da177e4SLinus Torvalds (elm)->field.le_prev; \ 3081da177e4SLinus Torvalds *(elm)->field.le_prev = LIST_NEXT((elm), field); \ 3091da177e4SLinus Torvalds } while (0) 3101da177e4SLinus Torvalds 3111da177e4SLinus Torvalds /* 3121da177e4SLinus Torvalds * Tail queue declarations. 3131da177e4SLinus Torvalds */ 3141da177e4SLinus Torvalds #define TAILQ_HEAD(name, type) \ 3151da177e4SLinus Torvalds struct name { \ 3161da177e4SLinus Torvalds struct type *tqh_first; /* first element */ \ 3171da177e4SLinus Torvalds struct type **tqh_last; /* addr of last next element */ \ 3181da177e4SLinus Torvalds } 3191da177e4SLinus Torvalds 3201da177e4SLinus Torvalds #define TAILQ_HEAD_INITIALIZER(head) \ 3211da177e4SLinus Torvalds { NULL, &(head).tqh_first } 3221da177e4SLinus Torvalds 3231da177e4SLinus Torvalds #define TAILQ_ENTRY(type) \ 3241da177e4SLinus Torvalds struct { \ 3251da177e4SLinus Torvalds struct type *tqe_next; /* next element */ \ 3261da177e4SLinus Torvalds struct type **tqe_prev; /* address of previous next element */ \ 3271da177e4SLinus Torvalds } 3281da177e4SLinus Torvalds 3291da177e4SLinus Torvalds /* 3301da177e4SLinus Torvalds * Tail queue functions. 3311da177e4SLinus Torvalds */ 3321da177e4SLinus Torvalds #define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) 3331da177e4SLinus Torvalds 3341da177e4SLinus Torvalds #define TAILQ_FIRST(head) ((head)->tqh_first) 3351da177e4SLinus Torvalds 3361da177e4SLinus Torvalds #define TAILQ_FOREACH(var, head, field) \ 3371da177e4SLinus Torvalds for ((var) = TAILQ_FIRST((head)); \ 3381da177e4SLinus Torvalds (var); \ 3391da177e4SLinus Torvalds (var) = TAILQ_NEXT((var), field)) 3401da177e4SLinus Torvalds 3411da177e4SLinus Torvalds #define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ 3421da177e4SLinus Torvalds for ((var) = TAILQ_LAST((head), headname); \ 3431da177e4SLinus Torvalds (var); \ 3441da177e4SLinus Torvalds (var) = TAILQ_PREV((var), headname, field)) 3451da177e4SLinus Torvalds 3461da177e4SLinus Torvalds #define TAILQ_INIT(head) do { \ 3471da177e4SLinus Torvalds TAILQ_FIRST((head)) = NULL; \ 3481da177e4SLinus Torvalds (head)->tqh_last = &TAILQ_FIRST((head)); \ 3491da177e4SLinus Torvalds } while (0) 3501da177e4SLinus Torvalds 3511da177e4SLinus Torvalds #define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ 3521da177e4SLinus Torvalds if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\ 3531da177e4SLinus Torvalds TAILQ_NEXT((elm), field)->field.tqe_prev = \ 3541da177e4SLinus Torvalds &TAILQ_NEXT((elm), field); \ 3551da177e4SLinus Torvalds else \ 3561da177e4SLinus Torvalds (head)->tqh_last = &TAILQ_NEXT((elm), field); \ 3571da177e4SLinus Torvalds TAILQ_NEXT((listelm), field) = (elm); \ 3581da177e4SLinus Torvalds (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \ 3591da177e4SLinus Torvalds } while (0) 3601da177e4SLinus Torvalds 3611da177e4SLinus Torvalds #define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ 3621da177e4SLinus Torvalds (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ 3631da177e4SLinus Torvalds TAILQ_NEXT((elm), field) = (listelm); \ 3641da177e4SLinus Torvalds *(listelm)->field.tqe_prev = (elm); \ 3651da177e4SLinus Torvalds (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \ 3661da177e4SLinus Torvalds } while (0) 3671da177e4SLinus Torvalds 3681da177e4SLinus Torvalds #define TAILQ_INSERT_HEAD(head, elm, field) do { \ 3691da177e4SLinus Torvalds if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \ 3701da177e4SLinus Torvalds TAILQ_FIRST((head))->field.tqe_prev = \ 3711da177e4SLinus Torvalds &TAILQ_NEXT((elm), field); \ 3721da177e4SLinus Torvalds else \ 3731da177e4SLinus Torvalds (head)->tqh_last = &TAILQ_NEXT((elm), field); \ 3741da177e4SLinus Torvalds TAILQ_FIRST((head)) = (elm); \ 3751da177e4SLinus Torvalds (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \ 3761da177e4SLinus Torvalds } while (0) 3771da177e4SLinus Torvalds 3781da177e4SLinus Torvalds #define TAILQ_INSERT_TAIL(head, elm, field) do { \ 3791da177e4SLinus Torvalds TAILQ_NEXT((elm), field) = NULL; \ 3801da177e4SLinus Torvalds (elm)->field.tqe_prev = (head)->tqh_last; \ 3811da177e4SLinus Torvalds *(head)->tqh_last = (elm); \ 3821da177e4SLinus Torvalds (head)->tqh_last = &TAILQ_NEXT((elm), field); \ 3831da177e4SLinus Torvalds } while (0) 3841da177e4SLinus Torvalds 3851da177e4SLinus Torvalds #define TAILQ_LAST(head, headname) \ 3861da177e4SLinus Torvalds (*(((struct headname *)((head)->tqh_last))->tqh_last)) 3871da177e4SLinus Torvalds 3881da177e4SLinus Torvalds #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) 3891da177e4SLinus Torvalds 3901da177e4SLinus Torvalds #define TAILQ_PREV(elm, headname, field) \ 3911da177e4SLinus Torvalds (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) 3921da177e4SLinus Torvalds 3931da177e4SLinus Torvalds #define TAILQ_REMOVE(head, elm, field) do { \ 3941da177e4SLinus Torvalds if ((TAILQ_NEXT((elm), field)) != NULL) \ 3951da177e4SLinus Torvalds TAILQ_NEXT((elm), field)->field.tqe_prev = \ 3961da177e4SLinus Torvalds (elm)->field.tqe_prev; \ 3971da177e4SLinus Torvalds else \ 3981da177e4SLinus Torvalds (head)->tqh_last = (elm)->field.tqe_prev; \ 3991da177e4SLinus Torvalds *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ 4001da177e4SLinus Torvalds } while (0) 4011da177e4SLinus Torvalds 4021da177e4SLinus Torvalds /* 4031da177e4SLinus Torvalds * Circular queue declarations. 4041da177e4SLinus Torvalds */ 4051da177e4SLinus Torvalds #define CIRCLEQ_HEAD(name, type) \ 4061da177e4SLinus Torvalds struct name { \ 4071da177e4SLinus Torvalds struct type *cqh_first; /* first element */ \ 4081da177e4SLinus Torvalds struct type *cqh_last; /* last element */ \ 4091da177e4SLinus Torvalds } 4101da177e4SLinus Torvalds 4111da177e4SLinus Torvalds #define CIRCLEQ_HEAD_INITIALIZER(head) \ 4121da177e4SLinus Torvalds { (void *)&(head), (void *)&(head) } 4131da177e4SLinus Torvalds 4141da177e4SLinus Torvalds #define CIRCLEQ_ENTRY(type) \ 4151da177e4SLinus Torvalds struct { \ 4161da177e4SLinus Torvalds struct type *cqe_next; /* next element */ \ 4171da177e4SLinus Torvalds struct type *cqe_prev; /* previous element */ \ 4181da177e4SLinus Torvalds } 4191da177e4SLinus Torvalds 4201da177e4SLinus Torvalds /* 4211da177e4SLinus Torvalds * Circular queue functions. 4221da177e4SLinus Torvalds */ 4231da177e4SLinus Torvalds #define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head)) 4241da177e4SLinus Torvalds 4251da177e4SLinus Torvalds #define CIRCLEQ_FIRST(head) ((head)->cqh_first) 4261da177e4SLinus Torvalds 4271da177e4SLinus Torvalds #define CIRCLEQ_FOREACH(var, head, field) \ 4281da177e4SLinus Torvalds for ((var) = CIRCLEQ_FIRST((head)); \ 4291da177e4SLinus Torvalds (var) != (void *)(head); \ 4301da177e4SLinus Torvalds (var) = CIRCLEQ_NEXT((var), field)) 4311da177e4SLinus Torvalds 4321da177e4SLinus Torvalds #define CIRCLEQ_FOREACH_REVERSE(var, head, field) \ 4331da177e4SLinus Torvalds for ((var) = CIRCLEQ_LAST((head)); \ 4341da177e4SLinus Torvalds (var) != (void *)(head); \ 4351da177e4SLinus Torvalds (var) = CIRCLEQ_PREV((var), field)) 4361da177e4SLinus Torvalds 4371da177e4SLinus Torvalds #define CIRCLEQ_INIT(head) do { \ 4381da177e4SLinus Torvalds CIRCLEQ_FIRST((head)) = (void *)(head); \ 4391da177e4SLinus Torvalds CIRCLEQ_LAST((head)) = (void *)(head); \ 4401da177e4SLinus Torvalds } while (0) 4411da177e4SLinus Torvalds 4421da177e4SLinus Torvalds #define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ 4431da177e4SLinus Torvalds CIRCLEQ_NEXT((elm), field) = CIRCLEQ_NEXT((listelm), field); \ 4441da177e4SLinus Torvalds CIRCLEQ_PREV((elm), field) = (listelm); \ 4451da177e4SLinus Torvalds if (CIRCLEQ_NEXT((listelm), field) == (void *)(head)) \ 4461da177e4SLinus Torvalds CIRCLEQ_LAST((head)) = (elm); \ 4471da177e4SLinus Torvalds else \ 4481da177e4SLinus Torvalds CIRCLEQ_PREV(CIRCLEQ_NEXT((listelm), field), field) = (elm);\ 4491da177e4SLinus Torvalds CIRCLEQ_NEXT((listelm), field) = (elm); \ 4501da177e4SLinus Torvalds } while (0) 4511da177e4SLinus Torvalds 4521da177e4SLinus Torvalds #define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ 4531da177e4SLinus Torvalds CIRCLEQ_NEXT((elm), field) = (listelm); \ 4541da177e4SLinus Torvalds CIRCLEQ_PREV((elm), field) = CIRCLEQ_PREV((listelm), field); \ 4551da177e4SLinus Torvalds if (CIRCLEQ_PREV((listelm), field) == (void *)(head)) \ 4561da177e4SLinus Torvalds CIRCLEQ_FIRST((head)) = (elm); \ 4571da177e4SLinus Torvalds else \ 4581da177e4SLinus Torvalds CIRCLEQ_NEXT(CIRCLEQ_PREV((listelm), field), field) = (elm);\ 4591da177e4SLinus Torvalds CIRCLEQ_PREV((listelm), field) = (elm); \ 4601da177e4SLinus Torvalds } while (0) 4611da177e4SLinus Torvalds 4621da177e4SLinus Torvalds #define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ 4631da177e4SLinus Torvalds CIRCLEQ_NEXT((elm), field) = CIRCLEQ_FIRST((head)); \ 4641da177e4SLinus Torvalds CIRCLEQ_PREV((elm), field) = (void *)(head); \ 4651da177e4SLinus Torvalds if (CIRCLEQ_LAST((head)) == (void *)(head)) \ 4661da177e4SLinus Torvalds CIRCLEQ_LAST((head)) = (elm); \ 4671da177e4SLinus Torvalds else \ 4681da177e4SLinus Torvalds CIRCLEQ_PREV(CIRCLEQ_FIRST((head)), field) = (elm); \ 4691da177e4SLinus Torvalds CIRCLEQ_FIRST((head)) = (elm); \ 4701da177e4SLinus Torvalds } while (0) 4711da177e4SLinus Torvalds 4721da177e4SLinus Torvalds #define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ 4731da177e4SLinus Torvalds CIRCLEQ_NEXT((elm), field) = (void *)(head); \ 4741da177e4SLinus Torvalds CIRCLEQ_PREV((elm), field) = CIRCLEQ_LAST((head)); \ 4751da177e4SLinus Torvalds if (CIRCLEQ_FIRST((head)) == (void *)(head)) \ 4761da177e4SLinus Torvalds CIRCLEQ_FIRST((head)) = (elm); \ 4771da177e4SLinus Torvalds else \ 4781da177e4SLinus Torvalds CIRCLEQ_NEXT(CIRCLEQ_LAST((head)), field) = (elm); \ 4791da177e4SLinus Torvalds CIRCLEQ_LAST((head)) = (elm); \ 4801da177e4SLinus Torvalds } while (0) 4811da177e4SLinus Torvalds 4821da177e4SLinus Torvalds #define CIRCLEQ_LAST(head) ((head)->cqh_last) 4831da177e4SLinus Torvalds 4841da177e4SLinus Torvalds #define CIRCLEQ_NEXT(elm,field) ((elm)->field.cqe_next) 4851da177e4SLinus Torvalds 4861da177e4SLinus Torvalds #define CIRCLEQ_PREV(elm,field) ((elm)->field.cqe_prev) 4871da177e4SLinus Torvalds 4881da177e4SLinus Torvalds #define CIRCLEQ_REMOVE(head, elm, field) do { \ 4891da177e4SLinus Torvalds if (CIRCLEQ_NEXT((elm), field) == (void *)(head)) \ 4901da177e4SLinus Torvalds CIRCLEQ_LAST((head)) = CIRCLEQ_PREV((elm), field); \ 4911da177e4SLinus Torvalds else \ 4921da177e4SLinus Torvalds CIRCLEQ_PREV(CIRCLEQ_NEXT((elm), field), field) = \ 4931da177e4SLinus Torvalds CIRCLEQ_PREV((elm), field); \ 4941da177e4SLinus Torvalds if (CIRCLEQ_PREV((elm), field) == (void *)(head)) \ 4951da177e4SLinus Torvalds CIRCLEQ_FIRST((head)) = CIRCLEQ_NEXT((elm), field); \ 4961da177e4SLinus Torvalds else \ 4971da177e4SLinus Torvalds CIRCLEQ_NEXT(CIRCLEQ_PREV((elm), field), field) = \ 4981da177e4SLinus Torvalds CIRCLEQ_NEXT((elm), field); \ 4991da177e4SLinus Torvalds } while (0) 5001da177e4SLinus Torvalds 5011da177e4SLinus Torvalds #endif /* !_SYS_QUEUE_H_ */ 502