/******************************************************************************* *Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved. * *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. * *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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 * * $FreeBSD$ * ********************************************************************************/ /*******************************************************************************/ /*! \file sallist.h * \brief The file contains link list manipulation helper routines * */ /*******************************************************************************/ #ifndef __SALLIST_H__ #define __SALLIST_H__ /******************************************************************** ********************************************************************* ** DATA STRUCTURES ********************************************************************/ /** \brief Structure of Link Data * * link data, need to be included at the start (offset 0) * of any structures that are to be stored in the link list * */ typedef struct _SALINK { struct _SALINK *pNext; struct _SALINK *pPrev; /* ** for assertion purpose only */ struct _SALINK * pHead; /* track the link list the link is a member of */ } SALINK, * PSALINK; /** \brief Structure of Link List * * link list basic pointers * */ typedef struct _SALINK_LIST { PSALINK pHead; bit32 Count; SALINK Head; /* allways one link to speed up insert and delete */ } SALINK_LIST, * PSALINK_LIST; /******************************************************************** ********************************************************************* ** MACROS ********************************************************************/ /*! \def saLlistInitialize(pList) * \brief saLlistInitialize macro * * use to initialize a Link List */ /******************************************************************************* ******************************************************************************** ** ** MODULE NAME: saLlistInitialize ** ** PURPOSE: Initialize a link list. ** ** PARAMETERS: PSALINK_LIST OUT - Link list definition. ** ** SIDE EFFECTS & CAVEATS: ** ** ALGORITHM: ** ********************************************************************************/ /*lint -emacro(613,saLlistInitialize) */ #define saLlistInitialize(pList) {(pList)->pHead = &((pList)->Head); \ (pList)->pHead->pNext = (pList)->pHead; \ (pList)->pHead->pPrev = (pList)->pHead; \ (pList)->Count = 0; \ } #define saLlistIOInitialize(pList){(pList)->pHead = &((pList)->Head); \ (pList)->pHead->pNext = (pList)->pHead; \ (pList)->pHead->pPrev = (pList)->pHead; \ (pList)->Count = 0; \ } /*! \def saLlinkInitialize(pLink) * \brief saLlinkInitialize macro * * use to initialize a Link */ /******************************************************************************** ******************************************************************************** ** ** MODULE NAME: saLlinkInitialize ** ** PURPOSE: Initialize a link. ** This function should be used to initialize a new link before it ** is used in the linked list. This will initialize the link so ** the assertion will work ** ** PARAMETERS: PSALINK IN - Link to be initialized. ** ** SIDE EFFECTS & CAVEATS: ** ** ALGORITHM: ** ******************************************************************************** *******************************************************************************/ /*lint -emacro(613,saLlinkInitialize) */ #define saLlinkInitialize(pLink) { (pLink)->pHead = agNULL; \ (pLink)->pNext = agNULL; \ (pLink)->pPrev = agNULL; \ } #define saLlinkIOInitialize(pLink) { (pLink)->pHead = agNULL; \ (pLink)->pNext = agNULL; \ (pLink)->pPrev = agNULL; \ } /*! \def saLlistAdd(pList, pLink) * \brief saLlistAdd macro * * use to add a link to the tail of list */ /******************************************************************************** ******************************************************************************** ** ** MODULE NAME: saLlistAdd ** ** PURPOSE: add a link at the tail of the list ** ** PARAMETERS: PSALINK_LIST OUT - Link list definition. ** PSALINK IN - Link to be inserted. ** ** SIDE EFFECTS & CAVEATS: ** !!! assumes that fcllistInitialize has been called on the linklist ** !!! if not, this function behavior is un-predictable ** ** The OS_ASSERT() is an assignment for debug code only ** ** ALGORITHM: ** ******************************************************************************** *******************************************************************************/ /*lint -emacro(506,saLlistAdd) */ /*lint -emacro(613,saLlistAdd) */ /*lint -emacro(666,saLlistAdd) */ /*lint -emacro(720,saLlistAdd) */ #define saLlistAdd(pList, pLink) { \ (pLink)->pNext = (pList)->pHead; \ (pLink)->pPrev = (pList)->pHead->pPrev; \ (pLink)->pPrev->pNext = (pLink); \ (pList)->pHead->pPrev = (pLink); \ (pList)->Count ++; \ (pLink)->pHead = (pList)->pHead; \ } #define saLlistIOAdd(pList, pLink) { \ (pLink)->pNext = (pList)->pHead; \ (pLink)->pPrev = (pList)->pHead->pPrev; \ (pLink)->pPrev->pNext = (pLink); \ (pList)->pHead->pPrev = (pLink); \ (pList)->Count ++; \ (pLink)->pHead = (pList)->pHead; \ } /*! \def saLlistInsert(pList, pLink, pNew) * \brief saLlistInsert macro * * use to insert a link preceding the given one */ /******************************************************************************** ******************************************************************************** ** ** MODULE NAME: saLlistInsert ** ** PURPOSE: insert a link preceding the given one ** ** PARAMETERS: PSALINK_LIST OUT - Link list definition. ** PSALINK IN - Link to be inserted after. ** PSALINK IN - Link to be inserted. ** ** SIDE EFFECTS & CAVEATS: ** !!! assumes that fcllistInitialize has been called on the linklist ** !!! if not, this function behavior is un-predictable ** ** The OS_ASSERT() is an assignment for debug code only ** ** ALGORITHM: ** ******************************************************************************** *******************************************************************************/ /*lint -emacro(506,saLlistInsert) */ /*lint -emacro(613,saLlistInsert) */ /*lint -emacro(666,saLlistInsert) */ /*lint -emacro(720,saLlistInsert) */ #define saLlistInsert(pList, pLink, pNew) { \ (pNew)->pNext = (pLink); \ (pNew)->pPrev = (pLink)->pPrev; \ (pNew)->pPrev->pNext = (pNew); \ (pLink)->pPrev = (pNew); \ (pList)->Count ++; \ (pNew)->pHead = (pList)->pHead; \ } /*! \def saLlistRemove(pList, pLink) * \brief saLlistRemove macro * * use to remove the link from the list */ /******************************************************************************** ******************************************************************************** ** ** MODULE NAME: saLlistRemove ** ** PURPOSE: remove the link from the list. ** ** PARAMETERS: PSALINK_LIST OUT - Link list definition. ** PSALINK IN - Link to delet from list ** ** SIDE EFFECTS & CAVEATS: ** !!! assumes that fcllistInitialize has been called on the linklist ** !!! if not, this function behavior is un-predictable ** ** !!! No validation is made on the list or the validity of the link ** !!! the caller must make sure that the link is in the list ** ** ** ALGORITHM: ** ******************************************************************************** *******************************************************************************/ /*lint -emacro(506,saLlistRemove) */ /*lint -emacro(613,saLlistRemove) */ /*lint -emacro(666,saLlistRemove) */ /*lint -emacro(720,saLlistRemove) */ #define saLlistRemove(pList, pLink) { \ (pLink)->pPrev->pNext = (pLink)->pNext; \ (pLink)->pNext->pPrev = (pLink)->pPrev; \ (pLink)->pHead = agNULL; \ (pList)->Count --; \ } #define saLlistIORemove(pList, pLink) { \ (pLink)->pPrev->pNext = (pLink)->pNext; \ (pLink)->pNext->pPrev = (pLink)->pPrev; \ (pLink)->pHead = agNULL; \ (pList)->Count --; \ } /*! \def saLlistGetHead(pList) * \brief saLlistGetHead macro * * use to get the link following the head link */ /******************************************************************************** ******************************************************************************** ** ** MODULE NAME: saLlistGetHead ** ** PURPOSE: get the link following the head link. ** ** PARAMETERS: PSALINK_LIST OUT - Link list definition. ** RETURNS - PSALINK the link following the head ** agNULL if the following link is the head ** ** SIDE EFFECTS & CAVEATS: ** !!! assumes that fcllistInitialize has been called on the linklist ** !!! if not, this function behavior is un-predictable ** ** ALGORITHM: ** ******************************************************************************** *******************************************************************************/ #define saLlistGetHead(pList) saLlistGetNext(pList,(pList)->pHead) #define saLlistIOGetHead(pList) saLlistGetNext(pList,(pList)->pHead) /*! \def saLlistGetTail(pList) * \brief saLlistGetTail macro * * use to get the link preceding the tail link */ /******************************************************************************** ******************************************************************************** ** ** MODULE NAME: saLlistGetTail ** ** PURPOSE: get the link preceding the tail link. ** ** PARAMETERS: PSALINK_LIST OUT - Link list definition. ** RETURNS - PSALINK the link preceding the head ** agNULL if the preceding link is the head ** ** SIDE EFFECTS & CAVEATS: ** ** ALGORITHM: ** ******************************************************************************** *******************************************************************************/ #define saLlistGetTail(pList) saLlistGetPrev((pList), (pList)->pHead) /*! \def saLlistGetCount(pList) * \brief saLlistGetCount macro * * use to get the number of links in the list excluding head and tail */ /******************************************************************************** ******************************************************************************** ** ** MODULE NAME: saLlistGetCount ** ** PURPOSE: get the number of links in the list excluding head and tail. ** ** PARAMETERS: PSALINK_LIST OUT - Link list definition. ** ** SIDE EFFECTS & CAVEATS: ** !!! assumes that fcllistInitialize has been called on the linklist ** !!! if not, this function behavior is un-predictable ** ** ALGORITHM: ** ******************************************************************************** *******************************************************************************/ /*lint -emacro(613,saLlistGetCount) */ /*lint -emacro(666,saLlistGetCount) */ #define saLlistGetCount(pList) ((pList)->Count) #define saLlistIOGetCount(pList) ((pList)->Count) /*! \def saLlistGetNext(pList, pLink) * \brief saLlistGetNext macro * * use to get the next link in the list */ /******************************************************************************** ******************************************************************************** ** ** MODULE NAME: saLlistGetNext ** ** PURPOSE: get the next link in the list. (one toward tail) ** ** PARAMETERS: PSALINK_LIST OUT - Link list definition. ** PSALINK IN - Link to get next to ** ** return PLINK - points to next link ** agNULL if next link is head ** ** SIDE EFFECTS & CAVEATS: ** !!! assumes that fcllistInitialize has been called on the linklist ** !!! if not, this function behavior is un-predictable ** ** !!! No validation is made on the list or the validity of the link ** !!! the caller must make sure that the link is in the list ** ** ALGORITHM: ** ******************************************************************************** *******************************************************************************/ /*lint -emacro(613,saLlistGetNext) */ #define saLlistGetNext(pList, pLink) (((pLink)->pNext == (pList)->pHead) ? \ agNULL : (pLink)->pNext) #define saLlistIOGetNext(pList, pLink) (((pLink)->pNext == (pList)->pHead) ? \ agNULL : (pLink)->pNext) /*! \def saLlistGetPrev(pList, pLink) * \brief saLlistGetPrev macro * * use to get the previous link in the list */ /******************************************************************************** ******************************************************************************** ** ** MODULE NAME: saLlistGetPrev ** ** PURPOSE: get the previous link in the list. (one toward head) ** ** PARAMETERS: PSALINK_LIST OUT - Link list definition. ** PSALINK IN - Link to get prev to ** ** return PLINK - points to previous link ** agNULL if previous link is head ** ** SIDE EFFECTS & CAVEATS: ** !!! assumes that fcllistInitialize has been called on the linklist ** !!! if not, this function behavior is un-predictable ** ** !!! No validation is made on the list or the validity of the link ** !!! the caller must make sure that the link is in the list ** ** ALGORITHM: ** ******************************************************************************** *******************************************************************************/ /*lint -emacro(613,saLlistGetPrev) */ #define saLlistGetPrev(pList, pLink) (((pLink)->pPrev == (pList)->pHead) ? \ agNULL : (pLink)->pPrev) #define agObjectBase(baseType,fieldName,fieldPtr) \ (void * ) fieldPtr == (void *) 0 ? (baseType *) 0 : \ ((baseType *)((bit8 *)(fieldPtr) - ((bitptr)(&(((baseType *)0)->fieldName))))) #endif /* #ifndef __SALLIST_H__*/