1d74d50a8SDag-Erling Smørgrav /* $OpenBSD: queue.h,v 1.45 2018/07/12 14:22:54 sashan Exp $ */ 24b17dab0SDag-Erling Smørgrav /* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */ 34b17dab0SDag-Erling Smørgrav 44b17dab0SDag-Erling Smørgrav /* 54b17dab0SDag-Erling Smørgrav * Copyright (c) 1991, 1993 64b17dab0SDag-Erling Smørgrav * The Regents of the University of California. All rights reserved. 74b17dab0SDag-Erling Smørgrav * 84b17dab0SDag-Erling Smørgrav * Redistribution and use in source and binary forms, with or without 94b17dab0SDag-Erling Smørgrav * modification, are permitted provided that the following conditions 104b17dab0SDag-Erling Smørgrav * are met: 114b17dab0SDag-Erling Smørgrav * 1. Redistributions of source code must retain the above copyright 124b17dab0SDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer. 134b17dab0SDag-Erling Smørgrav * 2. Redistributions in binary form must reproduce the above copyright 144b17dab0SDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer in the 154b17dab0SDag-Erling Smørgrav * documentation and/or other materials provided with the distribution. 16d95e11bfSDag-Erling Smørgrav * 3. Neither the name of the University nor the names of its contributors 174b17dab0SDag-Erling Smørgrav * may be used to endorse or promote products derived from this software 184b17dab0SDag-Erling Smørgrav * without specific prior written permission. 194b17dab0SDag-Erling Smørgrav * 204b17dab0SDag-Erling Smørgrav * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 214b17dab0SDag-Erling Smørgrav * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 224b17dab0SDag-Erling Smørgrav * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 234b17dab0SDag-Erling Smørgrav * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 244b17dab0SDag-Erling Smørgrav * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 254b17dab0SDag-Erling Smørgrav * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 264b17dab0SDag-Erling Smørgrav * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 274b17dab0SDag-Erling Smørgrav * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 284b17dab0SDag-Erling Smørgrav * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 294b17dab0SDag-Erling Smørgrav * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 304b17dab0SDag-Erling Smørgrav * SUCH DAMAGE. 314b17dab0SDag-Erling Smørgrav * 324b17dab0SDag-Erling Smørgrav * @(#)queue.h 8.5 (Berkeley) 8/20/94 334b17dab0SDag-Erling Smørgrav */ 344b17dab0SDag-Erling Smørgrav 35*021d409fSDag-Erling Smørgrav /* OPENBSD ORIGINAL: sys/sys/queue.h */ 36*021d409fSDag-Erling Smørgrav 374b17dab0SDag-Erling Smørgrav #ifndef _FAKE_QUEUE_H_ 384b17dab0SDag-Erling Smørgrav #define _FAKE_QUEUE_H_ 394b17dab0SDag-Erling Smørgrav 404b17dab0SDag-Erling Smørgrav /* 41d74d50a8SDag-Erling Smørgrav * Require for OS/X and other platforms that have old/broken/incomplete 42d74d50a8SDag-Erling Smørgrav * <sys/queue.h>. 434b17dab0SDag-Erling Smørgrav */ 444b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_EMPTY 454b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_END 464b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_ENTRY 47d74d50a8SDag-Erling Smørgrav #undef CIRCLEQ_FIRST 484b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_FOREACH 494b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_FOREACH_REVERSE 504b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_HEAD 514b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_HEAD_INITIALIZER 524b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_INIT 534b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_INSERT_AFTER 544b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_INSERT_BEFORE 554b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_INSERT_HEAD 564b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_INSERT_TAIL 574b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_LAST 58d74d50a8SDag-Erling Smørgrav #undef CIRCLEQ_NEXT 594b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_PREV 604b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_REMOVE 614b17dab0SDag-Erling Smørgrav #undef CIRCLEQ_REPLACE 624b17dab0SDag-Erling Smørgrav #undef LIST_EMPTY 634b17dab0SDag-Erling Smørgrav #undef LIST_END 644b17dab0SDag-Erling Smørgrav #undef LIST_ENTRY 654b17dab0SDag-Erling Smørgrav #undef LIST_FIRST 664b17dab0SDag-Erling Smørgrav #undef LIST_FOREACH 674b17dab0SDag-Erling Smørgrav #undef LIST_FOREACH_SAFE 684b17dab0SDag-Erling Smørgrav #undef LIST_HEAD 694b17dab0SDag-Erling Smørgrav #undef LIST_HEAD_INITIALIZER 704b17dab0SDag-Erling Smørgrav #undef LIST_INIT 714b17dab0SDag-Erling Smørgrav #undef LIST_INSERT_AFTER 724b17dab0SDag-Erling Smørgrav #undef LIST_INSERT_BEFORE 734b17dab0SDag-Erling Smørgrav #undef LIST_INSERT_HEAD 744b17dab0SDag-Erling Smørgrav #undef LIST_NEXT 754b17dab0SDag-Erling Smørgrav #undef LIST_REMOVE 764b17dab0SDag-Erling Smørgrav #undef LIST_REPLACE 774b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_CONCAT 784b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_EMPTY 794b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_END 804b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_ENTRY 814b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_FIRST 824b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_FOREACH 834b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_FOREACH_SAFE 844b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_HEAD 854b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_HEAD_INITIALIZER 864b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_INIT 874b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_INSERT_AFTER 884b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_INSERT_HEAD 894b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_INSERT_TAIL 904b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_NEXT 914b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_REMOVE_AFTER 924b17dab0SDag-Erling Smørgrav #undef SIMPLEQ_REMOVE_HEAD 934b17dab0SDag-Erling Smørgrav #undef SLIST_EMPTY 944b17dab0SDag-Erling Smørgrav #undef SLIST_END 954b17dab0SDag-Erling Smørgrav #undef SLIST_ENTRY 964b17dab0SDag-Erling Smørgrav #undef SLIST_FIRST 974b17dab0SDag-Erling Smørgrav #undef SLIST_FOREACH 984b17dab0SDag-Erling Smørgrav #undef SLIST_FOREACH_PREVPTR 994b17dab0SDag-Erling Smørgrav #undef SLIST_FOREACH_SAFE 1004b17dab0SDag-Erling Smørgrav #undef SLIST_HEAD 1014b17dab0SDag-Erling Smørgrav #undef SLIST_HEAD_INITIALIZER 1024b17dab0SDag-Erling Smørgrav #undef SLIST_INIT 1034b17dab0SDag-Erling Smørgrav #undef SLIST_INSERT_AFTER 1044b17dab0SDag-Erling Smørgrav #undef SLIST_INSERT_HEAD 1054b17dab0SDag-Erling Smørgrav #undef SLIST_NEXT 1064b17dab0SDag-Erling Smørgrav #undef SLIST_REMOVE 1074b17dab0SDag-Erling Smørgrav #undef SLIST_REMOVE_AFTER 1084b17dab0SDag-Erling Smørgrav #undef SLIST_REMOVE_HEAD 1094b17dab0SDag-Erling Smørgrav #undef SLIST_REMOVE_NEXT 1104b17dab0SDag-Erling Smørgrav #undef TAILQ_CONCAT 1114b17dab0SDag-Erling Smørgrav #undef TAILQ_EMPTY 1124b17dab0SDag-Erling Smørgrav #undef TAILQ_END 1134b17dab0SDag-Erling Smørgrav #undef TAILQ_ENTRY 1144b17dab0SDag-Erling Smørgrav #undef TAILQ_FIRST 1154b17dab0SDag-Erling Smørgrav #undef TAILQ_FOREACH 1164b17dab0SDag-Erling Smørgrav #undef TAILQ_FOREACH_REVERSE 1174b17dab0SDag-Erling Smørgrav #undef TAILQ_FOREACH_REVERSE_SAFE 1184b17dab0SDag-Erling Smørgrav #undef TAILQ_FOREACH_SAFE 1194b17dab0SDag-Erling Smørgrav #undef TAILQ_HEAD 1204b17dab0SDag-Erling Smørgrav #undef TAILQ_HEAD_INITIALIZER 1214b17dab0SDag-Erling Smørgrav #undef TAILQ_INIT 1224b17dab0SDag-Erling Smørgrav #undef TAILQ_INSERT_AFTER 1234b17dab0SDag-Erling Smørgrav #undef TAILQ_INSERT_BEFORE 1244b17dab0SDag-Erling Smørgrav #undef TAILQ_INSERT_HEAD 1254b17dab0SDag-Erling Smørgrav #undef TAILQ_INSERT_TAIL 1264b17dab0SDag-Erling Smørgrav #undef TAILQ_LAST 1274b17dab0SDag-Erling Smørgrav #undef TAILQ_NEXT 1284b17dab0SDag-Erling Smørgrav #undef TAILQ_PREV 1294b17dab0SDag-Erling Smørgrav #undef TAILQ_REMOVE 1304b17dab0SDag-Erling Smørgrav #undef TAILQ_REPLACE 1314b17dab0SDag-Erling Smørgrav 1324b17dab0SDag-Erling Smørgrav /* 1334b17dab0SDag-Erling Smørgrav * This file defines five types of data structures: singly-linked lists, 1344b17dab0SDag-Erling Smørgrav * lists, simple queues, tail queues and XOR simple queues. 1354b17dab0SDag-Erling Smørgrav * 1364b17dab0SDag-Erling Smørgrav * 1374b17dab0SDag-Erling Smørgrav * A singly-linked list is headed by a single forward pointer. The elements 1384b17dab0SDag-Erling Smørgrav * are singly linked for minimum space and pointer manipulation overhead at 1394b17dab0SDag-Erling Smørgrav * the expense of O(n) removal for arbitrary elements. New elements can be 1404b17dab0SDag-Erling Smørgrav * added to the list after an existing element or at the head of the list. 1414b17dab0SDag-Erling Smørgrav * Elements being removed from the head of the list should use the explicit 1424b17dab0SDag-Erling Smørgrav * macro for this purpose for optimum efficiency. A singly-linked list may 1434b17dab0SDag-Erling Smørgrav * only be traversed in the forward direction. Singly-linked lists are ideal 1444b17dab0SDag-Erling Smørgrav * for applications with large datasets and few or no removals or for 1454b17dab0SDag-Erling Smørgrav * implementing a LIFO queue. 1464b17dab0SDag-Erling Smørgrav * 1474b17dab0SDag-Erling Smørgrav * A list is headed by a single forward pointer (or an array of forward 1484b17dab0SDag-Erling Smørgrav * pointers for a hash table header). The elements are doubly linked 1494b17dab0SDag-Erling Smørgrav * so that an arbitrary element can be removed without a need to 1504b17dab0SDag-Erling Smørgrav * traverse the list. New elements can be added to the list before 1514b17dab0SDag-Erling Smørgrav * or after an existing element or at the head of the list. A list 1524b17dab0SDag-Erling Smørgrav * may only be traversed in the forward direction. 1534b17dab0SDag-Erling Smørgrav * 1544b17dab0SDag-Erling Smørgrav * A simple queue is headed by a pair of pointers, one to the head of the 1554b17dab0SDag-Erling Smørgrav * list and the other to the tail of the list. The elements are singly 1564b17dab0SDag-Erling Smørgrav * linked to save space, so elements can only be removed from the 1574b17dab0SDag-Erling Smørgrav * head of the list. New elements can be added to the list before or after 1584b17dab0SDag-Erling Smørgrav * an existing element, at the head of the list, or at the end of the 1594b17dab0SDag-Erling Smørgrav * list. A simple queue may only be traversed in the forward direction. 1604b17dab0SDag-Erling Smørgrav * 1614b17dab0SDag-Erling Smørgrav * A tail queue is headed by a pair of pointers, one to the head of the 1624b17dab0SDag-Erling Smørgrav * list and the other to the tail of the list. The elements are doubly 1634b17dab0SDag-Erling Smørgrav * linked so that an arbitrary element can be removed without a need to 1644b17dab0SDag-Erling Smørgrav * traverse the list. New elements can be added to the list before or 1654b17dab0SDag-Erling Smørgrav * after an existing element, at the head of the list, or at the end of 1664b17dab0SDag-Erling Smørgrav * the list. A tail queue may be traversed in either direction. 1674b17dab0SDag-Erling Smørgrav * 1684b17dab0SDag-Erling Smørgrav * An XOR simple queue is used in the same way as a regular simple queue. 1694b17dab0SDag-Erling Smørgrav * The difference is that the head structure also includes a "cookie" that 1704b17dab0SDag-Erling Smørgrav * is XOR'd with the queue pointer (first, last or next) to generate the 1714b17dab0SDag-Erling Smørgrav * real pointer value. 1724b17dab0SDag-Erling Smørgrav * 1734b17dab0SDag-Erling Smørgrav * For details on the use of these macros, see the queue(3) manual page. 1744b17dab0SDag-Erling Smørgrav */ 1754b17dab0SDag-Erling Smørgrav 1764b17dab0SDag-Erling Smørgrav #if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC)) 1774b17dab0SDag-Erling Smørgrav #define _Q_INVALID ((void *)-1) 1784b17dab0SDag-Erling Smørgrav #define _Q_INVALIDATE(a) (a) = _Q_INVALID 1794b17dab0SDag-Erling Smørgrav #else 1804b17dab0SDag-Erling Smørgrav #define _Q_INVALIDATE(a) 1814b17dab0SDag-Erling Smørgrav #endif 1824b17dab0SDag-Erling Smørgrav 1834b17dab0SDag-Erling Smørgrav /* 1844b17dab0SDag-Erling Smørgrav * Singly-linked List definitions. 1854b17dab0SDag-Erling Smørgrav */ 1864b17dab0SDag-Erling Smørgrav #define SLIST_HEAD(name, type) \ 1874b17dab0SDag-Erling Smørgrav struct name { \ 1884b17dab0SDag-Erling Smørgrav struct type *slh_first; /* first element */ \ 1894b17dab0SDag-Erling Smørgrav } 1904b17dab0SDag-Erling Smørgrav 1914b17dab0SDag-Erling Smørgrav #define SLIST_HEAD_INITIALIZER(head) \ 1924b17dab0SDag-Erling Smørgrav { NULL } 1934b17dab0SDag-Erling Smørgrav 1944b17dab0SDag-Erling Smørgrav #define SLIST_ENTRY(type) \ 1954b17dab0SDag-Erling Smørgrav struct { \ 1964b17dab0SDag-Erling Smørgrav struct type *sle_next; /* next element */ \ 1974b17dab0SDag-Erling Smørgrav } 1984b17dab0SDag-Erling Smørgrav 199d74d50a8SDag-Erling Smørgrav /* 200d74d50a8SDag-Erling Smørgrav * Singly-linked List access methods. 201d74d50a8SDag-Erling Smørgrav */ 202d74d50a8SDag-Erling Smørgrav #define SLIST_FIRST(head) ((head)->slh_first) 203d74d50a8SDag-Erling Smørgrav #define SLIST_END(head) NULL 2044b17dab0SDag-Erling Smørgrav #define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head)) 2054b17dab0SDag-Erling Smørgrav #define SLIST_NEXT(elm, field) ((elm)->field.sle_next) 2064b17dab0SDag-Erling Smørgrav 2074b17dab0SDag-Erling Smørgrav #define SLIST_FOREACH(var, head, field) \ 2084b17dab0SDag-Erling Smørgrav for((var) = SLIST_FIRST(head); \ 2094b17dab0SDag-Erling Smørgrav (var) != SLIST_END(head); \ 2104b17dab0SDag-Erling Smørgrav (var) = SLIST_NEXT(var, field)) 2114b17dab0SDag-Erling Smørgrav 2124b17dab0SDag-Erling Smørgrav #define SLIST_FOREACH_SAFE(var, head, field, tvar) \ 2134b17dab0SDag-Erling Smørgrav for ((var) = SLIST_FIRST(head); \ 2144b17dab0SDag-Erling Smørgrav (var) && ((tvar) = SLIST_NEXT(var, field), 1); \ 2154b17dab0SDag-Erling Smørgrav (var) = (tvar)) 2164b17dab0SDag-Erling Smørgrav 2174b17dab0SDag-Erling Smørgrav /* 2184b17dab0SDag-Erling Smørgrav * Singly-linked List functions. 2194b17dab0SDag-Erling Smørgrav */ 2204b17dab0SDag-Erling Smørgrav #define SLIST_INIT(head) { \ 221d74d50a8SDag-Erling Smørgrav SLIST_FIRST(head) = SLIST_END(head); \ 222d74d50a8SDag-Erling Smørgrav } 223d74d50a8SDag-Erling Smørgrav 224d74d50a8SDag-Erling Smørgrav #define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ 2254b17dab0SDag-Erling Smørgrav (elm)->field.sle_next = (slistelm)->field.sle_next; \ 2264b17dab0SDag-Erling Smørgrav (slistelm)->field.sle_next = (elm); \ 2274b17dab0SDag-Erling Smørgrav } while (0) 2284b17dab0SDag-Erling Smørgrav 2294b17dab0SDag-Erling Smørgrav #define SLIST_INSERT_HEAD(head, elm, field) do { \ 2304b17dab0SDag-Erling Smørgrav (elm)->field.sle_next = (head)->slh_first; \ 2314b17dab0SDag-Erling Smørgrav (head)->slh_first = (elm); \ 2324b17dab0SDag-Erling Smørgrav } while (0) 2334b17dab0SDag-Erling Smørgrav 2344b17dab0SDag-Erling Smørgrav #define SLIST_REMOVE_AFTER(elm, field) do { \ 2354b17dab0SDag-Erling Smørgrav (elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \ 2364b17dab0SDag-Erling Smørgrav } while (0) 2374b17dab0SDag-Erling Smørgrav 2384b17dab0SDag-Erling Smørgrav #define SLIST_REMOVE_HEAD(head, field) do { \ 2394b17dab0SDag-Erling Smørgrav (head)->slh_first = (head)->slh_first->field.sle_next; \ 2404b17dab0SDag-Erling Smørgrav } while (0) 2414b17dab0SDag-Erling Smørgrav 2424b17dab0SDag-Erling Smørgrav #define SLIST_REMOVE(head, elm, type, field) do { \ 2434b17dab0SDag-Erling Smørgrav if ((head)->slh_first == (elm)) { \ 2444b17dab0SDag-Erling Smørgrav SLIST_REMOVE_HEAD((head), field); \ 2454b17dab0SDag-Erling Smørgrav } else { \ 2464b17dab0SDag-Erling Smørgrav struct type *curelm = (head)->slh_first; \ 2474b17dab0SDag-Erling Smørgrav \ 2484b17dab0SDag-Erling Smørgrav while (curelm->field.sle_next != (elm)) \ 2494b17dab0SDag-Erling Smørgrav curelm = curelm->field.sle_next; \ 2504b17dab0SDag-Erling Smørgrav curelm->field.sle_next = \ 2514b17dab0SDag-Erling Smørgrav curelm->field.sle_next->field.sle_next; \ 2524b17dab0SDag-Erling Smørgrav } \ 2534b17dab0SDag-Erling Smørgrav _Q_INVALIDATE((elm)->field.sle_next); \ 2544b17dab0SDag-Erling Smørgrav } while (0) 2554b17dab0SDag-Erling Smørgrav 2564b17dab0SDag-Erling Smørgrav /* 2574b17dab0SDag-Erling Smørgrav * List definitions. 2584b17dab0SDag-Erling Smørgrav */ 2594b17dab0SDag-Erling Smørgrav #define LIST_HEAD(name, type) \ 2604b17dab0SDag-Erling Smørgrav struct name { \ 2614b17dab0SDag-Erling Smørgrav struct type *lh_first; /* first element */ \ 2624b17dab0SDag-Erling Smørgrav } 2634b17dab0SDag-Erling Smørgrav 2644b17dab0SDag-Erling Smørgrav #define LIST_HEAD_INITIALIZER(head) \ 2654b17dab0SDag-Erling Smørgrav { NULL } 2664b17dab0SDag-Erling Smørgrav 2674b17dab0SDag-Erling Smørgrav #define LIST_ENTRY(type) \ 2684b17dab0SDag-Erling Smørgrav struct { \ 2694b17dab0SDag-Erling Smørgrav struct type *le_next; /* next element */ \ 2704b17dab0SDag-Erling Smørgrav struct type **le_prev; /* address of previous next element */ \ 2714b17dab0SDag-Erling Smørgrav } 2724b17dab0SDag-Erling Smørgrav 2734b17dab0SDag-Erling Smørgrav /* 2744b17dab0SDag-Erling Smørgrav * List access methods. 2754b17dab0SDag-Erling Smørgrav */ 2764b17dab0SDag-Erling Smørgrav #define LIST_FIRST(head) ((head)->lh_first) 2774b17dab0SDag-Erling Smørgrav #define LIST_END(head) NULL 2784b17dab0SDag-Erling Smørgrav #define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head)) 2794b17dab0SDag-Erling Smørgrav #define LIST_NEXT(elm, field) ((elm)->field.le_next) 2804b17dab0SDag-Erling Smørgrav 2814b17dab0SDag-Erling Smørgrav #define LIST_FOREACH(var, head, field) \ 2824b17dab0SDag-Erling Smørgrav for((var) = LIST_FIRST(head); \ 2834b17dab0SDag-Erling Smørgrav (var)!= LIST_END(head); \ 2844b17dab0SDag-Erling Smørgrav (var) = LIST_NEXT(var, field)) 2854b17dab0SDag-Erling Smørgrav 2864b17dab0SDag-Erling Smørgrav #define LIST_FOREACH_SAFE(var, head, field, tvar) \ 2874b17dab0SDag-Erling Smørgrav for ((var) = LIST_FIRST(head); \ 2884b17dab0SDag-Erling Smørgrav (var) && ((tvar) = LIST_NEXT(var, field), 1); \ 2894b17dab0SDag-Erling Smørgrav (var) = (tvar)) 2904b17dab0SDag-Erling Smørgrav 2914b17dab0SDag-Erling Smørgrav /* 2924b17dab0SDag-Erling Smørgrav * List functions. 2934b17dab0SDag-Erling Smørgrav */ 2944b17dab0SDag-Erling Smørgrav #define LIST_INIT(head) do { \ 2954b17dab0SDag-Erling Smørgrav LIST_FIRST(head) = LIST_END(head); \ 2964b17dab0SDag-Erling Smørgrav } while (0) 2974b17dab0SDag-Erling Smørgrav 2984b17dab0SDag-Erling Smørgrav #define LIST_INSERT_AFTER(listelm, elm, field) do { \ 2994b17dab0SDag-Erling Smørgrav if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ 3004b17dab0SDag-Erling Smørgrav (listelm)->field.le_next->field.le_prev = \ 3014b17dab0SDag-Erling Smørgrav &(elm)->field.le_next; \ 3024b17dab0SDag-Erling Smørgrav (listelm)->field.le_next = (elm); \ 3034b17dab0SDag-Erling Smørgrav (elm)->field.le_prev = &(listelm)->field.le_next; \ 3044b17dab0SDag-Erling Smørgrav } while (0) 3054b17dab0SDag-Erling Smørgrav 3064b17dab0SDag-Erling Smørgrav #define LIST_INSERT_BEFORE(listelm, elm, field) do { \ 3074b17dab0SDag-Erling Smørgrav (elm)->field.le_prev = (listelm)->field.le_prev; \ 3084b17dab0SDag-Erling Smørgrav (elm)->field.le_next = (listelm); \ 3094b17dab0SDag-Erling Smørgrav *(listelm)->field.le_prev = (elm); \ 3104b17dab0SDag-Erling Smørgrav (listelm)->field.le_prev = &(elm)->field.le_next; \ 3114b17dab0SDag-Erling Smørgrav } while (0) 3124b17dab0SDag-Erling Smørgrav 3134b17dab0SDag-Erling Smørgrav #define LIST_INSERT_HEAD(head, elm, field) do { \ 3144b17dab0SDag-Erling Smørgrav if (((elm)->field.le_next = (head)->lh_first) != NULL) \ 3154b17dab0SDag-Erling Smørgrav (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ 3164b17dab0SDag-Erling Smørgrav (head)->lh_first = (elm); \ 3174b17dab0SDag-Erling Smørgrav (elm)->field.le_prev = &(head)->lh_first; \ 3184b17dab0SDag-Erling Smørgrav } while (0) 3194b17dab0SDag-Erling Smørgrav 3204b17dab0SDag-Erling Smørgrav #define LIST_REMOVE(elm, field) do { \ 3214b17dab0SDag-Erling Smørgrav if ((elm)->field.le_next != NULL) \ 3224b17dab0SDag-Erling Smørgrav (elm)->field.le_next->field.le_prev = \ 3234b17dab0SDag-Erling Smørgrav (elm)->field.le_prev; \ 3244b17dab0SDag-Erling Smørgrav *(elm)->field.le_prev = (elm)->field.le_next; \ 3254b17dab0SDag-Erling Smørgrav _Q_INVALIDATE((elm)->field.le_prev); \ 3264b17dab0SDag-Erling Smørgrav _Q_INVALIDATE((elm)->field.le_next); \ 3274b17dab0SDag-Erling Smørgrav } while (0) 3284b17dab0SDag-Erling Smørgrav 3294b17dab0SDag-Erling Smørgrav #define LIST_REPLACE(elm, elm2, field) do { \ 3304b17dab0SDag-Erling Smørgrav if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \ 3314b17dab0SDag-Erling Smørgrav (elm2)->field.le_next->field.le_prev = \ 3324b17dab0SDag-Erling Smørgrav &(elm2)->field.le_next; \ 3334b17dab0SDag-Erling Smørgrav (elm2)->field.le_prev = (elm)->field.le_prev; \ 3344b17dab0SDag-Erling Smørgrav *(elm2)->field.le_prev = (elm2); \ 3354b17dab0SDag-Erling Smørgrav _Q_INVALIDATE((elm)->field.le_prev); \ 3364b17dab0SDag-Erling Smørgrav _Q_INVALIDATE((elm)->field.le_next); \ 3374b17dab0SDag-Erling Smørgrav } while (0) 3384b17dab0SDag-Erling Smørgrav 3394b17dab0SDag-Erling Smørgrav /* 3404b17dab0SDag-Erling Smørgrav * Simple queue definitions. 3414b17dab0SDag-Erling Smørgrav */ 3424b17dab0SDag-Erling Smørgrav #define SIMPLEQ_HEAD(name, type) \ 3434b17dab0SDag-Erling Smørgrav struct name { \ 3444b17dab0SDag-Erling Smørgrav struct type *sqh_first; /* first element */ \ 3454b17dab0SDag-Erling Smørgrav struct type **sqh_last; /* addr of last next element */ \ 3464b17dab0SDag-Erling Smørgrav } 3474b17dab0SDag-Erling Smørgrav 3484b17dab0SDag-Erling Smørgrav #define SIMPLEQ_HEAD_INITIALIZER(head) \ 3494b17dab0SDag-Erling Smørgrav { NULL, &(head).sqh_first } 3504b17dab0SDag-Erling Smørgrav 3514b17dab0SDag-Erling Smørgrav #define SIMPLEQ_ENTRY(type) \ 3524b17dab0SDag-Erling Smørgrav struct { \ 3534b17dab0SDag-Erling Smørgrav struct type *sqe_next; /* next element */ \ 3544b17dab0SDag-Erling Smørgrav } 3554b17dab0SDag-Erling Smørgrav 3564b17dab0SDag-Erling Smørgrav /* 3574b17dab0SDag-Erling Smørgrav * Simple queue access methods. 3584b17dab0SDag-Erling Smørgrav */ 3594b17dab0SDag-Erling Smørgrav #define SIMPLEQ_FIRST(head) ((head)->sqh_first) 3604b17dab0SDag-Erling Smørgrav #define SIMPLEQ_END(head) NULL 3614b17dab0SDag-Erling Smørgrav #define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head)) 3624b17dab0SDag-Erling Smørgrav #define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) 3634b17dab0SDag-Erling Smørgrav 3644b17dab0SDag-Erling Smørgrav #define SIMPLEQ_FOREACH(var, head, field) \ 3654b17dab0SDag-Erling Smørgrav for((var) = SIMPLEQ_FIRST(head); \ 3664b17dab0SDag-Erling Smørgrav (var) != SIMPLEQ_END(head); \ 3674b17dab0SDag-Erling Smørgrav (var) = SIMPLEQ_NEXT(var, field)) 3684b17dab0SDag-Erling Smørgrav 3694b17dab0SDag-Erling Smørgrav #define SIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \ 3704b17dab0SDag-Erling Smørgrav for ((var) = SIMPLEQ_FIRST(head); \ 3714b17dab0SDag-Erling Smørgrav (var) && ((tvar) = SIMPLEQ_NEXT(var, field), 1); \ 3724b17dab0SDag-Erling Smørgrav (var) = (tvar)) 3734b17dab0SDag-Erling Smørgrav 3744b17dab0SDag-Erling Smørgrav /* 3754b17dab0SDag-Erling Smørgrav * Simple queue functions. 3764b17dab0SDag-Erling Smørgrav */ 3774b17dab0SDag-Erling Smørgrav #define SIMPLEQ_INIT(head) do { \ 3784b17dab0SDag-Erling Smørgrav (head)->sqh_first = NULL; \ 3794b17dab0SDag-Erling Smørgrav (head)->sqh_last = &(head)->sqh_first; \ 3804b17dab0SDag-Erling Smørgrav } while (0) 3814b17dab0SDag-Erling Smørgrav 3824b17dab0SDag-Erling Smørgrav #define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \ 3834b17dab0SDag-Erling Smørgrav if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \ 3844b17dab0SDag-Erling Smørgrav (head)->sqh_last = &(elm)->field.sqe_next; \ 3854b17dab0SDag-Erling Smørgrav (head)->sqh_first = (elm); \ 3864b17dab0SDag-Erling Smørgrav } while (0) 3874b17dab0SDag-Erling Smørgrav 3884b17dab0SDag-Erling Smørgrav #define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \ 3894b17dab0SDag-Erling Smørgrav (elm)->field.sqe_next = NULL; \ 3904b17dab0SDag-Erling Smørgrav *(head)->sqh_last = (elm); \ 3914b17dab0SDag-Erling Smørgrav (head)->sqh_last = &(elm)->field.sqe_next; \ 3924b17dab0SDag-Erling Smørgrav } while (0) 3934b17dab0SDag-Erling Smørgrav 3944b17dab0SDag-Erling Smørgrav #define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ 3954b17dab0SDag-Erling Smørgrav if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\ 3964b17dab0SDag-Erling Smørgrav (head)->sqh_last = &(elm)->field.sqe_next; \ 3974b17dab0SDag-Erling Smørgrav (listelm)->field.sqe_next = (elm); \ 3984b17dab0SDag-Erling Smørgrav } while (0) 3994b17dab0SDag-Erling Smørgrav 4004b17dab0SDag-Erling Smørgrav #define SIMPLEQ_REMOVE_HEAD(head, field) do { \ 4014b17dab0SDag-Erling Smørgrav if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \ 4024b17dab0SDag-Erling Smørgrav (head)->sqh_last = &(head)->sqh_first; \ 4034b17dab0SDag-Erling Smørgrav } while (0) 4044b17dab0SDag-Erling Smørgrav 4054b17dab0SDag-Erling Smørgrav #define SIMPLEQ_REMOVE_AFTER(head, elm, field) do { \ 4064b17dab0SDag-Erling Smørgrav if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \ 4074b17dab0SDag-Erling Smørgrav == NULL) \ 4084b17dab0SDag-Erling Smørgrav (head)->sqh_last = &(elm)->field.sqe_next; \ 4094b17dab0SDag-Erling Smørgrav } while (0) 4104b17dab0SDag-Erling Smørgrav 4114b17dab0SDag-Erling Smørgrav #define SIMPLEQ_CONCAT(head1, head2) do { \ 4124b17dab0SDag-Erling Smørgrav if (!SIMPLEQ_EMPTY((head2))) { \ 4134b17dab0SDag-Erling Smørgrav *(head1)->sqh_last = (head2)->sqh_first; \ 414d74d50a8SDag-Erling Smørgrav (head1)->sqh_last = (head2)->sqh_last; \ 4154b17dab0SDag-Erling Smørgrav SIMPLEQ_INIT((head2)); \ 4164b17dab0SDag-Erling Smørgrav } \ 4174b17dab0SDag-Erling Smørgrav } while (0) 4184b17dab0SDag-Erling Smørgrav 4194b17dab0SDag-Erling Smørgrav /* 4204b17dab0SDag-Erling Smørgrav * XOR Simple queue definitions. 4214b17dab0SDag-Erling Smørgrav */ 4224b17dab0SDag-Erling Smørgrav #define XSIMPLEQ_HEAD(name, type) \ 4234b17dab0SDag-Erling Smørgrav struct name { \ 4244b17dab0SDag-Erling Smørgrav struct type *sqx_first; /* first element */ \ 4254b17dab0SDag-Erling Smørgrav struct type **sqx_last; /* addr of last next element */ \ 4264b17dab0SDag-Erling Smørgrav unsigned long sqx_cookie; \ 4274b17dab0SDag-Erling Smørgrav } 4284b17dab0SDag-Erling Smørgrav 4294b17dab0SDag-Erling Smørgrav #define XSIMPLEQ_ENTRY(type) \ 4304b17dab0SDag-Erling Smørgrav struct { \ 4314b17dab0SDag-Erling Smørgrav struct type *sqx_next; /* next element */ \ 4324b17dab0SDag-Erling Smørgrav } 4334b17dab0SDag-Erling Smørgrav 4344b17dab0SDag-Erling Smørgrav /* 4354b17dab0SDag-Erling Smørgrav * XOR Simple queue access methods. 4364b17dab0SDag-Erling Smørgrav */ 4374b17dab0SDag-Erling Smørgrav #define XSIMPLEQ_XOR(head, ptr) ((__typeof(ptr))((head)->sqx_cookie ^ \ 4384b17dab0SDag-Erling Smørgrav (unsigned long)(ptr))) 4394b17dab0SDag-Erling Smørgrav #define XSIMPLEQ_FIRST(head) XSIMPLEQ_XOR(head, ((head)->sqx_first)) 4404b17dab0SDag-Erling Smørgrav #define XSIMPLEQ_END(head) NULL 4414b17dab0SDag-Erling Smørgrav #define XSIMPLEQ_EMPTY(head) (XSIMPLEQ_FIRST(head) == XSIMPLEQ_END(head)) 4424b17dab0SDag-Erling Smørgrav #define XSIMPLEQ_NEXT(head, elm, field) XSIMPLEQ_XOR(head, ((elm)->field.sqx_next)) 4434b17dab0SDag-Erling Smørgrav 4444b17dab0SDag-Erling Smørgrav 4454b17dab0SDag-Erling Smørgrav #define XSIMPLEQ_FOREACH(var, head, field) \ 4464b17dab0SDag-Erling Smørgrav for ((var) = XSIMPLEQ_FIRST(head); \ 4474b17dab0SDag-Erling Smørgrav (var) != XSIMPLEQ_END(head); \ 4484b17dab0SDag-Erling Smørgrav (var) = XSIMPLEQ_NEXT(head, var, field)) 4494b17dab0SDag-Erling Smørgrav 4504b17dab0SDag-Erling Smørgrav #define XSIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \ 4514b17dab0SDag-Erling Smørgrav for ((var) = XSIMPLEQ_FIRST(head); \ 4524b17dab0SDag-Erling Smørgrav (var) && ((tvar) = XSIMPLEQ_NEXT(head, var, field), 1); \ 4534b17dab0SDag-Erling Smørgrav (var) = (tvar)) 4544b17dab0SDag-Erling Smørgrav 4554b17dab0SDag-Erling Smørgrav /* 4564b17dab0SDag-Erling Smørgrav * XOR Simple queue functions. 4574b17dab0SDag-Erling Smørgrav */ 4584b17dab0SDag-Erling Smørgrav #define XSIMPLEQ_INIT(head) do { \ 4594b17dab0SDag-Erling Smørgrav arc4random_buf(&(head)->sqx_cookie, sizeof((head)->sqx_cookie)); \ 4604b17dab0SDag-Erling Smørgrav (head)->sqx_first = XSIMPLEQ_XOR(head, NULL); \ 4614b17dab0SDag-Erling Smørgrav (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \ 4624b17dab0SDag-Erling Smørgrav } while (0) 4634b17dab0SDag-Erling Smørgrav 4644b17dab0SDag-Erling Smørgrav #define XSIMPLEQ_INSERT_HEAD(head, elm, field) do { \ 4654b17dab0SDag-Erling Smørgrav if (((elm)->field.sqx_next = (head)->sqx_first) == \ 4664b17dab0SDag-Erling Smørgrav XSIMPLEQ_XOR(head, NULL)) \ 4674b17dab0SDag-Erling Smørgrav (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \ 4684b17dab0SDag-Erling Smørgrav (head)->sqx_first = XSIMPLEQ_XOR(head, (elm)); \ 4694b17dab0SDag-Erling Smørgrav } while (0) 4704b17dab0SDag-Erling Smørgrav 4714b17dab0SDag-Erling Smørgrav #define XSIMPLEQ_INSERT_TAIL(head, elm, field) do { \ 4724b17dab0SDag-Erling Smørgrav (elm)->field.sqx_next = XSIMPLEQ_XOR(head, NULL); \ 4734b17dab0SDag-Erling Smørgrav *(XSIMPLEQ_XOR(head, (head)->sqx_last)) = XSIMPLEQ_XOR(head, (elm)); \ 4744b17dab0SDag-Erling Smørgrav (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \ 4754b17dab0SDag-Erling Smørgrav } while (0) 4764b17dab0SDag-Erling Smørgrav 4774b17dab0SDag-Erling Smørgrav #define XSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ 4784b17dab0SDag-Erling Smørgrav if (((elm)->field.sqx_next = (listelm)->field.sqx_next) == \ 4794b17dab0SDag-Erling Smørgrav XSIMPLEQ_XOR(head, NULL)) \ 4804b17dab0SDag-Erling Smørgrav (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \ 4814b17dab0SDag-Erling Smørgrav (listelm)->field.sqx_next = XSIMPLEQ_XOR(head, (elm)); \ 4824b17dab0SDag-Erling Smørgrav } while (0) 4834b17dab0SDag-Erling Smørgrav 4844b17dab0SDag-Erling Smørgrav #define XSIMPLEQ_REMOVE_HEAD(head, field) do { \ 4854b17dab0SDag-Erling Smørgrav if (((head)->sqx_first = XSIMPLEQ_XOR(head, \ 4864b17dab0SDag-Erling Smørgrav (head)->sqx_first)->field.sqx_next) == XSIMPLEQ_XOR(head, NULL)) \ 4874b17dab0SDag-Erling Smørgrav (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \ 4884b17dab0SDag-Erling Smørgrav } while (0) 4894b17dab0SDag-Erling Smørgrav 4904b17dab0SDag-Erling Smørgrav #define XSIMPLEQ_REMOVE_AFTER(head, elm, field) do { \ 4914b17dab0SDag-Erling Smørgrav if (((elm)->field.sqx_next = XSIMPLEQ_XOR(head, \ 4924b17dab0SDag-Erling Smørgrav (elm)->field.sqx_next)->field.sqx_next) \ 4934b17dab0SDag-Erling Smørgrav == XSIMPLEQ_XOR(head, NULL)) \ 4944b17dab0SDag-Erling Smørgrav (head)->sqx_last = \ 4954b17dab0SDag-Erling Smørgrav XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \ 4964b17dab0SDag-Erling Smørgrav } while (0) 4974b17dab0SDag-Erling Smørgrav 4984b17dab0SDag-Erling Smørgrav 4994b17dab0SDag-Erling Smørgrav /* 5004b17dab0SDag-Erling Smørgrav * Tail queue definitions. 5014b17dab0SDag-Erling Smørgrav */ 5024b17dab0SDag-Erling Smørgrav #define TAILQ_HEAD(name, type) \ 5034b17dab0SDag-Erling Smørgrav struct name { \ 5044b17dab0SDag-Erling Smørgrav struct type *tqh_first; /* first element */ \ 5054b17dab0SDag-Erling Smørgrav struct type **tqh_last; /* addr of last next element */ \ 5064b17dab0SDag-Erling Smørgrav } 5074b17dab0SDag-Erling Smørgrav 5084b17dab0SDag-Erling Smørgrav #define TAILQ_HEAD_INITIALIZER(head) \ 5094b17dab0SDag-Erling Smørgrav { NULL, &(head).tqh_first } 5104b17dab0SDag-Erling Smørgrav 5114b17dab0SDag-Erling Smørgrav #define TAILQ_ENTRY(type) \ 5124b17dab0SDag-Erling Smørgrav struct { \ 5134b17dab0SDag-Erling Smørgrav struct type *tqe_next; /* next element */ \ 5144b17dab0SDag-Erling Smørgrav struct type **tqe_prev; /* address of previous next element */ \ 5154b17dab0SDag-Erling Smørgrav } 5164b17dab0SDag-Erling Smørgrav 5174b17dab0SDag-Erling Smørgrav /* 5184b17dab0SDag-Erling Smørgrav * Tail queue access methods. 5194b17dab0SDag-Erling Smørgrav */ 5204b17dab0SDag-Erling Smørgrav #define TAILQ_FIRST(head) ((head)->tqh_first) 5214b17dab0SDag-Erling Smørgrav #define TAILQ_END(head) NULL 5224b17dab0SDag-Erling Smørgrav #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) 5234b17dab0SDag-Erling Smørgrav #define TAILQ_LAST(head, headname) \ 5244b17dab0SDag-Erling Smørgrav (*(((struct headname *)((head)->tqh_last))->tqh_last)) 5254b17dab0SDag-Erling Smørgrav /* XXX */ 5264b17dab0SDag-Erling Smørgrav #define TAILQ_PREV(elm, headname, field) \ 5274b17dab0SDag-Erling Smørgrav (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) 5284b17dab0SDag-Erling Smørgrav #define TAILQ_EMPTY(head) \ 5294b17dab0SDag-Erling Smørgrav (TAILQ_FIRST(head) == TAILQ_END(head)) 5304b17dab0SDag-Erling Smørgrav 5314b17dab0SDag-Erling Smørgrav #define TAILQ_FOREACH(var, head, field) \ 5324b17dab0SDag-Erling Smørgrav for((var) = TAILQ_FIRST(head); \ 5334b17dab0SDag-Erling Smørgrav (var) != TAILQ_END(head); \ 5344b17dab0SDag-Erling Smørgrav (var) = TAILQ_NEXT(var, field)) 5354b17dab0SDag-Erling Smørgrav 5364b17dab0SDag-Erling Smørgrav #define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ 5374b17dab0SDag-Erling Smørgrav for ((var) = TAILQ_FIRST(head); \ 5384b17dab0SDag-Erling Smørgrav (var) != TAILQ_END(head) && \ 5394b17dab0SDag-Erling Smørgrav ((tvar) = TAILQ_NEXT(var, field), 1); \ 5404b17dab0SDag-Erling Smørgrav (var) = (tvar)) 5414b17dab0SDag-Erling Smørgrav 5424b17dab0SDag-Erling Smørgrav 5434b17dab0SDag-Erling Smørgrav #define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ 5444b17dab0SDag-Erling Smørgrav for((var) = TAILQ_LAST(head, headname); \ 5454b17dab0SDag-Erling Smørgrav (var) != TAILQ_END(head); \ 5464b17dab0SDag-Erling Smørgrav (var) = TAILQ_PREV(var, headname, field)) 5474b17dab0SDag-Erling Smørgrav 5484b17dab0SDag-Erling Smørgrav #define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \ 5494b17dab0SDag-Erling Smørgrav for ((var) = TAILQ_LAST(head, headname); \ 5504b17dab0SDag-Erling Smørgrav (var) != TAILQ_END(head) && \ 5514b17dab0SDag-Erling Smørgrav ((tvar) = TAILQ_PREV(var, headname, field), 1); \ 5524b17dab0SDag-Erling Smørgrav (var) = (tvar)) 5534b17dab0SDag-Erling Smørgrav 5544b17dab0SDag-Erling Smørgrav /* 5554b17dab0SDag-Erling Smørgrav * Tail queue functions. 5564b17dab0SDag-Erling Smørgrav */ 5574b17dab0SDag-Erling Smørgrav #define TAILQ_INIT(head) do { \ 5584b17dab0SDag-Erling Smørgrav (head)->tqh_first = NULL; \ 5594b17dab0SDag-Erling Smørgrav (head)->tqh_last = &(head)->tqh_first; \ 5604b17dab0SDag-Erling Smørgrav } while (0) 5614b17dab0SDag-Erling Smørgrav 5624b17dab0SDag-Erling Smørgrav #define TAILQ_INSERT_HEAD(head, elm, field) do { \ 5634b17dab0SDag-Erling Smørgrav if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ 5644b17dab0SDag-Erling Smørgrav (head)->tqh_first->field.tqe_prev = \ 5654b17dab0SDag-Erling Smørgrav &(elm)->field.tqe_next; \ 5664b17dab0SDag-Erling Smørgrav else \ 5674b17dab0SDag-Erling Smørgrav (head)->tqh_last = &(elm)->field.tqe_next; \ 5684b17dab0SDag-Erling Smørgrav (head)->tqh_first = (elm); \ 5694b17dab0SDag-Erling Smørgrav (elm)->field.tqe_prev = &(head)->tqh_first; \ 5704b17dab0SDag-Erling Smørgrav } while (0) 5714b17dab0SDag-Erling Smørgrav 5724b17dab0SDag-Erling Smørgrav #define TAILQ_INSERT_TAIL(head, elm, field) do { \ 5734b17dab0SDag-Erling Smørgrav (elm)->field.tqe_next = NULL; \ 5744b17dab0SDag-Erling Smørgrav (elm)->field.tqe_prev = (head)->tqh_last; \ 5754b17dab0SDag-Erling Smørgrav *(head)->tqh_last = (elm); \ 5764b17dab0SDag-Erling Smørgrav (head)->tqh_last = &(elm)->field.tqe_next; \ 5774b17dab0SDag-Erling Smørgrav } while (0) 5784b17dab0SDag-Erling Smørgrav 5794b17dab0SDag-Erling Smørgrav #define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ 5804b17dab0SDag-Erling Smørgrav if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ 5814b17dab0SDag-Erling Smørgrav (elm)->field.tqe_next->field.tqe_prev = \ 5824b17dab0SDag-Erling Smørgrav &(elm)->field.tqe_next; \ 5834b17dab0SDag-Erling Smørgrav else \ 5844b17dab0SDag-Erling Smørgrav (head)->tqh_last = &(elm)->field.tqe_next; \ 5854b17dab0SDag-Erling Smørgrav (listelm)->field.tqe_next = (elm); \ 5864b17dab0SDag-Erling Smørgrav (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ 5874b17dab0SDag-Erling Smørgrav } while (0) 5884b17dab0SDag-Erling Smørgrav 5894b17dab0SDag-Erling Smørgrav #define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ 5904b17dab0SDag-Erling Smørgrav (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ 5914b17dab0SDag-Erling Smørgrav (elm)->field.tqe_next = (listelm); \ 5924b17dab0SDag-Erling Smørgrav *(listelm)->field.tqe_prev = (elm); \ 5934b17dab0SDag-Erling Smørgrav (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ 594 } while (0) 595 596 #define TAILQ_REMOVE(head, elm, field) do { \ 597 if (((elm)->field.tqe_next) != NULL) \ 598 (elm)->field.tqe_next->field.tqe_prev = \ 599 (elm)->field.tqe_prev; \ 600 else \ 601 (head)->tqh_last = (elm)->field.tqe_prev; \ 602 *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ 603 _Q_INVALIDATE((elm)->field.tqe_prev); \ 604 _Q_INVALIDATE((elm)->field.tqe_next); \ 605 } while (0) 606 607 #define TAILQ_REPLACE(head, elm, elm2, field) do { \ 608 if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \ 609 (elm2)->field.tqe_next->field.tqe_prev = \ 610 &(elm2)->field.tqe_next; \ 611 else \ 612 (head)->tqh_last = &(elm2)->field.tqe_next; \ 613 (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \ 614 *(elm2)->field.tqe_prev = (elm2); \ 615 _Q_INVALIDATE((elm)->field.tqe_prev); \ 616 _Q_INVALIDATE((elm)->field.tqe_next); \ 617 } while (0) 618 619 #define TAILQ_CONCAT(head1, head2, field) do { \ 620 if (!TAILQ_EMPTY(head2)) { \ 621 *(head1)->tqh_last = (head2)->tqh_first; \ 622 (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \ 623 (head1)->tqh_last = (head2)->tqh_last; \ 624 TAILQ_INIT((head2)); \ 625 } \ 626 } while (0) 627 628 #endif /* !_SYS_QUEUE_H_ */ 629