Path: blob/main/crypto/krb5/src/plugins/kdb/db2/libdb2/include/db-queue.h
34928 views
/*1* Copyright (c) 1991, 19932* The Regents of the University of California. All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12* 3. All advertising materials mentioning features or use of this software13* must display the following acknowledgement:14* This product includes software developed by the University of15* California, Berkeley and its contributors.16* 4. Neither the name of the University nor the names of its contributors17* may be used to endorse or promote products derived from this software18* without specific prior written permission.19*20* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND21* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE22* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE23* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE24* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL25* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS26* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)27* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT28* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY29* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF30* SUCH DAMAGE.31*32* @(#)queue.h 8.3 (Berkeley) 12/13/9333*/3435#ifndef _QUEUE_H_36#define _QUEUE_H_3738/*39* This file defines three types of data structures: lists, tail queues,40* and circular queues.41*42* A list is headed by a single forward pointer (or an array of forward43* pointers for a hash table header). The elements are doubly linked44* so that an arbitrary element can be removed without a need to45* traverse the list. New elements can be added to the list after46* an existing element or at the head of the list. A list may only be47* traversed in the forward direction.48*49* A tail queue is headed by a pair of pointers, one to the head of the50* list and the other to the tail of the list. The elements are doubly51* linked so that an arbitrary element can be removed without a need to52* traverse the list. New elements can be added to the list after53* an existing element, at the head of the list, or at the end of the54* list. A tail queue may only be traversed in the forward direction.55*56* A circle queue is headed by a pair of pointers, one to the head of the57* list and the other to the tail of the list. The elements are doubly58* linked so that an arbitrary element can be removed without a need to59* traverse the list. New elements can be added to the list before or after60* an existing element, at the head of the list, or at the end of the list.61* A circle queue may be traversed in either direction, but has a more62* complex end of list detection.63*64* For details on the use of these macros, see the queue(3) manual page.65*/6667/*68* List definitions.69*/70#define LIST_HEAD(name, type) \71struct name { \72struct type *lh_first; /* first element */ \73}7475#define LIST_ENTRY(type) \76struct { \77struct type *le_next; /* next element */ \78struct type **le_prev; /* address of previous next element */ \79}8081/*82* List functions.83*/84#define LIST_INIT(head) { \85(head)->lh_first = NULL; \86}8788#define LIST_INSERT_AFTER(listelm, elm, field) { \89if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \90(listelm)->field.le_next->field.le_prev = \91&(elm)->field.le_next; \92(listelm)->field.le_next = (elm); \93(elm)->field.le_prev = &(listelm)->field.le_next; \94}9596#define LIST_INSERT_HEAD(head, elm, field) { \97if (((elm)->field.le_next = (head)->lh_first) != NULL) \98(head)->lh_first->field.le_prev = &(elm)->field.le_next;\99(head)->lh_first = (elm); \100(elm)->field.le_prev = &(head)->lh_first; \101}102103#define LIST_REMOVE(elm, field) { \104if ((elm)->field.le_next != NULL) \105(elm)->field.le_next->field.le_prev = \106(elm)->field.le_prev; \107*(elm)->field.le_prev = (elm)->field.le_next; \108}109110/*111* Tail queue definitions.112*/113#define TAILQ_HEAD(name, type) \114struct name { \115struct type *tqh_first; /* first element */ \116struct type **tqh_last; /* addr of last next element */ \117}118119#define TAILQ_ENTRY(type) \120struct { \121struct type *tqe_next; /* next element */ \122struct type **tqe_prev; /* address of previous next element */ \123}124125/*126* Tail queue functions.127*/128#define TAILQ_INIT(head) { \129(head)->tqh_first = NULL; \130(head)->tqh_last = &(head)->tqh_first; \131}132133#define TAILQ_INSERT_HEAD(head, elm, field) { \134if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \135(elm)->field.tqe_next->field.tqe_prev = \136&(elm)->field.tqe_next; \137else \138(head)->tqh_last = &(elm)->field.tqe_next; \139(head)->tqh_first = (elm); \140(elm)->field.tqe_prev = &(head)->tqh_first; \141}142143#define TAILQ_INSERT_TAIL(head, elm, field) { \144(elm)->field.tqe_next = NULL; \145(elm)->field.tqe_prev = (head)->tqh_last; \146*(head)->tqh_last = (elm); \147(head)->tqh_last = &(elm)->field.tqe_next; \148}149150#define TAILQ_INSERT_AFTER(head, listelm, elm, field) { \151if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\152(elm)->field.tqe_next->field.tqe_prev = \153&(elm)->field.tqe_next; \154else \155(head)->tqh_last = &(elm)->field.tqe_next; \156(listelm)->field.tqe_next = (elm); \157(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \158}159160#define TAILQ_REMOVE(head, elm, field) { \161if (((elm)->field.tqe_next) != NULL) \162(elm)->field.tqe_next->field.tqe_prev = \163(elm)->field.tqe_prev; \164else \165(head)->tqh_last = (elm)->field.tqe_prev; \166*(elm)->field.tqe_prev = (elm)->field.tqe_next; \167}168169/*170* Circular queue definitions.171*/172#define CIRCLEQ_HEAD(name, type) \173struct name { \174struct type *cqh_first; /* first element */ \175struct type *cqh_last; /* last element */ \176}177178#define CIRCLEQ_ENTRY(type) \179struct { \180struct type *cqe_next; /* next element */ \181struct type *cqe_prev; /* previous element */ \182}183184/*185* Circular queue functions.186*/187#define CIRCLEQ_INIT(head) { \188(head)->cqh_first = (void *)(head); \189(head)->cqh_last = (void *)(head); \190}191192#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) { \193(elm)->field.cqe_next = (listelm)->field.cqe_next; \194(elm)->field.cqe_prev = (listelm); \195if ((listelm)->field.cqe_next == (void *)(head)) \196(head)->cqh_last = (elm); \197else \198(listelm)->field.cqe_next->field.cqe_prev = (elm); \199(listelm)->field.cqe_next = (elm); \200}201202#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) { \203(elm)->field.cqe_next = (listelm); \204(elm)->field.cqe_prev = (listelm)->field.cqe_prev; \205if ((listelm)->field.cqe_prev == (void *)(head)) \206(head)->cqh_first = (elm); \207else \208(listelm)->field.cqe_prev->field.cqe_next = (elm); \209(listelm)->field.cqe_prev = (elm); \210}211212#define CIRCLEQ_INSERT_HEAD(head, elm, field) { \213(elm)->field.cqe_next = (head)->cqh_first; \214(elm)->field.cqe_prev = (void *)(head); \215if ((head)->cqh_last == (void *)(head)) \216(head)->cqh_last = (elm); \217else \218(head)->cqh_first->field.cqe_prev = (elm); \219(head)->cqh_first = (elm); \220}221222#define CIRCLEQ_INSERT_TAIL(head, elm, field) { \223(elm)->field.cqe_next = (void *)(head); \224(elm)->field.cqe_prev = (head)->cqh_last; \225if ((head)->cqh_first == (void *)(head)) \226(head)->cqh_first = (elm); \227else \228(head)->cqh_last->field.cqe_next = (elm); \229(head)->cqh_last = (elm); \230}231232#define CIRCLEQ_REMOVE(head, elm, field) { \233if ((elm)->field.cqe_next == (void *)(head)) \234(head)->cqh_last = (elm)->field.cqe_prev; \235else \236(elm)->field.cqe_next->field.cqe_prev = \237(elm)->field.cqe_prev; \238if ((elm)->field.cqe_prev == (void *)(head)) \239(head)->cqh_first = (elm)->field.cqe_next; \240else \241(elm)->field.cqe_prev->field.cqe_next = \242(elm)->field.cqe_next; \243}244#endif /* !_QUEUE_H_ */245246247