13d0407baSopenharmony_ci/* 23d0407baSopenharmony_ci * Copyright (c) 2022 FuZhou Lockzhiner Electronic Co., Ltd. All rights reserved. 33d0407baSopenharmony_ci * Copyright (c) 1991, 1993 43d0407baSopenharmony_ci * The Regents of the University of California. All rights reserved. 53d0407baSopenharmony_ci * 63d0407baSopenharmony_ci * Redistribution and use in source and binary forms, with or without 73d0407baSopenharmony_ci * modification, are permitted provided that the following conditions 83d0407baSopenharmony_ci * are met: 93d0407baSopenharmony_ci * 1. Redistributions of source code must retain the above copyright 103d0407baSopenharmony_ci * notice, this list of conditions and the following disclaimer. 113d0407baSopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright 123d0407baSopenharmony_ci * notice, this list of conditions and the following disclaimer in the 133d0407baSopenharmony_ci * documentation and/or other materials provided with the distribution. 143d0407baSopenharmony_ci * 4. Neither the name of the University nor the names of its contributors 153d0407baSopenharmony_ci * may be used to endorse or promote products derived from this software 163d0407baSopenharmony_ci * without specific prior written permission. 173d0407baSopenharmony_ci * 183d0407baSopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 193d0407baSopenharmony_ci * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 203d0407baSopenharmony_ci * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 213d0407baSopenharmony_ci * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 223d0407baSopenharmony_ci * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 233d0407baSopenharmony_ci * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 243d0407baSopenharmony_ci * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 253d0407baSopenharmony_ci * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 263d0407baSopenharmony_ci * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 273d0407baSopenharmony_ci * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 283d0407baSopenharmony_ci * SUCH DAMAGE. 293d0407baSopenharmony_ci * 303d0407baSopenharmony_ci * @(#)queue.h 8.5 (Berkeley) 8/20/94 313d0407baSopenharmony_ci * $FreeBSD: releng/10.1/sys/sys/queue.h 251887 2013-06-18 02:57:56Z lstewart $ 323d0407baSopenharmony_ci */ 333d0407baSopenharmony_ci 343d0407baSopenharmony_ci#ifndef _SYS_QUEUE_H 353d0407baSopenharmony_ci#define _SYS_QUEUE_H 363d0407baSopenharmony_ci 373d0407baSopenharmony_ci#include "sys/defs.h" 383d0407baSopenharmony_ci 393d0407baSopenharmony_ci/* 403d0407baSopenharmony_ci * This file defines four types of data structures: singly-linked lists, 413d0407baSopenharmony_ci * singly-linked tail queues, lists and tail queues. 423d0407baSopenharmony_ci * 433d0407baSopenharmony_ci * A singly-linked list is headed by a single forward pointer. The elements 443d0407baSopenharmony_ci * are singly linked for minimum space and pointer manipulation overhead at 453d0407baSopenharmony_ci * the expense of O(n) removal for arbitrary elements. New elements can be 463d0407baSopenharmony_ci * added to the list after an existing element or at the head of the list. 473d0407baSopenharmony_ci * Elements being removed from the head of the list should use the explicit 483d0407baSopenharmony_ci * macro for this purpose for optimum efficiency. A singly-linked list may 493d0407baSopenharmony_ci * only be traversed in the forward direction. Singly-linked lists are ideal 503d0407baSopenharmony_ci * for applications with large datasets and few or no removals or for 513d0407baSopenharmony_ci * implementing a LIFO queue. 523d0407baSopenharmony_ci * 533d0407baSopenharmony_ci * A singly-linked tail queue is headed by a pair of pointers, one to the 543d0407baSopenharmony_ci * head of the list and the other to the tail of the list. The elements are 553d0407baSopenharmony_ci * singly linked for minimum space and pointer manipulation overhead at the 563d0407baSopenharmony_ci * expense of O(n) removal for arbitrary elements. New elements can be added 573d0407baSopenharmony_ci * to the list after an existing element, at the head of the list, or at the 583d0407baSopenharmony_ci * end of the list. Elements being removed from the head of the tail queue 593d0407baSopenharmony_ci * should use the explicit macro for this purpose for optimum efficiency. 603d0407baSopenharmony_ci * A singly-linked tail queue may only be traversed in the forward direction. 613d0407baSopenharmony_ci * Singly-linked tail queues are ideal for applications with large datasets 623d0407baSopenharmony_ci * and few or no removals or for implementing a FIFO queue. 633d0407baSopenharmony_ci * 643d0407baSopenharmony_ci * A list is headed by a single forward pointer (or an array of forward 653d0407baSopenharmony_ci * pointers for a hash table header). The elements are doubly linked 663d0407baSopenharmony_ci * so that an arbitrary element can be removed without a need to 673d0407baSopenharmony_ci * traverse the list. New elements can be added to the list before 683d0407baSopenharmony_ci * or after an existing element or at the head of the list. A list 693d0407baSopenharmony_ci * may be traversed in either direction. 703d0407baSopenharmony_ci * 713d0407baSopenharmony_ci * A tail queue is headed by a pair of pointers, one to the head of the 723d0407baSopenharmony_ci * list and the other to the tail of the list. The elements are doubly 733d0407baSopenharmony_ci * linked so that an arbitrary element can be removed without a need to 743d0407baSopenharmony_ci * traverse the list. New elements can be added to the list before or 753d0407baSopenharmony_ci * after an existing element, at the head of the list, or at the end of 763d0407baSopenharmony_ci * the list. A tail queue may be traversed in either direction. 773d0407baSopenharmony_ci * 783d0407baSopenharmony_ci * For details on the use of these macros, see the queue(3) manual page. 793d0407baSopenharmony_ci * 803d0407baSopenharmony_ci * 813d0407baSopenharmony_ci * SLIST LIST STAILQ TAILQ 823d0407baSopenharmony_ci * _HEAD + + + + 833d0407baSopenharmony_ci * _HEAD_INITIALIZER + + + + 843d0407baSopenharmony_ci * _ENTRY + + + + 853d0407baSopenharmony_ci * _INIT + + + + 863d0407baSopenharmony_ci * _EMPTY + + + + 873d0407baSopenharmony_ci * _FIRST + + + + 883d0407baSopenharmony_ci * _NEXT + + + + 893d0407baSopenharmony_ci * _PREV - + - + 903d0407baSopenharmony_ci * _LAST - - + + 913d0407baSopenharmony_ci * _FOREACH + + + + 923d0407baSopenharmony_ci * _FOREACH_FROM + + + + 933d0407baSopenharmony_ci * _FOREACH_SAFE + + + + 943d0407baSopenharmony_ci * _FOREACH_FROM_SAFE + + + + 953d0407baSopenharmony_ci * _FOREACH_REVERSE - - - + 963d0407baSopenharmony_ci * _FOREACH_REVERSE_FROM - - - + 973d0407baSopenharmony_ci * _FOREACH_REVERSE_SAFE - - - + 983d0407baSopenharmony_ci * _FOREACH_REVERSE_FROM_SAFE - - - + 993d0407baSopenharmony_ci * _INSERT_HEAD + + + + 1003d0407baSopenharmony_ci * _INSERT_BEFORE - + - + 1013d0407baSopenharmony_ci * _INSERT_AFTER + + + + 1023d0407baSopenharmony_ci * _INSERT_TAIL - - + + 1033d0407baSopenharmony_ci * _CONCAT - - + + 1043d0407baSopenharmony_ci * _REMOVE_AFTER + - + - 1053d0407baSopenharmony_ci * _REMOVE_HEAD + - + - 1063d0407baSopenharmony_ci * _REMOVE + + + + 1073d0407baSopenharmony_ci * _SWAP + + + + 1083d0407baSopenharmony_ci * 1093d0407baSopenharmony_ci */ 1103d0407baSopenharmony_ci#ifdef QUEUE_MACRO_DEBUG 1113d0407baSopenharmony_ci/* Store the last 2 places the queue element or head was altered */ 1123d0407baSopenharmony_cistruct qm_trace { 1133d0407baSopenharmony_ci unsigned long lastline; 1143d0407baSopenharmony_ci unsigned long prevline; 1153d0407baSopenharmony_ci const char *lastfile; 1163d0407baSopenharmony_ci const char *prevfile; 1173d0407baSopenharmony_ci}; 1183d0407baSopenharmony_ci 1193d0407baSopenharmony_ci#define TRACEBUF struct qm_trace trace; 1203d0407baSopenharmony_ci#define TRACEBUF_INITIALIZER { __FILE__, __LINE__, NULL, 0 } , 1213d0407baSopenharmony_ci#define TRASHIT(x) do { (x) = (void *)-1; } while (0) 1223d0407baSopenharmony_ci#define QMD_SAVELINK(name, link) void **name = (void *)&(link) 1233d0407baSopenharmony_ci 1243d0407baSopenharmony_ci#define QMD_TRACE_HEAD(head) do { \ 1253d0407baSopenharmony_ci (head)->trace.prevline = (head)->trace.lastline; \ 1263d0407baSopenharmony_ci (head)->trace.prevfile = (head)->trace.lastfile; \ 1273d0407baSopenharmony_ci (head)->trace.lastline = __LINE__; \ 1283d0407baSopenharmony_ci (head)->trace.lastfile = __FILE__; \ 1293d0407baSopenharmony_ci} while (0) 1303d0407baSopenharmony_ci 1313d0407baSopenharmony_ci#define QMD_TRACE_ELEM(elem) do { \ 1323d0407baSopenharmony_ci (elem)->trace.prevline = (elem)->trace.lastline; \ 1333d0407baSopenharmony_ci (elem)->trace.prevfile = (elem)->trace.lastfile; \ 1343d0407baSopenharmony_ci (elem)->trace.lastline = __LINE__; \ 1353d0407baSopenharmony_ci (elem)->trace.lastfile = __FILE__; \ 1363d0407baSopenharmony_ci} while (0) 1373d0407baSopenharmony_ci 1383d0407baSopenharmony_ci#else 1393d0407baSopenharmony_ci#define QMD_TRACE_ELEM(elem) 1403d0407baSopenharmony_ci#define QMD_TRACE_HEAD(head) 1413d0407baSopenharmony_ci#define QMD_SAVELINK(name, link) 1423d0407baSopenharmony_ci#define TRACEBUF 1433d0407baSopenharmony_ci#define TRACEBUF_INITIALIZER 1443d0407baSopenharmony_ci#define TRASHIT(x) 1453d0407baSopenharmony_ci#endif /* QUEUE_MACRO_DEBUG */ 1463d0407baSopenharmony_ci 1473d0407baSopenharmony_ci/* 1483d0407baSopenharmony_ci * Singly-linked List declarations. 1493d0407baSopenharmony_ci */ 1503d0407baSopenharmony_ci#define SLIST_HEAD(name, type) \ 1513d0407baSopenharmony_cistruct name { \ 1523d0407baSopenharmony_ci struct type *slh_first; /* first element */ \ 1533d0407baSopenharmony_ci} 1543d0407baSopenharmony_ci 1553d0407baSopenharmony_ci#define SLIST_HEAD_INITIALIZER(head) \ 1563d0407baSopenharmony_ci { NULL } 1573d0407baSopenharmony_ci 1583d0407baSopenharmony_ci#define SLIST_ENTRY(type) \ 1593d0407baSopenharmony_cistruct { \ 1603d0407baSopenharmony_ci struct type *sle_next; /* next element */ \ 1613d0407baSopenharmony_ci} 1623d0407baSopenharmony_ci 1633d0407baSopenharmony_ci/* 1643d0407baSopenharmony_ci * Singly-linked List functions. 1653d0407baSopenharmony_ci */ 1663d0407baSopenharmony_ci#define SLIST_EMPTY(head) ((head)->slh_first == NULL) 1673d0407baSopenharmony_ci 1683d0407baSopenharmony_ci#define SLIST_FIRST(head) ((head)->slh_first) 1693d0407baSopenharmony_ci 1703d0407baSopenharmony_ci#define SLIST_FOREACH(var, head, field) \ 1713d0407baSopenharmony_ci for ((var) = SLIST_FIRST((head)); \ 1723d0407baSopenharmony_ci (var); \ 1733d0407baSopenharmony_ci (var) = SLIST_NEXT((var), field)) 1743d0407baSopenharmony_ci 1753d0407baSopenharmony_ci#define SLIST_FOREACH_FROM(var, head, field) \ 1763d0407baSopenharmony_ci for ((var) = ((var) ? (var) : SLIST_FIRST((head))); \ 1773d0407baSopenharmony_ci (var); \ 1783d0407baSopenharmony_ci (var) = SLIST_NEXT((var), field)) 1793d0407baSopenharmony_ci 1803d0407baSopenharmony_ci#define SLIST_FOREACH_SAFE(var, head, field, tvar) \ 1813d0407baSopenharmony_ci for ((var) = SLIST_FIRST((head)); \ 1823d0407baSopenharmony_ci (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ 1833d0407baSopenharmony_ci (var) = (tvar)) 1843d0407baSopenharmony_ci 1853d0407baSopenharmony_ci#define SLIST_FOREACH_FROM_SAFE(var, head, field, tvar) \ 1863d0407baSopenharmony_ci for ((var) = ((var) ? (var) : SLIST_FIRST((head))); \ 1873d0407baSopenharmony_ci (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ 1883d0407baSopenharmony_ci (var) = (tvar)) 1893d0407baSopenharmony_ci 1903d0407baSopenharmony_ci#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \ 1913d0407baSopenharmony_ci for ((varp) = &SLIST_FIRST((head)); \ 1923d0407baSopenharmony_ci ((var) = *(varp)) != NULL; \ 1933d0407baSopenharmony_ci (varp) = &SLIST_NEXT((var), field)) 1943d0407baSopenharmony_ci 1953d0407baSopenharmony_ci#define SLIST_INIT(head) do { \ 1963d0407baSopenharmony_ci SLIST_FIRST((head)) = NULL; \ 1973d0407baSopenharmony_ci} while (0) 1983d0407baSopenharmony_ci 1993d0407baSopenharmony_ci#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ 2003d0407baSopenharmony_ci SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \ 2013d0407baSopenharmony_ci SLIST_NEXT((slistelm), field) = (elm); \ 2023d0407baSopenharmony_ci} while (0) 2033d0407baSopenharmony_ci 2043d0407baSopenharmony_ci#define SLIST_INSERT_HEAD(head, elm, field) do { \ 2053d0407baSopenharmony_ci SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \ 2063d0407baSopenharmony_ci SLIST_FIRST((head)) = (elm); \ 2073d0407baSopenharmony_ci} while (0) 2083d0407baSopenharmony_ci 2093d0407baSopenharmony_ci#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) 2103d0407baSopenharmony_ci 2113d0407baSopenharmony_ci#define SLIST_REMOVE(head, elm, type, field) do { \ 2123d0407baSopenharmony_ci QMD_SAVELINK(oldnext, (elm)->field.sle_next); \ 2133d0407baSopenharmony_ci if (SLIST_FIRST((head)) == (elm)) { \ 2143d0407baSopenharmony_ci SLIST_REMOVE_HEAD((head), field); \ 2153d0407baSopenharmony_ci } \ 2163d0407baSopenharmony_ci else { \ 2173d0407baSopenharmony_ci struct type *curelm = SLIST_FIRST((head)); \ 2183d0407baSopenharmony_ci while (SLIST_NEXT(curelm, field) != (elm)) \ 2193d0407baSopenharmony_ci curelm = SLIST_NEXT(curelm, field); \ 2203d0407baSopenharmony_ci SLIST_REMOVE_AFTER(curelm, field); \ 2213d0407baSopenharmony_ci } \ 2223d0407baSopenharmony_ci TRASHIT(*oldnext); \ 2233d0407baSopenharmony_ci} while (0) 2243d0407baSopenharmony_ci 2253d0407baSopenharmony_ci#define SLIST_REMOVE_AFTER(elm, field) do { \ 2263d0407baSopenharmony_ci SLIST_NEXT(elm, field) = \ 2273d0407baSopenharmony_ci SLIST_NEXT(SLIST_NEXT(elm, field), field); \ 2283d0407baSopenharmony_ci} while (0) 2293d0407baSopenharmony_ci 2303d0407baSopenharmony_ci#define SLIST_REMOVE_HEAD(head, field) do { \ 2313d0407baSopenharmony_ci SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ 2323d0407baSopenharmony_ci} while (0) 2333d0407baSopenharmony_ci 2343d0407baSopenharmony_ci#define SLIST_SWAP(head1, head2, type) do { \ 2353d0407baSopenharmony_ci struct type *swap_first = SLIST_FIRST(head1); \ 2363d0407baSopenharmony_ci SLIST_FIRST(head1) = SLIST_FIRST(head2); \ 2373d0407baSopenharmony_ci SLIST_FIRST(head2) = swap_first; \ 2383d0407baSopenharmony_ci} while (0) 2393d0407baSopenharmony_ci 2403d0407baSopenharmony_ci/* 2413d0407baSopenharmony_ci * Singly-linked Tail queue declarations. 2423d0407baSopenharmony_ci */ 2433d0407baSopenharmony_ci#define STAILQ_HEAD(name, type) \ 2443d0407baSopenharmony_cistruct name { \ 2453d0407baSopenharmony_ci struct type *stqh_first; /* first element */ \ 2463d0407baSopenharmony_ci struct type **stqh_last; /* addr of last next element */ \ 2473d0407baSopenharmony_ci} 2483d0407baSopenharmony_ci 2493d0407baSopenharmony_ci#define STAILQ_HEAD_INITIALIZER(head) \ 2503d0407baSopenharmony_ci { NULL, &(head).stqh_first } 2513d0407baSopenharmony_ci 2523d0407baSopenharmony_ci#define STAILQ_ENTRY(type) \ 2533d0407baSopenharmony_cistruct { \ 2543d0407baSopenharmony_ci struct type *stqe_next; /* next element */ \ 2553d0407baSopenharmony_ci} 2563d0407baSopenharmony_ci 2573d0407baSopenharmony_ci/* 2583d0407baSopenharmony_ci * Singly-linked Tail queue functions. 2593d0407baSopenharmony_ci */ 2603d0407baSopenharmony_ci#define STAILQ_CONCAT(head1, head2) do { \ 2613d0407baSopenharmony_ci if (!STAILQ_EMPTY((head2))) { \ 2623d0407baSopenharmony_ci *(head1)->stqh_last = (head2)->stqh_first; \ 2633d0407baSopenharmony_ci (head1)->stqh_last = (head2)->stqh_last; \ 2643d0407baSopenharmony_ci STAILQ_INIT((head2)); \ 2653d0407baSopenharmony_ci } \ 2663d0407baSopenharmony_ci} while (0) 2673d0407baSopenharmony_ci 2683d0407baSopenharmony_ci#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) 2693d0407baSopenharmony_ci 2703d0407baSopenharmony_ci#define STAILQ_FIRST(head) ((head)->stqh_first) 2713d0407baSopenharmony_ci 2723d0407baSopenharmony_ci#define STAILQ_FOREACH(var, head, field) \ 2733d0407baSopenharmony_ci for ((var) = STAILQ_FIRST((head)); \ 2743d0407baSopenharmony_ci (var); \ 2753d0407baSopenharmony_ci (var) = STAILQ_NEXT((var), field)) 2763d0407baSopenharmony_ci 2773d0407baSopenharmony_ci#define STAILQ_FOREACH_FROM(var, head, field) \ 2783d0407baSopenharmony_ci for ((var) = ((var) ? (var) : STAILQ_FIRST((head))); \ 2793d0407baSopenharmony_ci (var); \ 2803d0407baSopenharmony_ci (var) = STAILQ_NEXT((var), field)) 2813d0407baSopenharmony_ci 2823d0407baSopenharmony_ci#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \ 2833d0407baSopenharmony_ci for ((var) = STAILQ_FIRST((head)); \ 2843d0407baSopenharmony_ci (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ 2853d0407baSopenharmony_ci (var) = (tvar)) 2863d0407baSopenharmony_ci 2873d0407baSopenharmony_ci#define STAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \ 2883d0407baSopenharmony_ci for ((var) = ((var) ? (var) : STAILQ_FIRST((head))); \ 2893d0407baSopenharmony_ci (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ 2903d0407baSopenharmony_ci (var) = (tvar)) 2913d0407baSopenharmony_ci 2923d0407baSopenharmony_ci#define STAILQ_INIT(head) do { \ 2933d0407baSopenharmony_ci STAILQ_FIRST((head)) = NULL; \ 2943d0407baSopenharmony_ci (head)->stqh_last = &STAILQ_FIRST((head)); \ 2953d0407baSopenharmony_ci} while (0) 2963d0407baSopenharmony_ci 2973d0407baSopenharmony_ci#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ 2983d0407baSopenharmony_ci if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL) \ 2993d0407baSopenharmony_ci (head)->stqh_last = &STAILQ_NEXT((elm), field); \ 3003d0407baSopenharmony_ci STAILQ_NEXT((tqelm), field) = (elm); \ 3013d0407baSopenharmony_ci} while (0) 3023d0407baSopenharmony_ci 3033d0407baSopenharmony_ci#define STAILQ_INSERT_HEAD(head, elm, field) do { \ 3043d0407baSopenharmony_ci if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \ 3053d0407baSopenharmony_ci (head)->stqh_last = &STAILQ_NEXT((elm), field); \ 3063d0407baSopenharmony_ci STAILQ_FIRST((head)) = (elm); \ 3073d0407baSopenharmony_ci} while (0) 3083d0407baSopenharmony_ci 3093d0407baSopenharmony_ci#define STAILQ_INSERT_TAIL(head, elm, field) do { \ 3103d0407baSopenharmony_ci STAILQ_NEXT((elm), field) = NULL; \ 3113d0407baSopenharmony_ci *(head)->stqh_last = (elm); \ 3123d0407baSopenharmony_ci (head)->stqh_last = &STAILQ_NEXT((elm), field); \ 3133d0407baSopenharmony_ci} while (0) 3143d0407baSopenharmony_ci 3153d0407baSopenharmony_ci#define STAILQ_LAST(head, type, field) \ 3163d0407baSopenharmony_ci (STAILQ_EMPTY((head)) ? NULL : __containerof((head)->stqh_last, struct type, (field).stqe_next)) 3173d0407baSopenharmony_ci 3183d0407baSopenharmony_ci#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) 3193d0407baSopenharmony_ci 3203d0407baSopenharmony_ci#define STAILQ_REMOVE(head, elm, type, field) do { \ 3213d0407baSopenharmony_ci QMD_SAVELINK(oldnext, (elm)->field.stqe_next); \ 3223d0407baSopenharmony_ci if (STAILQ_FIRST((head)) == (elm)) { \ 3233d0407baSopenharmony_ci STAILQ_REMOVE_HEAD((head), field); \ 3243d0407baSopenharmony_ci } \ 3253d0407baSopenharmony_ci else { \ 3263d0407baSopenharmony_ci struct type *curelm = STAILQ_FIRST((head)); \ 3273d0407baSopenharmony_ci while (STAILQ_NEXT(curelm, field) != (elm)) \ 3283d0407baSopenharmony_ci curelm = STAILQ_NEXT(curelm, field); \ 3293d0407baSopenharmony_ci STAILQ_REMOVE_AFTER(head, curelm, field); \ 3303d0407baSopenharmony_ci } \ 3313d0407baSopenharmony_ci TRASHIT(*oldnext); \ 3323d0407baSopenharmony_ci} while (0) 3333d0407baSopenharmony_ci 3343d0407baSopenharmony_ci#define STAILQ_REMOVE_AFTER(head, elm, field) do { \ 3353d0407baSopenharmony_ci if ((STAILQ_NEXT(elm, field) = \ 3363d0407baSopenharmony_ci STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \ 3373d0407baSopenharmony_ci (head)->stqh_last = &STAILQ_NEXT((elm), field); \ 3383d0407baSopenharmony_ci} while (0) 3393d0407baSopenharmony_ci 3403d0407baSopenharmony_ci#define STAILQ_REMOVE_HEAD(head, field) do { \ 3413d0407baSopenharmony_ci if ((STAILQ_FIRST((head)) = \ 3423d0407baSopenharmony_ci STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \ 3433d0407baSopenharmony_ci (head)->stqh_last = &STAILQ_FIRST((head)); \ 3443d0407baSopenharmony_ci} while (0) 3453d0407baSopenharmony_ci 3463d0407baSopenharmony_ci#define STAILQ_SWAP(head1, head2, type) do { \ 3473d0407baSopenharmony_ci struct type *swap_first = STAILQ_FIRST(head1); \ 3483d0407baSopenharmony_ci struct type **swap_last = (head1)->stqh_last; \ 3493d0407baSopenharmony_ci STAILQ_FIRST(head1) = STAILQ_FIRST(head2); \ 3503d0407baSopenharmony_ci (head1)->stqh_last = (head2)->stqh_last; \ 3513d0407baSopenharmony_ci STAILQ_FIRST(head2) = swap_first; \ 3523d0407baSopenharmony_ci (head2)->stqh_last = swap_last; \ 3533d0407baSopenharmony_ci if (STAILQ_EMPTY(head1)) \ 3543d0407baSopenharmony_ci (head1)->stqh_last = &STAILQ_FIRST(head1); \ 3553d0407baSopenharmony_ci if (STAILQ_EMPTY(head2)) \ 3563d0407baSopenharmony_ci (head2)->stqh_last = &STAILQ_FIRST(head2); \ 3573d0407baSopenharmony_ci} while (0) 3583d0407baSopenharmony_ci 3593d0407baSopenharmony_ci/* 3603d0407baSopenharmony_ci * List declarations. 3613d0407baSopenharmony_ci */ 3623d0407baSopenharmony_ci#define LIST_HEAD(name, type) \ 3633d0407baSopenharmony_cistruct name { \ 3643d0407baSopenharmony_ci struct type *lh_first; /* first element */ \ 3653d0407baSopenharmony_ci} 3663d0407baSopenharmony_ci 3673d0407baSopenharmony_ci#define LIST_HEAD_INITIALIZER(head) \ 3683d0407baSopenharmony_ci { NULL } 3693d0407baSopenharmony_ci 3703d0407baSopenharmony_ci#define LIST_ENTRY(type) \ 3713d0407baSopenharmony_cistruct { \ 3723d0407baSopenharmony_ci struct type *le_next; /* next element */ \ 3733d0407baSopenharmony_ci struct type **le_prev; /* address of previous next element */ \ 3743d0407baSopenharmony_ci} 3753d0407baSopenharmony_ci 3763d0407baSopenharmony_ci/* 3773d0407baSopenharmony_ci * List functions. 3783d0407baSopenharmony_ci */ 3793d0407baSopenharmony_ci 3803d0407baSopenharmony_ci#if (defined(_KERNEL) && defined(INVARIANTS)) 3813d0407baSopenharmony_ci#define QMD_LIST_CHECK_HEAD(head, field) do { \ 3823d0407baSopenharmony_ci if (LIST_FIRST((head)) != NULL && \ 3833d0407baSopenharmony_ci LIST_FIRST((head))->field.le_prev != \ 3843d0407baSopenharmony_ci &LIST_FIRST((head))) \ 3853d0407baSopenharmony_ci panic("Bad list head %p first->prev != head", (head)); \ 3863d0407baSopenharmony_ci} while (0) 3873d0407baSopenharmony_ci 3883d0407baSopenharmony_ci#define QMD_LIST_CHECK_NEXT(elm, field) do { \ 3893d0407baSopenharmony_ci if (LIST_NEXT((elm), field) != NULL && \ 3903d0407baSopenharmony_ci LIST_NEXT((elm), field)->field.le_prev != \ 3913d0407baSopenharmony_ci &((elm)->field.le_next)) \ 3923d0407baSopenharmony_ci panic("Bad link elm %p next->prev != elm", (elm)); \ 3933d0407baSopenharmony_ci} while (0) 3943d0407baSopenharmony_ci 3953d0407baSopenharmony_ci#define QMD_LIST_CHECK_PREV(elm, field) do { \ 3963d0407baSopenharmony_ci if (*(elm)->field.le_prev != (elm)) \ 3973d0407baSopenharmony_ci panic("Bad link elm %p prev->next != elm", (elm)); \ 3983d0407baSopenharmony_ci} while (0) 3993d0407baSopenharmony_ci#else 4003d0407baSopenharmony_ci#define QMD_LIST_CHECK_HEAD(head, field) 4013d0407baSopenharmony_ci#define QMD_LIST_CHECK_NEXT(elm, field) 4023d0407baSopenharmony_ci#define QMD_LIST_CHECK_PREV(elm, field) 4033d0407baSopenharmony_ci#endif /* (_KERNEL && INVARIANTS) */ 4043d0407baSopenharmony_ci 4053d0407baSopenharmony_ci#define LIST_EMPTY(head) ((head)->lh_first == NULL) 4063d0407baSopenharmony_ci 4073d0407baSopenharmony_ci#define LIST_FIRST(head) ((head)->lh_first) 4083d0407baSopenharmony_ci 4093d0407baSopenharmony_ci#define LIST_FOREACH(var, head, field) \ 4103d0407baSopenharmony_ci for ((var) = LIST_FIRST((head)); \ 4113d0407baSopenharmony_ci (var); \ 4123d0407baSopenharmony_ci (var) = LIST_NEXT((var), field)) 4133d0407baSopenharmony_ci 4143d0407baSopenharmony_ci#define LIST_FOREACH_FROM(var, head, field) \ 4153d0407baSopenharmony_ci for ((var) = ((var) ? (var) : LIST_FIRST((head))); \ 4163d0407baSopenharmony_ci (var); \ 4173d0407baSopenharmony_ci (var) = LIST_NEXT((var), field)) 4183d0407baSopenharmony_ci 4193d0407baSopenharmony_ci#define LIST_FOREACH_SAFE(var, head, field, tvar) \ 4203d0407baSopenharmony_ci for ((var) = LIST_FIRST((head)); \ 4213d0407baSopenharmony_ci (var) && ((tvar) = LIST_NEXT((var), field), 1); \ 4223d0407baSopenharmony_ci (var) = (tvar)) 4233d0407baSopenharmony_ci 4243d0407baSopenharmony_ci#define LIST_FOREACH_FROM_SAFE(var, head, field, tvar) \ 4253d0407baSopenharmony_ci for ((var) = ((var) ? (var) : LIST_FIRST((head))); \ 4263d0407baSopenharmony_ci (var) && ((tvar) = LIST_NEXT((var), field), 1); \ 4273d0407baSopenharmony_ci (var) = (tvar)) 4283d0407baSopenharmony_ci 4293d0407baSopenharmony_ci#define LIST_INIT(head) do { \ 4303d0407baSopenharmony_ci LIST_FIRST((head)) = NULL; \ 4313d0407baSopenharmony_ci} while (0) 4323d0407baSopenharmony_ci 4333d0407baSopenharmony_ci#define LIST_INSERT_AFTER(listelm, elm, field) do { \ 4343d0407baSopenharmony_ci QMD_LIST_CHECK_NEXT(listelm, field); \ 4353d0407baSopenharmony_ci if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL) \ 4363d0407baSopenharmony_ci LIST_NEXT((listelm), field)->field.le_prev = \ 4373d0407baSopenharmony_ci &LIST_NEXT((elm), field); \ 4383d0407baSopenharmony_ci LIST_NEXT((listelm), field) = (elm); \ 4393d0407baSopenharmony_ci (elm)->field.le_prev = &LIST_NEXT((listelm), field); \ 4403d0407baSopenharmony_ci} while (0) 4413d0407baSopenharmony_ci 4423d0407baSopenharmony_ci#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ 4433d0407baSopenharmony_ci QMD_LIST_CHECK_PREV(listelm, field); \ 4443d0407baSopenharmony_ci (elm)->field.le_prev = (listelm)->field.le_prev; \ 4453d0407baSopenharmony_ci LIST_NEXT((elm), field) = (listelm); \ 4463d0407baSopenharmony_ci *(listelm)->field.le_prev = (elm); \ 4473d0407baSopenharmony_ci (listelm)->field.le_prev = &LIST_NEXT((elm), field); \ 4483d0407baSopenharmony_ci} while (0) 4493d0407baSopenharmony_ci 4503d0407baSopenharmony_ci#define LIST_INSERT_HEAD(head, elm, field) do { \ 4513d0407baSopenharmony_ci QMD_LIST_CHECK_HEAD((head), field); \ 4523d0407baSopenharmony_ci if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ 4533d0407baSopenharmony_ci LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field); \ 4543d0407baSopenharmony_ci LIST_FIRST((head)) = (elm); \ 4553d0407baSopenharmony_ci (elm)->field.le_prev = &LIST_FIRST((head)); \ 4563d0407baSopenharmony_ci} while (0) 4573d0407baSopenharmony_ci 4583d0407baSopenharmony_ci#define LIST_NEXT(elm, field) ((elm)->field.le_next) 4593d0407baSopenharmony_ci 4603d0407baSopenharmony_ci#define LIST_PREV(elm, head, type, field) \ 4613d0407baSopenharmony_ci ((elm)->field.le_prev == &LIST_FIRST((head)) ? \ 4623d0407baSopenharmony_ci NULL : __containerof((elm)->(field).le_prev, struct type, (field).le_next)) 4633d0407baSopenharmony_ci 4643d0407baSopenharmony_ci#define LIST_REMOVE(elm, field) do { \ 4653d0407baSopenharmony_ci QMD_SAVELINK(oldnext, (elm)->field.le_next); \ 4663d0407baSopenharmony_ci QMD_SAVELINK(oldprev, (elm)->field.le_prev); \ 4673d0407baSopenharmony_ci QMD_LIST_CHECK_NEXT(elm, field); \ 4683d0407baSopenharmony_ci QMD_LIST_CHECK_PREV(elm, field); \ 4693d0407baSopenharmony_ci if (LIST_NEXT((elm), field) != NULL) \ 4703d0407baSopenharmony_ci LIST_NEXT((elm), field)->field.le_prev = \ 4713d0407baSopenharmony_ci (elm)->field.le_prev; \ 4723d0407baSopenharmony_ci *(elm)->field.le_prev = LIST_NEXT((elm), field); \ 4733d0407baSopenharmony_ci TRASHIT(*oldnext); \ 4743d0407baSopenharmony_ci TRASHIT(*oldprev); \ 4753d0407baSopenharmony_ci} while (0) 4763d0407baSopenharmony_ci 4773d0407baSopenharmony_ci#define LIST_SWAP(head1, head2, type, field) do { \ 4783d0407baSopenharmony_ci struct type *swap_tmp = LIST_FIRST((head1)); \ 4793d0407baSopenharmony_ci LIST_FIRST((head1)) = LIST_FIRST((head2)); \ 4803d0407baSopenharmony_ci LIST_FIRST((head2)) = swap_tmp; \ 4813d0407baSopenharmony_ci if ((swap_tmp = LIST_FIRST((head1))) != NULL) \ 4823d0407baSopenharmony_ci swap_tmp->field.le_prev = &LIST_FIRST((head1)); \ 4833d0407baSopenharmony_ci if ((swap_tmp = LIST_FIRST((head2))) != NULL) \ 4843d0407baSopenharmony_ci swap_tmp->field.le_prev = &LIST_FIRST((head2)); \ 4853d0407baSopenharmony_ci} while (0) 4863d0407baSopenharmony_ci 4873d0407baSopenharmony_ci/* 4883d0407baSopenharmony_ci * Tail queue declarations. 4893d0407baSopenharmony_ci */ 4903d0407baSopenharmony_ci#define TAILQ_HEAD(name, type) \ 4913d0407baSopenharmony_cistruct name { \ 4923d0407baSopenharmony_ci struct type *tqh_first; /* first element */ \ 4933d0407baSopenharmony_ci struct type **tqh_last; /* addr of last next element */ \ 4943d0407baSopenharmony_ci TRACEBUF \ 4953d0407baSopenharmony_ci} 4963d0407baSopenharmony_ci 4973d0407baSopenharmony_ci#define TAILQ_HEAD_INITIALIZER(head) \ 4983d0407baSopenharmony_ci { NULL, &(head).tqh_first, TRACEBUF_INITIALIZER } 4993d0407baSopenharmony_ci 5003d0407baSopenharmony_ci#define TAILQ_ENTRY(type) \ 5013d0407baSopenharmony_cistruct { \ 5023d0407baSopenharmony_ci struct type *tqe_next; /* next element */ \ 5033d0407baSopenharmony_ci struct type **tqe_prev; /* address of previous next element */ \ 5043d0407baSopenharmony_ci TRACEBUF \ 5053d0407baSopenharmony_ci} 5063d0407baSopenharmony_ci 5073d0407baSopenharmony_ci/* 5083d0407baSopenharmony_ci * Tail queue functions. 5093d0407baSopenharmony_ci */ 5103d0407baSopenharmony_ci#if (defined(_KERNEL) && defined(INVARIANTS)) 5113d0407baSopenharmony_ci#define QMD_TAILQ_CHECK_HEAD(head, field) do { \ 5123d0407baSopenharmony_ci if (!TAILQ_EMPTY(head) && \ 5133d0407baSopenharmony_ci TAILQ_FIRST((head))->field.tqe_prev != \ 5143d0407baSopenharmony_ci &TAILQ_FIRST((head))) \ 5153d0407baSopenharmony_ci panic("Bad tailq head %p first->prev != head", (head)); \ 5163d0407baSopenharmony_ci} while (0) 5173d0407baSopenharmony_ci 5183d0407baSopenharmony_ci#define QMD_TAILQ_CHECK_TAIL(head, field) do { \ 5193d0407baSopenharmony_ci if (*(head)->tqh_last != NULL) \ 5203d0407baSopenharmony_ci panic("Bad tailq NEXT(%p->tqh_last) != NULL", (head)); \ 5213d0407baSopenharmony_ci} while (0) 5223d0407baSopenharmony_ci 5233d0407baSopenharmony_ci#define QMD_TAILQ_CHECK_NEXT(elm, field) do { \ 5243d0407baSopenharmony_ci if (TAILQ_NEXT((elm), field) != NULL && \ 5253d0407baSopenharmony_ci TAILQ_NEXT((elm), field)->field.tqe_prev != \ 5263d0407baSopenharmony_ci &((elm)->field.tqe_next)) \ 5273d0407baSopenharmony_ci panic("Bad link elm %p next->prev != elm", (elm)); \ 5283d0407baSopenharmony_ci} while (0) 5293d0407baSopenharmony_ci 5303d0407baSopenharmony_ci#define QMD_TAILQ_CHECK_PREV(elm, field) do { \ 5313d0407baSopenharmony_ci if (*(elm)->field.tqe_prev != (elm)) \ 5323d0407baSopenharmony_ci panic("Bad link elm %p prev->next != elm", (elm)); \ 5333d0407baSopenharmony_ci} while (0) 5343d0407baSopenharmony_ci#else 5353d0407baSopenharmony_ci#define QMD_TAILQ_CHECK_HEAD(head, field) 5363d0407baSopenharmony_ci#define QMD_TAILQ_CHECK_TAIL(head, headname) 5373d0407baSopenharmony_ci#define QMD_TAILQ_CHECK_NEXT(elm, field) 5383d0407baSopenharmony_ci#define QMD_TAILQ_CHECK_PREV(elm, field) 5393d0407baSopenharmony_ci#endif /* (_KERNEL && INVARIANTS) */ 5403d0407baSopenharmony_ci 5413d0407baSopenharmony_ci#define TAILQ_CONCAT(head1, head2, field) do { \ 5423d0407baSopenharmony_ci if (!TAILQ_EMPTY(head2)) { \ 5433d0407baSopenharmony_ci *(head1)->tqh_last = (head2)->tqh_first; \ 5443d0407baSopenharmony_ci (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \ 5453d0407baSopenharmony_ci (head1)->tqh_last = (head2)->tqh_last; \ 5463d0407baSopenharmony_ci TAILQ_INIT((head2)); \ 5473d0407baSopenharmony_ci QMD_TRACE_HEAD(head1); \ 5483d0407baSopenharmony_ci QMD_TRACE_HEAD(head2); \ 5493d0407baSopenharmony_ci } \ 5503d0407baSopenharmony_ci} while (0) 5513d0407baSopenharmony_ci 5523d0407baSopenharmony_ci#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) 5533d0407baSopenharmony_ci 5543d0407baSopenharmony_ci#define TAILQ_FIRST(head) ((head)->tqh_first) 5553d0407baSopenharmony_ci 5563d0407baSopenharmony_ci#define TAILQ_FOREACH(var, head, field) \ 5573d0407baSopenharmony_ci for ((var) = TAILQ_FIRST((head)); \ 5583d0407baSopenharmony_ci (var); \ 5593d0407baSopenharmony_ci (var) = TAILQ_NEXT((var), field)) 5603d0407baSopenharmony_ci 5613d0407baSopenharmony_ci#define TAILQ_FOREACH_FROM(var, head, field) \ 5623d0407baSopenharmony_ci for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); \ 5633d0407baSopenharmony_ci (var); \ 5643d0407baSopenharmony_ci (var) = TAILQ_NEXT((var), field)) 5653d0407baSopenharmony_ci 5663d0407baSopenharmony_ci#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ 5673d0407baSopenharmony_ci for ((var) = TAILQ_FIRST((head)); \ 5683d0407baSopenharmony_ci (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ 5693d0407baSopenharmony_ci (var) = (tvar)) 5703d0407baSopenharmony_ci 5713d0407baSopenharmony_ci#define TAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \ 5723d0407baSopenharmony_ci for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); \ 5733d0407baSopenharmony_ci (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ 5743d0407baSopenharmony_ci (var) = (tvar)) 5753d0407baSopenharmony_ci 5763d0407baSopenharmony_ci#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ 5773d0407baSopenharmony_ci for ((var) = TAILQ_LAST((head), headname); \ 5783d0407baSopenharmony_ci (var); \ 5793d0407baSopenharmony_ci (var) = TAILQ_PREV((var), headname, field)) 5803d0407baSopenharmony_ci 5813d0407baSopenharmony_ci#define TAILQ_FOREACH_REVERSE_FROM(var, head, headname, field) \ 5823d0407baSopenharmony_ci for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); \ 5833d0407baSopenharmony_ci (var); \ 5843d0407baSopenharmony_ci (var) = TAILQ_PREV((var), headname, field)) 5853d0407baSopenharmony_ci 5863d0407baSopenharmony_ci#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \ 5873d0407baSopenharmony_ci for ((var) = TAILQ_LAST((head), headname); \ 5883d0407baSopenharmony_ci (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \ 5893d0407baSopenharmony_ci (var) = (tvar)) 5903d0407baSopenharmony_ci 5913d0407baSopenharmony_ci#define TAILQ_FOREACH_REVERSE_FROM_SAFE(var, head, headname, field, tvar) \ 5923d0407baSopenharmony_ci for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); \ 5933d0407baSopenharmony_ci (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \ 5943d0407baSopenharmony_ci (var) = (tvar)) 5953d0407baSopenharmony_ci 5963d0407baSopenharmony_ci#define TAILQ_INIT(head) do { \ 5973d0407baSopenharmony_ci TAILQ_FIRST((head)) = NULL; \ 5983d0407baSopenharmony_ci (head)->tqh_last = &TAILQ_FIRST((head)); \ 5993d0407baSopenharmony_ci QMD_TRACE_HEAD(head); \ 6003d0407baSopenharmony_ci} while (0) 6013d0407baSopenharmony_ci 6023d0407baSopenharmony_ci#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ 6033d0407baSopenharmony_ci QMD_TAILQ_CHECK_NEXT(listelm, field); \ 6043d0407baSopenharmony_ci if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL) \ 6053d0407baSopenharmony_ci TAILQ_NEXT((elm), field)->field.tqe_prev = \ 6063d0407baSopenharmony_ci &TAILQ_NEXT((elm), field); \ 6073d0407baSopenharmony_ci else { \ 6083d0407baSopenharmony_ci (head)->tqh_last = &TAILQ_NEXT((elm), field); \ 6093d0407baSopenharmony_ci QMD_TRACE_HEAD(head); \ 6103d0407baSopenharmony_ci } \ 6113d0407baSopenharmony_ci TAILQ_NEXT((listelm), field) = (elm); \ 6123d0407baSopenharmony_ci (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \ 6133d0407baSopenharmony_ci QMD_TRACE_ELEM(&(elm)->field); \ 6143d0407baSopenharmony_ci QMD_TRACE_ELEM(&(listelm)->field); \ 6153d0407baSopenharmony_ci} while (0) 6163d0407baSopenharmony_ci 6173d0407baSopenharmony_ci#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ 6183d0407baSopenharmony_ci QMD_TAILQ_CHECK_PREV(listelm, field); \ 6193d0407baSopenharmony_ci (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ 6203d0407baSopenharmony_ci TAILQ_NEXT((elm), field) = (listelm); \ 6213d0407baSopenharmony_ci *(listelm)->field.tqe_prev = (elm); \ 6223d0407baSopenharmony_ci (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \ 6233d0407baSopenharmony_ci QMD_TRACE_ELEM(&(elm)->field); \ 6243d0407baSopenharmony_ci QMD_TRACE_ELEM(&(listelm)->field); \ 6253d0407baSopenharmony_ci} while (0) 6263d0407baSopenharmony_ci 6273d0407baSopenharmony_ci#define TAILQ_INSERT_HEAD(head, elm, field) do { \ 6283d0407baSopenharmony_ci QMD_TAILQ_CHECK_HEAD(head, field); \ 6293d0407baSopenharmony_ci if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \ 6303d0407baSopenharmony_ci TAILQ_FIRST((head))->field.tqe_prev = \ 6313d0407baSopenharmony_ci &TAILQ_NEXT((elm), field); \ 6323d0407baSopenharmony_ci else \ 6333d0407baSopenharmony_ci (head)->tqh_last = &TAILQ_NEXT((elm), field); \ 6343d0407baSopenharmony_ci TAILQ_FIRST((head)) = (elm); \ 6353d0407baSopenharmony_ci (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \ 6363d0407baSopenharmony_ci QMD_TRACE_HEAD(head); \ 6373d0407baSopenharmony_ci QMD_TRACE_ELEM(&(elm)->field); \ 6383d0407baSopenharmony_ci} while (0) 6393d0407baSopenharmony_ci 6403d0407baSopenharmony_ci#define TAILQ_INSERT_TAIL(head, elm, field) do { \ 6413d0407baSopenharmony_ci QMD_TAILQ_CHECK_TAIL(head, field); \ 6423d0407baSopenharmony_ci TAILQ_NEXT((elm), field) = NULL; \ 6433d0407baSopenharmony_ci (elm)->field.tqe_prev = (head)->tqh_last; \ 6443d0407baSopenharmony_ci *(head)->tqh_last = (elm); \ 6453d0407baSopenharmony_ci (head)->tqh_last = &TAILQ_NEXT((elm), field); \ 6463d0407baSopenharmony_ci QMD_TRACE_HEAD(head); \ 6473d0407baSopenharmony_ci QMD_TRACE_ELEM(&(elm)->field); \ 6483d0407baSopenharmony_ci} while (0) 6493d0407baSopenharmony_ci 6503d0407baSopenharmony_ci#define TAILQ_LAST(head, headname) \ 6513d0407baSopenharmony_ci (*(((struct headname *)((head)->tqh_last))->tqh_last)) 6523d0407baSopenharmony_ci 6533d0407baSopenharmony_ci#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) 6543d0407baSopenharmony_ci 6553d0407baSopenharmony_ci#define TAILQ_PREV(elm, headname, field) \ 6563d0407baSopenharmony_ci (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) 6573d0407baSopenharmony_ci 6583d0407baSopenharmony_ci#define TAILQ_REMOVE(head, elm, field) do { \ 6593d0407baSopenharmony_ci QMD_SAVELINK(oldnext, (elm)->field.tqe_next); \ 6603d0407baSopenharmony_ci QMD_SAVELINK(oldprev, (elm)->field.tqe_prev); \ 6613d0407baSopenharmony_ci QMD_TAILQ_CHECK_NEXT(elm, field); \ 6623d0407baSopenharmony_ci QMD_TAILQ_CHECK_PREV(elm, field); \ 6633d0407baSopenharmony_ci if ((TAILQ_NEXT((elm), field)) != NULL) \ 6643d0407baSopenharmony_ci TAILQ_NEXT((elm), field)->field.tqe_prev = \ 6653d0407baSopenharmony_ci (elm)->field.tqe_prev; \ 6663d0407baSopenharmony_ci else { \ 6673d0407baSopenharmony_ci (head)->tqh_last = (elm)->field.tqe_prev; \ 6683d0407baSopenharmony_ci QMD_TRACE_HEAD(head); \ 6693d0407baSopenharmony_ci } \ 6703d0407baSopenharmony_ci *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ 6713d0407baSopenharmony_ci TRASHIT(*oldnext); \ 6723d0407baSopenharmony_ci TRASHIT(*oldprev); \ 6733d0407baSopenharmony_ci QMD_TRACE_ELEM(&(elm)->field); \ 6743d0407baSopenharmony_ci} while (0) 6753d0407baSopenharmony_ci 6763d0407baSopenharmony_ci#define TAILQ_SWAP(head1, head2, type, field) do { \ 6773d0407baSopenharmony_ci struct type *swap_first = (head1)->tqh_first; \ 6783d0407baSopenharmony_ci struct type **swap_last = (head1)->tqh_last; \ 6793d0407baSopenharmony_ci (head1)->tqh_first = (head2)->tqh_first; \ 6803d0407baSopenharmony_ci (head1)->tqh_last = (head2)->tqh_last; \ 6813d0407baSopenharmony_ci (head2)->tqh_first = swap_first; \ 6823d0407baSopenharmony_ci (head2)->tqh_last = swap_last; \ 6833d0407baSopenharmony_ci if ((swap_first = (head1)->tqh_first) != NULL) \ 6843d0407baSopenharmony_ci swap_first->field.tqe_prev = &(head1)->tqh_first; \ 6853d0407baSopenharmony_ci else \ 6863d0407baSopenharmony_ci (head1)->tqh_last = &(head1)->tqh_first; \ 6873d0407baSopenharmony_ci if ((swap_first = (head2)->tqh_first) != NULL) \ 6883d0407baSopenharmony_ci swap_first->field.tqe_prev = &(head2)->tqh_first; \ 6893d0407baSopenharmony_ci else \ 6903d0407baSopenharmony_ci (head2)->tqh_last = &(head2)->tqh_first; \ 6913d0407baSopenharmony_ci} while (0) 6923d0407baSopenharmony_ci 6933d0407baSopenharmony_ci#endif /* !_SYS_QUEUE_H */ 694