/*************************************************************************** * * Copyright (C) 2001 International Business Machines * All rights reserved. * * This file is part of the GPFS mmfslinux kernel module. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *************************************************************************** */ /* @(#)02 1.9 src/avs/fs/mmfs/ts/kernext/ibm-kxi/cxiLinkList.h, mmfs, avs_rgpfs24, rgpfs240610b 8/4/04 11:54:21 */ #ifndef _h_CXILINKLIST #define _h_CXILINKLIST #include #include #ifdef __cplusplus /* A double linked list element class. */ class DLink_t { public: DLink_tSXPtr nextP; DLink_tSXPtr prevP; /* The head element of the list is initialized to point to itself, * signifying no elements on the list. */ inline void init() { nextP = this; prevP = this; } DLink_t() { init(); } /* Add an element or circular linked list of elements, immediately * after this (head of the list) */ inline void enqueueHead(DLink_t *elementP) { DLink_t *saveP = elementP->prevP; saveP->nextP = nextP; nextP->prevP = saveP; elementP->prevP = this; nextP = elementP; } /* Add an element or circular linked list of elements, immediately * preceding this (tail of the list) */ inline void enqueueTail(DLink_t *elementP) { DLink_t *saveP = elementP->prevP; prevP->nextP = elementP; elementP->prevP = prevP; prevP = saveP; saveP->nextP = this; } /* Remove a single element from the linked list and * initialize it as a linked list pointing to itself */ inline DLink_t *dequeue() { prevP->nextP = nextP; nextP->prevP = prevP; init(); return this; } /* Remove the element immediately after this (head of the list) * and initialize it as a linked list pointing to itself. */ inline DLink_t *dequeueHead() { return nextP->dequeue(); } /* Remove the element immediately preceeding this (tail of the list) * and initialize it as a linked list pointing to itself. */ inline DLink_t *dequeueTail() { return prevP->dequeue(); } inline Boolean isEmpty() { return (nextP == this); } inline DLink_t *next() { return nextP; } inline DLink_t *prev() { return prevP; } inline DLink_t *head() { return nextP; } inline DLink_t *tail() { return prevP; } }; #else /* The same class as above, declared as a structure for C code */ struct DLink_t { /* Use standard pointers here for the portability layer / kernel. */ struct DLink_t *nextP; struct DLink_t *prevP; }; typedef struct DLink_t DLink_t; #endif /* __cplusplus */ /* Inline functions mimic'ing the class members of the DLink class. * Can be used in either C or C++ code. */ static inline void DLinkInit(DLink_t *thisP) { thisP->nextP = thisP; thisP->prevP = thisP; } /* Add an element or circular linked list of elements, immediately * after this (head of the list) */ static inline void DLinkEnqueueHead(DLink_t *thisP, DLink_t *elementP) { DLink_t *saveP = elementP->prevP; saveP->nextP = thisP->nextP; thisP->nextP->prevP = saveP; elementP->prevP = thisP; thisP->nextP = elementP; } /* Add an element or circular linked list of elements, immediately * preceding this (tail of the list) */ static inline void DLinkEnqueueTail(DLink_t *thisP, DLink_t *elementP) { DLink_t *saveP = elementP->prevP; thisP->prevP->nextP = elementP; elementP->prevP = thisP->prevP; thisP->prevP = saveP; saveP->nextP = thisP; } /* Remove a single element from the linked list and * initialize it as a linked list pointing to itself */ static inline DLink_t * DLinkDequeue(DLink_t *thisP) { thisP->prevP->nextP = thisP->nextP; thisP->nextP->prevP = thisP->prevP; DLinkInit(thisP); return thisP; } /* Remove the element immediately after this (head of the list) * and initialize it as a linked list pointing to itself. */ static inline DLink_t * DLinkDequeueHead(DLink_t *thisP) { return DLinkDequeue(thisP->nextP); } /* Remove the element immediately preceeding this (tail of the list) * and initialize it as a linked list pointing to itself. */ static inline DLink_t * DLinkDequeueTail(DLink_t *thisP) { return DLinkDequeue(thisP->prevP); } static inline Boolean DLinkIsEmpty(DLink_t *thisP) { return (thisP->nextP == thisP); } /* Given a class type, a pointer to the class member, and the * member name, return a pointer to the base class. */ #define MemberToClass(CLASSTYPE, PTRMEMBER, MEMBERNAME) \ (CLASSTYPE *)(((char *)PTRMEMBER) - OFFSET_OF(MEMBERNAME, CLASSTYPE)) #endif /* _h_CXILINKLIST */