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