xref: /libevent-2.1.12/compat/sys/queue.h (revision cb9da0bf)
161cb6846SNiels Provos /*	$OpenBSD: queue.h,v 1.16 2000/09/07 19:47:59 art Exp $	*/
261cb6846SNiels Provos /*	$NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $	*/
361cb6846SNiels Provos 
461cb6846SNiels Provos /*
561cb6846SNiels Provos  * Copyright (c) 1991, 1993
661cb6846SNiels Provos  *	The Regents of the University of California.  All rights reserved.
761cb6846SNiels Provos  *
861cb6846SNiels Provos  * Redistribution and use in source and binary forms, with or without
961cb6846SNiels Provos  * modification, are permitted provided that the following conditions
1061cb6846SNiels Provos  * are met:
1161cb6846SNiels Provos  * 1. Redistributions of source code must retain the above copyright
1261cb6846SNiels Provos  *    notice, this list of conditions and the following disclaimer.
1361cb6846SNiels Provos  * 2. Redistributions in binary form must reproduce the above copyright
1461cb6846SNiels Provos  *    notice, this list of conditions and the following disclaimer in the
1561cb6846SNiels Provos  *    documentation and/or other materials provided with the distribution.
16e2f06f4fSNiels Provos  * 3. Neither the name of the University nor the names of its contributors
1761cb6846SNiels Provos  *    may be used to endorse or promote products derived from this software
1861cb6846SNiels Provos  *    without specific prior written permission.
1961cb6846SNiels Provos  *
2061cb6846SNiels Provos  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2161cb6846SNiels Provos  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2261cb6846SNiels Provos  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2361cb6846SNiels Provos  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2461cb6846SNiels Provos  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2561cb6846SNiels Provos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2661cb6846SNiels Provos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2761cb6846SNiels Provos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2861cb6846SNiels Provos  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2961cb6846SNiels Provos  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3061cb6846SNiels Provos  * SUCH DAMAGE.
3161cb6846SNiels Provos  *
3261cb6846SNiels Provos  *	@(#)queue.h	8.5 (Berkeley) 8/20/94
3361cb6846SNiels Provos  */
3461cb6846SNiels Provos 
35*cb9da0bfSNick Mathewson #ifndef	SYS_QUEUE_H__
36*cb9da0bfSNick Mathewson #define	SYS_QUEUE_H__
3761cb6846SNiels Provos 
3861cb6846SNiels Provos /*
3961cb6846SNiels Provos  * This file defines five types of data structures: singly-linked lists,
4061cb6846SNiels Provos  * lists, simple queues, tail queues, and circular queues.
4161cb6846SNiels Provos  *
4261cb6846SNiels Provos  *
4361cb6846SNiels Provos  * A singly-linked list is headed by a single forward pointer. The elements
4461cb6846SNiels Provos  * are singly linked for minimum space and pointer manipulation overhead at
4561cb6846SNiels Provos  * the expense of O(n) removal for arbitrary elements. New elements can be
4661cb6846SNiels Provos  * added to the list after an existing element or at the head of the list.
4761cb6846SNiels Provos  * Elements being removed from the head of the list should use the explicit
4861cb6846SNiels Provos  * macro for this purpose for optimum efficiency. A singly-linked list may
4961cb6846SNiels Provos  * only be traversed in the forward direction.  Singly-linked lists are ideal
5061cb6846SNiels Provos  * for applications with large datasets and few or no removals or for
5161cb6846SNiels Provos  * implementing a LIFO queue.
5261cb6846SNiels Provos  *
5361cb6846SNiels Provos  * A list is headed by a single forward pointer (or an array of forward
5461cb6846SNiels Provos  * pointers for a hash table header). The elements are doubly linked
5561cb6846SNiels Provos  * so that an arbitrary element can be removed without a need to
5661cb6846SNiels Provos  * traverse the list. New elements can be added to the list before
5761cb6846SNiels Provos  * or after an existing element or at the head of the list. A list
5861cb6846SNiels Provos  * may only be traversed in the forward direction.
5961cb6846SNiels Provos  *
6061cb6846SNiels Provos  * A simple queue is headed by a pair of pointers, one the head of the
6161cb6846SNiels Provos  * list and the other to the tail of the list. The elements are singly
6261cb6846SNiels Provos  * linked to save space, so elements can only be removed from the
6361cb6846SNiels Provos  * head of the list. New elements can be added to the list before or after
6461cb6846SNiels Provos  * an existing element, at the head of the list, or at the end of the
6561cb6846SNiels Provos  * list. A simple queue may only be traversed in the forward direction.
6661cb6846SNiels Provos  *
6761cb6846SNiels Provos  * A tail queue is headed by a pair of pointers, one to the head of the
6861cb6846SNiels Provos  * list and the other to the tail of the list. The elements are doubly
6961cb6846SNiels Provos  * linked so that an arbitrary element can be removed without a need to
7061cb6846SNiels Provos  * traverse the list. New elements can be added to the list before or
7161cb6846SNiels Provos  * after an existing element, at the head of the list, or at the end of
7261cb6846SNiels Provos  * the list. A tail queue may be traversed in either direction.
7361cb6846SNiels Provos  *
7461cb6846SNiels Provos  * A circle queue is headed by a pair of pointers, one to the head of the
7561cb6846SNiels Provos  * list and the other to the tail of the list. The elements are doubly
7661cb6846SNiels Provos  * linked so that an arbitrary element can be removed without a need to
7761cb6846SNiels Provos  * traverse the list. New elements can be added to the list before or after
7861cb6846SNiels Provos  * an existing element, at the head of the list, or at the end of the list.
7961cb6846SNiels Provos  * A circle queue may be traversed in either direction, but has a more
8061cb6846SNiels Provos  * complex end of list detection.
8161cb6846SNiels Provos  *
8261cb6846SNiels Provos  * For details on the use of these macros, see the queue(3) manual page.
8361cb6846SNiels Provos  */
8461cb6846SNiels Provos 
8561cb6846SNiels Provos /*
8661cb6846SNiels Provos  * Singly-linked List definitions.
8761cb6846SNiels Provos  */
8861cb6846SNiels Provos #define SLIST_HEAD(name, type)						\
8961cb6846SNiels Provos struct name {								\
9061cb6846SNiels Provos 	struct type *slh_first;	/* first element */			\
9161cb6846SNiels Provos }
9261cb6846SNiels Provos 
9361cb6846SNiels Provos #define	SLIST_HEAD_INITIALIZER(head)					\
9461cb6846SNiels Provos 	{ NULL }
9561cb6846SNiels Provos 
969f560bfaSNick Mathewson #ifndef _WIN32
9761cb6846SNiels Provos #define SLIST_ENTRY(type)						\
9861cb6846SNiels Provos struct {								\
9961cb6846SNiels Provos 	struct type *sle_next;	/* next element */			\
10061cb6846SNiels Provos }
101e2f06f4fSNiels Provos #endif
10261cb6846SNiels Provos 
10361cb6846SNiels Provos /*
10461cb6846SNiels Provos  * Singly-linked List access methods.
10561cb6846SNiels Provos  */
10661cb6846SNiels Provos #define	SLIST_FIRST(head)	((head)->slh_first)
10761cb6846SNiels Provos #define	SLIST_END(head)		NULL
10861cb6846SNiels Provos #define	SLIST_EMPTY(head)	(SLIST_FIRST(head) == SLIST_END(head))
10961cb6846SNiels Provos #define	SLIST_NEXT(elm, field)	((elm)->field.sle_next)
11061cb6846SNiels Provos 
11161cb6846SNiels Provos #define	SLIST_FOREACH(var, head, field)					\
11261cb6846SNiels Provos 	for((var) = SLIST_FIRST(head);					\
11361cb6846SNiels Provos 	    (var) != SLIST_END(head);					\
11461cb6846SNiels Provos 	    (var) = SLIST_NEXT(var, field))
11561cb6846SNiels Provos 
11661cb6846SNiels Provos /*
11761cb6846SNiels Provos  * Singly-linked List functions.
11861cb6846SNiels Provos  */
11961cb6846SNiels Provos #define	SLIST_INIT(head) {						\
12061cb6846SNiels Provos 	SLIST_FIRST(head) = SLIST_END(head);				\
12161cb6846SNiels Provos }
12261cb6846SNiels Provos 
12361cb6846SNiels Provos #define	SLIST_INSERT_AFTER(slistelm, elm, field) do {			\
12461cb6846SNiels Provos 	(elm)->field.sle_next = (slistelm)->field.sle_next;		\
12561cb6846SNiels Provos 	(slistelm)->field.sle_next = (elm);				\
12661cb6846SNiels Provos } while (0)
12761cb6846SNiels Provos 
12861cb6846SNiels Provos #define	SLIST_INSERT_HEAD(head, elm, field) do {			\
12961cb6846SNiels Provos 	(elm)->field.sle_next = (head)->slh_first;			\
13061cb6846SNiels Provos 	(head)->slh_first = (elm);					\
13161cb6846SNiels Provos } while (0)
13261cb6846SNiels Provos 
13361cb6846SNiels Provos #define	SLIST_REMOVE_HEAD(head, field) do {				\
13461cb6846SNiels Provos 	(head)->slh_first = (head)->slh_first->field.sle_next;		\
13561cb6846SNiels Provos } while (0)
13661cb6846SNiels Provos 
13761cb6846SNiels Provos /*
13861cb6846SNiels Provos  * List definitions.
13961cb6846SNiels Provos  */
14061cb6846SNiels Provos #define LIST_HEAD(name, type)						\
14161cb6846SNiels Provos struct name {								\
14261cb6846SNiels Provos 	struct type *lh_first;	/* first element */			\
14361cb6846SNiels Provos }
14461cb6846SNiels Provos 
14561cb6846SNiels Provos #define LIST_HEAD_INITIALIZER(head)					\
14661cb6846SNiels Provos 	{ NULL }
14761cb6846SNiels Provos 
14861cb6846SNiels Provos #define LIST_ENTRY(type)						\
14961cb6846SNiels Provos struct {								\
15061cb6846SNiels Provos 	struct type *le_next;	/* next element */			\
15161cb6846SNiels Provos 	struct type **le_prev;	/* address of previous next element */	\
15261cb6846SNiels Provos }
15361cb6846SNiels Provos 
15461cb6846SNiels Provos /*
15561cb6846SNiels Provos  * List access methods
15661cb6846SNiels Provos  */
15761cb6846SNiels Provos #define	LIST_FIRST(head)		((head)->lh_first)
15861cb6846SNiels Provos #define	LIST_END(head)			NULL
15961cb6846SNiels Provos #define	LIST_EMPTY(head)		(LIST_FIRST(head) == LIST_END(head))
16061cb6846SNiels Provos #define	LIST_NEXT(elm, field)		((elm)->field.le_next)
16161cb6846SNiels Provos 
16261cb6846SNiels Provos #define LIST_FOREACH(var, head, field)					\
16361cb6846SNiels Provos 	for((var) = LIST_FIRST(head);					\
16461cb6846SNiels Provos 	    (var)!= LIST_END(head);					\
16561cb6846SNiels Provos 	    (var) = LIST_NEXT(var, field))
16661cb6846SNiels Provos 
16761cb6846SNiels Provos /*
16861cb6846SNiels Provos  * List functions.
16961cb6846SNiels Provos  */
17061cb6846SNiels Provos #define	LIST_INIT(head) do {						\
17161cb6846SNiels Provos 	LIST_FIRST(head) = LIST_END(head);				\
17261cb6846SNiels Provos } while (0)
17361cb6846SNiels Provos 
17461cb6846SNiels Provos #define LIST_INSERT_AFTER(listelm, elm, field) do {			\
17561cb6846SNiels Provos 	if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)	\
17661cb6846SNiels Provos 		(listelm)->field.le_next->field.le_prev =		\
17761cb6846SNiels Provos 		    &(elm)->field.le_next;				\
17861cb6846SNiels Provos 	(listelm)->field.le_next = (elm);				\
17961cb6846SNiels Provos 	(elm)->field.le_prev = &(listelm)->field.le_next;		\
18061cb6846SNiels Provos } while (0)
18161cb6846SNiels Provos 
18261cb6846SNiels Provos #define	LIST_INSERT_BEFORE(listelm, elm, field) do {			\
18361cb6846SNiels Provos 	(elm)->field.le_prev = (listelm)->field.le_prev;		\
18461cb6846SNiels Provos 	(elm)->field.le_next = (listelm);				\
18561cb6846SNiels Provos 	*(listelm)->field.le_prev = (elm);				\
18661cb6846SNiels Provos 	(listelm)->field.le_prev = &(elm)->field.le_next;		\
18761cb6846SNiels Provos } while (0)
18861cb6846SNiels Provos 
18961cb6846SNiels Provos #define LIST_INSERT_HEAD(head, elm, field) do {				\
19061cb6846SNiels Provos 	if (((elm)->field.le_next = (head)->lh_first) != NULL)		\
19161cb6846SNiels Provos 		(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
19261cb6846SNiels Provos 	(head)->lh_first = (elm);					\
19361cb6846SNiels Provos 	(elm)->field.le_prev = &(head)->lh_first;			\
19461cb6846SNiels Provos } while (0)
19561cb6846SNiels Provos 
19661cb6846SNiels Provos #define LIST_REMOVE(elm, field) do {					\
19761cb6846SNiels Provos 	if ((elm)->field.le_next != NULL)				\
19861cb6846SNiels Provos 		(elm)->field.le_next->field.le_prev =			\
19961cb6846SNiels Provos 		    (elm)->field.le_prev;				\
20061cb6846SNiels Provos 	*(elm)->field.le_prev = (elm)->field.le_next;			\
20161cb6846SNiels Provos } while (0)
20261cb6846SNiels Provos 
20361cb6846SNiels Provos #define LIST_REPLACE(elm, elm2, field) do {				\
20461cb6846SNiels Provos 	if (((elm2)->field.le_next = (elm)->field.le_next) != NULL)	\
20561cb6846SNiels Provos 		(elm2)->field.le_next->field.le_prev =			\
20661cb6846SNiels Provos 		    &(elm2)->field.le_next;				\
20761cb6846SNiels Provos 	(elm2)->field.le_prev = (elm)->field.le_prev;			\
20861cb6846SNiels Provos 	*(elm2)->field.le_prev = (elm2);				\
20961cb6846SNiels Provos } while (0)
21061cb6846SNiels Provos 
21161cb6846SNiels Provos /*
21261cb6846SNiels Provos  * Simple queue definitions.
21361cb6846SNiels Provos  */
21461cb6846SNiels Provos #define SIMPLEQ_HEAD(name, type)					\
21561cb6846SNiels Provos struct name {								\
21661cb6846SNiels Provos 	struct type *sqh_first;	/* first element */			\
21761cb6846SNiels Provos 	struct type **sqh_last;	/* addr of last next element */		\
21861cb6846SNiels Provos }
21961cb6846SNiels Provos 
22061cb6846SNiels Provos #define SIMPLEQ_HEAD_INITIALIZER(head)					\
22161cb6846SNiels Provos 	{ NULL, &(head).sqh_first }
22261cb6846SNiels Provos 
22361cb6846SNiels Provos #define SIMPLEQ_ENTRY(type)						\
22461cb6846SNiels Provos struct {								\
22561cb6846SNiels Provos 	struct type *sqe_next;	/* next element */			\
22661cb6846SNiels Provos }
22761cb6846SNiels Provos 
22861cb6846SNiels Provos /*
22961cb6846SNiels Provos  * Simple queue access methods.
23061cb6846SNiels Provos  */
23161cb6846SNiels Provos #define	SIMPLEQ_FIRST(head)	    ((head)->sqh_first)
23261cb6846SNiels Provos #define	SIMPLEQ_END(head)	    NULL
23361cb6846SNiels Provos #define	SIMPLEQ_EMPTY(head)	    (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
23461cb6846SNiels Provos #define	SIMPLEQ_NEXT(elm, field)    ((elm)->field.sqe_next)
23561cb6846SNiels Provos 
23661cb6846SNiels Provos #define SIMPLEQ_FOREACH(var, head, field)				\
23761cb6846SNiels Provos 	for((var) = SIMPLEQ_FIRST(head);				\
23861cb6846SNiels Provos 	    (var) != SIMPLEQ_END(head);					\
23961cb6846SNiels Provos 	    (var) = SIMPLEQ_NEXT(var, field))
24061cb6846SNiels Provos 
24161cb6846SNiels Provos /*
24261cb6846SNiels Provos  * Simple queue functions.
24361cb6846SNiels Provos  */
24461cb6846SNiels Provos #define	SIMPLEQ_INIT(head) do {						\
24561cb6846SNiels Provos 	(head)->sqh_first = NULL;					\
24661cb6846SNiels Provos 	(head)->sqh_last = &(head)->sqh_first;				\
24761cb6846SNiels Provos } while (0)
24861cb6846SNiels Provos 
24961cb6846SNiels Provos #define SIMPLEQ_INSERT_HEAD(head, elm, field) do {			\
25061cb6846SNiels Provos 	if (((elm)->field.sqe_next = (head)->sqh_first) == NULL)	\
25161cb6846SNiels Provos 		(head)->sqh_last = &(elm)->field.sqe_next;		\
25261cb6846SNiels Provos 	(head)->sqh_first = (elm);					\
25361cb6846SNiels Provos } while (0)
25461cb6846SNiels Provos 
25561cb6846SNiels Provos #define SIMPLEQ_INSERT_TAIL(head, elm, field) do {			\
25661cb6846SNiels Provos 	(elm)->field.sqe_next = NULL;					\
25761cb6846SNiels Provos 	*(head)->sqh_last = (elm);					\
25861cb6846SNiels Provos 	(head)->sqh_last = &(elm)->field.sqe_next;			\
25961cb6846SNiels Provos } while (0)
26061cb6846SNiels Provos 
26161cb6846SNiels Provos #define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
26261cb6846SNiels Provos 	if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
26361cb6846SNiels Provos 		(head)->sqh_last = &(elm)->field.sqe_next;		\
26461cb6846SNiels Provos 	(listelm)->field.sqe_next = (elm);				\
26561cb6846SNiels Provos } while (0)
26661cb6846SNiels Provos 
26761cb6846SNiels Provos #define SIMPLEQ_REMOVE_HEAD(head, elm, field) do {			\
26861cb6846SNiels Provos 	if (((head)->sqh_first = (elm)->field.sqe_next) == NULL)	\
26961cb6846SNiels Provos 		(head)->sqh_last = &(head)->sqh_first;			\
27061cb6846SNiels Provos } while (0)
27161cb6846SNiels Provos 
27261cb6846SNiels Provos /*
27361cb6846SNiels Provos  * Tail queue definitions.
27461cb6846SNiels Provos  */
27561cb6846SNiels Provos #define TAILQ_HEAD(name, type)						\
27661cb6846SNiels Provos struct name {								\
27761cb6846SNiels Provos 	struct type *tqh_first;	/* first element */			\
27861cb6846SNiels Provos 	struct type **tqh_last;	/* addr of last next element */		\
27961cb6846SNiels Provos }
28061cb6846SNiels Provos 
28161cb6846SNiels Provos #define TAILQ_HEAD_INITIALIZER(head)					\
28261cb6846SNiels Provos 	{ NULL, &(head).tqh_first }
28361cb6846SNiels Provos 
28461cb6846SNiels Provos #define TAILQ_ENTRY(type)						\
28561cb6846SNiels Provos struct {								\
28661cb6846SNiels Provos 	struct type *tqe_next;	/* next element */			\
28761cb6846SNiels Provos 	struct type **tqe_prev;	/* address of previous next element */	\
28861cb6846SNiels Provos }
28961cb6846SNiels Provos 
29061cb6846SNiels Provos /*
29161cb6846SNiels Provos  * tail queue access methods
29261cb6846SNiels Provos  */
29361cb6846SNiels Provos #define	TAILQ_FIRST(head)		((head)->tqh_first)
29461cb6846SNiels Provos #define	TAILQ_END(head)			NULL
29561cb6846SNiels Provos #define	TAILQ_NEXT(elm, field)		((elm)->field.tqe_next)
29661cb6846SNiels Provos #define TAILQ_LAST(head, headname)					\
29761cb6846SNiels Provos 	(*(((struct headname *)((head)->tqh_last))->tqh_last))
29861cb6846SNiels Provos /* XXX */
29961cb6846SNiels Provos #define TAILQ_PREV(elm, headname, field)				\
30061cb6846SNiels Provos 	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
30161cb6846SNiels Provos #define	TAILQ_EMPTY(head)						\
30261cb6846SNiels Provos 	(TAILQ_FIRST(head) == TAILQ_END(head))
30361cb6846SNiels Provos 
30461cb6846SNiels Provos #define TAILQ_FOREACH(var, head, field)					\
30561cb6846SNiels Provos 	for((var) = TAILQ_FIRST(head);					\
30661cb6846SNiels Provos 	    (var) != TAILQ_END(head);					\
30761cb6846SNiels Provos 	    (var) = TAILQ_NEXT(var, field))
30861cb6846SNiels Provos 
30971afc525SFrank Denis #define TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
31061cb6846SNiels Provos 	for((var) = TAILQ_LAST(head, headname);				\
31161cb6846SNiels Provos 	    (var) != TAILQ_END(head);					\
31261cb6846SNiels Provos 	    (var) = TAILQ_PREV(var, headname, field))
31361cb6846SNiels Provos 
31461cb6846SNiels Provos /*
31561cb6846SNiels Provos  * Tail queue functions.
31661cb6846SNiels Provos  */
31761cb6846SNiels Provos #define	TAILQ_INIT(head) do {						\
31861cb6846SNiels Provos 	(head)->tqh_first = NULL;					\
31961cb6846SNiels Provos 	(head)->tqh_last = &(head)->tqh_first;				\
32061cb6846SNiels Provos } while (0)
32161cb6846SNiels Provos 
32261cb6846SNiels Provos #define TAILQ_INSERT_HEAD(head, elm, field) do {			\
32361cb6846SNiels Provos 	if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)	\
32461cb6846SNiels Provos 		(head)->tqh_first->field.tqe_prev =			\
32561cb6846SNiels Provos 		    &(elm)->field.tqe_next;				\
32661cb6846SNiels Provos 	else								\
32761cb6846SNiels Provos 		(head)->tqh_last = &(elm)->field.tqe_next;		\
32861cb6846SNiels Provos 	(head)->tqh_first = (elm);					\
32961cb6846SNiels Provos 	(elm)->field.tqe_prev = &(head)->tqh_first;			\
33061cb6846SNiels Provos } while (0)
33161cb6846SNiels Provos 
33261cb6846SNiels Provos #define TAILQ_INSERT_TAIL(head, elm, field) do {			\
33361cb6846SNiels Provos 	(elm)->field.tqe_next = NULL;					\
33461cb6846SNiels Provos 	(elm)->field.tqe_prev = (head)->tqh_last;			\
33561cb6846SNiels Provos 	*(head)->tqh_last = (elm);					\
33661cb6846SNiels Provos 	(head)->tqh_last = &(elm)->field.tqe_next;			\
33761cb6846SNiels Provos } while (0)
33861cb6846SNiels Provos 
33961cb6846SNiels Provos #define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
34061cb6846SNiels Provos 	if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
34161cb6846SNiels Provos 		(elm)->field.tqe_next->field.tqe_prev =			\
34261cb6846SNiels Provos 		    &(elm)->field.tqe_next;				\
34361cb6846SNiels Provos 	else								\
34461cb6846SNiels Provos 		(head)->tqh_last = &(elm)->field.tqe_next;		\
34561cb6846SNiels Provos 	(listelm)->field.tqe_next = (elm);				\
34661cb6846SNiels Provos 	(elm)->field.tqe_prev = &(listelm)->field.tqe_next;		\
34761cb6846SNiels Provos } while (0)
34861cb6846SNiels Provos 
34961cb6846SNiels Provos #define	TAILQ_INSERT_BEFORE(listelm, elm, field) do {			\
35061cb6846SNiels Provos 	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
35161cb6846SNiels Provos 	(elm)->field.tqe_next = (listelm);				\
35261cb6846SNiels Provos 	*(listelm)->field.tqe_prev = (elm);				\
35361cb6846SNiels Provos 	(listelm)->field.tqe_prev = &(elm)->field.tqe_next;		\
35461cb6846SNiels Provos } while (0)
35561cb6846SNiels Provos 
35661cb6846SNiels Provos #define TAILQ_REMOVE(head, elm, field) do {				\
35761cb6846SNiels Provos 	if (((elm)->field.tqe_next) != NULL)				\
35861cb6846SNiels Provos 		(elm)->field.tqe_next->field.tqe_prev =			\
35961cb6846SNiels Provos 		    (elm)->field.tqe_prev;				\
36061cb6846SNiels Provos 	else								\
36161cb6846SNiels Provos 		(head)->tqh_last = (elm)->field.tqe_prev;		\
36261cb6846SNiels Provos 	*(elm)->field.tqe_prev = (elm)->field.tqe_next;			\
36361cb6846SNiels Provos } while (0)
36461cb6846SNiels Provos 
36561cb6846SNiels Provos #define TAILQ_REPLACE(head, elm, elm2, field) do {			\
36661cb6846SNiels Provos 	if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL)	\
36761cb6846SNiels Provos 		(elm2)->field.tqe_next->field.tqe_prev =		\
36861cb6846SNiels Provos 		    &(elm2)->field.tqe_next;				\
36961cb6846SNiels Provos 	else								\
37061cb6846SNiels Provos 		(head)->tqh_last = &(elm2)->field.tqe_next;		\
37161cb6846SNiels Provos 	(elm2)->field.tqe_prev = (elm)->field.tqe_prev;			\
37261cb6846SNiels Provos 	*(elm2)->field.tqe_prev = (elm2);				\
37361cb6846SNiels Provos } while (0)
37461cb6846SNiels Provos 
37561cb6846SNiels Provos /*
37661cb6846SNiels Provos  * Circular queue definitions.
37761cb6846SNiels Provos  */
37861cb6846SNiels Provos #define CIRCLEQ_HEAD(name, type)					\
37961cb6846SNiels Provos struct name {								\
38061cb6846SNiels Provos 	struct type *cqh_first;		/* first element */		\
38161cb6846SNiels Provos 	struct type *cqh_last;		/* last element */		\
38261cb6846SNiels Provos }
38361cb6846SNiels Provos 
38461cb6846SNiels Provos #define CIRCLEQ_HEAD_INITIALIZER(head)					\
38561cb6846SNiels Provos 	{ CIRCLEQ_END(&head), CIRCLEQ_END(&head) }
38661cb6846SNiels Provos 
38761cb6846SNiels Provos #define CIRCLEQ_ENTRY(type)						\
38861cb6846SNiels Provos struct {								\
38961cb6846SNiels Provos 	struct type *cqe_next;		/* next element */		\
39061cb6846SNiels Provos 	struct type *cqe_prev;		/* previous element */		\
39161cb6846SNiels Provos }
39261cb6846SNiels Provos 
39361cb6846SNiels Provos /*
39461cb6846SNiels Provos  * Circular queue access methods
39561cb6846SNiels Provos  */
39661cb6846SNiels Provos #define	CIRCLEQ_FIRST(head)		((head)->cqh_first)
39761cb6846SNiels Provos #define	CIRCLEQ_LAST(head)		((head)->cqh_last)
39861cb6846SNiels Provos #define	CIRCLEQ_END(head)		((void *)(head))
39961cb6846SNiels Provos #define	CIRCLEQ_NEXT(elm, field)	((elm)->field.cqe_next)
40061cb6846SNiels Provos #define	CIRCLEQ_PREV(elm, field)	((elm)->field.cqe_prev)
40161cb6846SNiels Provos #define	CIRCLEQ_EMPTY(head)						\
40261cb6846SNiels Provos 	(CIRCLEQ_FIRST(head) == CIRCLEQ_END(head))
40361cb6846SNiels Provos 
40461cb6846SNiels Provos #define CIRCLEQ_FOREACH(var, head, field)				\
40561cb6846SNiels Provos 	for((var) = CIRCLEQ_FIRST(head);				\
40661cb6846SNiels Provos 	    (var) != CIRCLEQ_END(head);					\
40761cb6846SNiels Provos 	    (var) = CIRCLEQ_NEXT(var, field))
40861cb6846SNiels Provos 
40961cb6846SNiels Provos #define CIRCLEQ_FOREACH_REVERSE(var, head, field)			\
41061cb6846SNiels Provos 	for((var) = CIRCLEQ_LAST(head);					\
41161cb6846SNiels Provos 	    (var) != CIRCLEQ_END(head);					\
41261cb6846SNiels Provos 	    (var) = CIRCLEQ_PREV(var, field))
41361cb6846SNiels Provos 
41461cb6846SNiels Provos /*
41561cb6846SNiels Provos  * Circular queue functions.
41661cb6846SNiels Provos  */
41761cb6846SNiels Provos #define	CIRCLEQ_INIT(head) do {						\
41861cb6846SNiels Provos 	(head)->cqh_first = CIRCLEQ_END(head);				\
41961cb6846SNiels Provos 	(head)->cqh_last = CIRCLEQ_END(head);				\
42061cb6846SNiels Provos } while (0)
42161cb6846SNiels Provos 
42261cb6846SNiels Provos #define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
42361cb6846SNiels Provos 	(elm)->field.cqe_next = (listelm)->field.cqe_next;		\
42461cb6846SNiels Provos 	(elm)->field.cqe_prev = (listelm);				\
42561cb6846SNiels Provos 	if ((listelm)->field.cqe_next == CIRCLEQ_END(head))		\
42661cb6846SNiels Provos 		(head)->cqh_last = (elm);				\
42761cb6846SNiels Provos 	else								\
42861cb6846SNiels Provos 		(listelm)->field.cqe_next->field.cqe_prev = (elm);	\
42961cb6846SNiels Provos 	(listelm)->field.cqe_next = (elm);				\
43061cb6846SNiels Provos } while (0)
43161cb6846SNiels Provos 
43261cb6846SNiels Provos #define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {		\
43361cb6846SNiels Provos 	(elm)->field.cqe_next = (listelm);				\
43461cb6846SNiels Provos 	(elm)->field.cqe_prev = (listelm)->field.cqe_prev;		\
43561cb6846SNiels Provos 	if ((listelm)->field.cqe_prev == CIRCLEQ_END(head))		\
43661cb6846SNiels Provos 		(head)->cqh_first = (elm);				\
43761cb6846SNiels Provos 	else								\
43861cb6846SNiels Provos 		(listelm)->field.cqe_prev->field.cqe_next = (elm);	\
43961cb6846SNiels Provos 	(listelm)->field.cqe_prev = (elm);				\
44061cb6846SNiels Provos } while (0)
44161cb6846SNiels Provos 
44261cb6846SNiels Provos #define CIRCLEQ_INSERT_HEAD(head, elm, field) do {			\
44361cb6846SNiels Provos 	(elm)->field.cqe_next = (head)->cqh_first;			\
44461cb6846SNiels Provos 	(elm)->field.cqe_prev = CIRCLEQ_END(head);			\
44561cb6846SNiels Provos 	if ((head)->cqh_last == CIRCLEQ_END(head))			\
44661cb6846SNiels Provos 		(head)->cqh_last = (elm);				\
44761cb6846SNiels Provos 	else								\
44861cb6846SNiels Provos 		(head)->cqh_first->field.cqe_prev = (elm);		\
44961cb6846SNiels Provos 	(head)->cqh_first = (elm);					\
45061cb6846SNiels Provos } while (0)
45161cb6846SNiels Provos 
45261cb6846SNiels Provos #define CIRCLEQ_INSERT_TAIL(head, elm, field) do {			\
45361cb6846SNiels Provos 	(elm)->field.cqe_next = CIRCLEQ_END(head);			\
45461cb6846SNiels Provos 	(elm)->field.cqe_prev = (head)->cqh_last;			\
45561cb6846SNiels Provos 	if ((head)->cqh_first == CIRCLEQ_END(head))			\
45661cb6846SNiels Provos 		(head)->cqh_first = (elm);				\
45761cb6846SNiels Provos 	else								\
45861cb6846SNiels Provos 		(head)->cqh_last->field.cqe_next = (elm);		\
45961cb6846SNiels Provos 	(head)->cqh_last = (elm);					\
46061cb6846SNiels Provos } while (0)
46161cb6846SNiels Provos 
46261cb6846SNiels Provos #define	CIRCLEQ_REMOVE(head, elm, field) do {				\
46361cb6846SNiels Provos 	if ((elm)->field.cqe_next == CIRCLEQ_END(head))			\
46461cb6846SNiels Provos 		(head)->cqh_last = (elm)->field.cqe_prev;		\
46561cb6846SNiels Provos 	else								\
46661cb6846SNiels Provos 		(elm)->field.cqe_next->field.cqe_prev =			\
46761cb6846SNiels Provos 		    (elm)->field.cqe_prev;				\
46861cb6846SNiels Provos 	if ((elm)->field.cqe_prev == CIRCLEQ_END(head))			\
46961cb6846SNiels Provos 		(head)->cqh_first = (elm)->field.cqe_next;		\
47061cb6846SNiels Provos 	else								\
47161cb6846SNiels Provos 		(elm)->field.cqe_prev->field.cqe_next =			\
47261cb6846SNiels Provos 		    (elm)->field.cqe_next;				\
47361cb6846SNiels Provos } while (0)
47461cb6846SNiels Provos 
47561cb6846SNiels Provos #define CIRCLEQ_REPLACE(head, elm, elm2, field) do {			\
47661cb6846SNiels Provos 	if (((elm2)->field.cqe_next = (elm)->field.cqe_next) ==		\
47761cb6846SNiels Provos 	    CIRCLEQ_END(head))						\
47861cb6846SNiels Provos 		(head).cqh_last = (elm2);				\
47961cb6846SNiels Provos 	else								\
48061cb6846SNiels Provos 		(elm2)->field.cqe_next->field.cqe_prev = (elm2);	\
48161cb6846SNiels Provos 	if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) ==		\
48261cb6846SNiels Provos 	    CIRCLEQ_END(head))						\
48361cb6846SNiels Provos 		(head).cqh_first = (elm2);				\
48461cb6846SNiels Provos 	else								\
48561cb6846SNiels Provos 		(elm2)->field.cqe_prev->field.cqe_next = (elm2);	\
48661cb6846SNiels Provos } while (0)
48761cb6846SNiels Provos 
488*cb9da0bfSNick Mathewson #endif	/* !SYS_QUEUE_H__ */
489