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