File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / iperf / src / queue.h
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Sep 27 11:14:54 2023 UTC (9 months, 1 week ago) by misho
Branches: iperf, MAIN
CVS tags: v3_15, HEAD
Version 3.15

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>