1 /*******************************************************************************
2 *Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved.
4 *Redistribution and use in source and binary forms, with or without modification, are permitted provided
5 *that the following conditions are met:
6 *1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
8 *2. Redistributions in binary form must reproduce the above copyright notice,
9 *this list of conditions and the following disclaimer in the documentation and/or other materials provided
10 *with the distribution.
12 *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
13 *WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14 *FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
15 *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16 *NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
17 *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18 *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
23 ********************************************************************************/
24 /*******************************************************************************/
26 * \brief The file contains link list manipulation helper routines
29 /*******************************************************************************/
35 /********************************************************************
36 *********************************************************************
38 ********************************************************************/
40 /** \brief Structure of Link Data
42 * link data, need to be included at the start (offset 0)
43 * of any strutures that are to be stored in the link list
46 typedef struct _SALINK
48 struct _SALINK *pNext;
49 struct _SALINK *pPrev;
52 ** for assertion purpose only
54 struct _SALINK * pHead; /* track the link list the link is a member of */
58 /** \brief Structure of Link List
60 * link list basic pointers
63 typedef struct _SALINK_LIST
68 SALINK Head; /* allways one link to speed up insert and delete */
70 } SALINK_LIST, * PSALINK_LIST;
73 /********************************************************************
74 *********************************************************************
76 ********************************************************************/
78 /*! \def saLlistInitialize(pList)
79 * \brief saLlistInitialize macro
81 * use to initialize a Link List
83 /*******************************************************************************
84 ********************************************************************************
86 ** MODULE NAME: saLlistInitialize
88 ** PURPOSE: Initialize a link list.
90 ** PARAMETERS: PSALINK_LIST OUT - Link list definition.
92 ** SIDE EFFECTS & CAVEATS:
96 ********************************************************************************/
97 /*lint -emacro(613,saLlistInitialize) */
99 #define saLlistInitialize(pList) {(pList)->pHead = &((pList)->Head); \
100 (pList)->pHead->pNext = (pList)->pHead; \
101 (pList)->pHead->pPrev = (pList)->pHead; \
102 (pList)->Count = 0; \
105 #define saLlistIOInitialize(pList){(pList)->pHead = &((pList)->Head); \
106 (pList)->pHead->pNext = (pList)->pHead; \
107 (pList)->pHead->pPrev = (pList)->pHead; \
108 (pList)->Count = 0; \
110 /*! \def saLlinkInitialize(pLink)
111 * \brief saLlinkInitialize macro
113 * use to initialize a Link
115 /********************************************************************************
116 ********************************************************************************
118 ** MODULE NAME: saLlinkInitialize
120 ** PURPOSE: Initialize a link.
121 ** This function should be used to initialize a new link before it
122 ** is used in the linked list. This will initialize the link so
123 ** the assertion will work
125 ** PARAMETERS: PSALINK IN - Link to be initialized.
127 ** SIDE EFFECTS & CAVEATS:
131 ********************************************************************************
132 *******************************************************************************/
134 /*lint -emacro(613,saLlinkInitialize) */
136 #define saLlinkInitialize(pLink) { (pLink)->pHead = agNULL; \
137 (pLink)->pNext = agNULL; \
138 (pLink)->pPrev = agNULL; \
141 #define saLlinkIOInitialize(pLink) { (pLink)->pHead = agNULL; \
142 (pLink)->pNext = agNULL; \
143 (pLink)->pPrev = agNULL; \
145 /*! \def saLlistAdd(pList, pLink)
146 * \brief saLlistAdd macro
148 * use to add a link to the tail of list
150 /********************************************************************************
151 ********************************************************************************
153 ** MODULE NAME: saLlistAdd
155 ** PURPOSE: add a link at the tail of the list
157 ** PARAMETERS: PSALINK_LIST OUT - Link list definition.
158 ** PSALINK IN - Link to be inserted.
160 ** SIDE EFFECTS & CAVEATS:
161 ** !!! assumes that fcllistInitialize has been called on the linklist
162 ** !!! if not, this function behavior is un-predictable
164 ** The OS_ASSERT() is an assignment for debug code only
168 ********************************************************************************
169 *******************************************************************************/
171 /*lint -emacro(506,saLlistAdd) */
172 /*lint -emacro(613,saLlistAdd) */
173 /*lint -emacro(666,saLlistAdd) */
174 /*lint -emacro(720,saLlistAdd) */
176 #define saLlistAdd(pList, pLink) { \
177 (pLink)->pNext = (pList)->pHead; \
178 (pLink)->pPrev = (pList)->pHead->pPrev; \
179 (pLink)->pPrev->pNext = (pLink); \
180 (pList)->pHead->pPrev = (pLink); \
182 (pLink)->pHead = (pList)->pHead; \
185 #define saLlistIOAdd(pList, pLink) { \
186 (pLink)->pNext = (pList)->pHead; \
187 (pLink)->pPrev = (pList)->pHead->pPrev; \
188 (pLink)->pPrev->pNext = (pLink); \
189 (pList)->pHead->pPrev = (pLink); \
191 (pLink)->pHead = (pList)->pHead; \
194 /*! \def saLlistInsert(pList, pLink, pNew)
195 * \brief saLlistInsert macro
197 * use to insert a link preceding the given one
199 /********************************************************************************
200 ********************************************************************************
202 ** MODULE NAME: saLlistInsert
204 ** PURPOSE: insert a link preceding the given one
206 ** PARAMETERS: PSALINK_LIST OUT - Link list definition.
207 ** PSALINK IN - Link to be inserted after.
208 ** PSALINK IN - Link to be inserted.
210 ** SIDE EFFECTS & CAVEATS:
211 ** !!! assumes that fcllistInitialize has been called on the linklist
212 ** !!! if not, this function behavior is un-predictable
214 ** The OS_ASSERT() is an assignment for debug code only
218 ********************************************************************************
219 *******************************************************************************/
221 /*lint -emacro(506,saLlistInsert) */
222 /*lint -emacro(613,saLlistInsert) */
223 /*lint -emacro(666,saLlistInsert) */
224 /*lint -emacro(720,saLlistInsert) */
226 #define saLlistInsert(pList, pLink, pNew) { \
227 (pNew)->pNext = (pLink); \
228 (pNew)->pPrev = (pLink)->pPrev; \
229 (pNew)->pPrev->pNext = (pNew); \
230 (pLink)->pPrev = (pNew); \
232 (pNew)->pHead = (pList)->pHead; \
235 /*! \def saLlistRemove(pList, pLink)
236 * \brief saLlistRemove macro
238 * use to remove the link from the list
240 /********************************************************************************
241 ********************************************************************************
243 ** MODULE NAME: saLlistRemove
245 ** PURPOSE: remove the link from the list.
247 ** PARAMETERS: PSALINK_LIST OUT - Link list definition.
248 ** PSALINK IN - Link to delet from list
250 ** SIDE EFFECTS & CAVEATS:
251 ** !!! assumes that fcllistInitialize has been called on the linklist
252 ** !!! if not, this function behavior is un-predictable
254 ** !!! No validation is made on the list or the validity of the link
255 ** !!! the caller must make sure that the link is in the list
260 ********************************************************************************
261 *******************************************************************************/
263 /*lint -emacro(506,saLlistRemove) */
264 /*lint -emacro(613,saLlistRemove) */
265 /*lint -emacro(666,saLlistRemove) */
266 /*lint -emacro(720,saLlistRemove) */
268 #define saLlistRemove(pList, pLink) { \
269 (pLink)->pPrev->pNext = (pLink)->pNext; \
270 (pLink)->pNext->pPrev = (pLink)->pPrev; \
271 (pLink)->pHead = agNULL; \
275 #define saLlistIORemove(pList, pLink) { \
276 (pLink)->pPrev->pNext = (pLink)->pNext; \
277 (pLink)->pNext->pPrev = (pLink)->pPrev; \
278 (pLink)->pHead = agNULL; \
281 /*! \def saLlistGetHead(pList)
282 * \brief saLlistGetHead macro
284 * use to get the link following the head link
286 /********************************************************************************
287 ********************************************************************************
289 ** MODULE NAME: saLlistGetHead
291 ** PURPOSE: get the link following the head link.
293 ** PARAMETERS: PSALINK_LIST OUT - Link list definition.
294 ** RETURNS - PSALINK the link following the head
295 ** agNULL if the following link is the head
297 ** SIDE EFFECTS & CAVEATS:
298 ** !!! assumes that fcllistInitialize has been called on the linklist
299 ** !!! if not, this function behavior is un-predictable
303 ********************************************************************************
304 *******************************************************************************/
305 #define saLlistGetHead(pList) saLlistGetNext(pList,(pList)->pHead)
307 #define saLlistIOGetHead(pList) saLlistGetNext(pList,(pList)->pHead)
309 /*! \def saLlistGetTail(pList)
310 * \brief saLlistGetTail macro
312 * use to get the link preceding the tail link
314 /********************************************************************************
315 ********************************************************************************
317 ** MODULE NAME: saLlistGetTail
319 ** PURPOSE: get the link preceding the tail link.
321 ** PARAMETERS: PSALINK_LIST OUT - Link list definition.
322 ** RETURNS - PSALINK the link preceding the head
323 ** agNULL if the preceding link is the head
325 ** SIDE EFFECTS & CAVEATS:
329 ********************************************************************************
330 *******************************************************************************/
331 #define saLlistGetTail(pList) saLlistGetPrev((pList), (pList)->pHead)
333 /*! \def saLlistGetCount(pList)
334 * \brief saLlistGetCount macro
336 * use to get the number of links in the list excluding head and tail
338 /********************************************************************************
339 ********************************************************************************
341 ** MODULE NAME: saLlistGetCount
343 ** PURPOSE: get the number of links in the list excluding head and tail.
345 ** PARAMETERS: PSALINK_LIST OUT - Link list definition.
347 ** SIDE EFFECTS & CAVEATS:
348 ** !!! assumes that fcllistInitialize has been called on the linklist
349 ** !!! if not, this function behavior is un-predictable
353 ********************************************************************************
354 *******************************************************************************/
356 /*lint -emacro(613,saLlistGetCount) */
357 /*lint -emacro(666,saLlistGetCount) */
359 #define saLlistGetCount(pList) ((pList)->Count)
361 #define saLlistIOGetCount(pList) ((pList)->Count)
363 /*! \def saLlistGetNext(pList, pLink)
364 * \brief saLlistGetNext macro
366 * use to get the next link in the list
368 /********************************************************************************
369 ********************************************************************************
371 ** MODULE NAME: saLlistGetNext
373 ** PURPOSE: get the next link in the list. (one toward tail)
375 ** PARAMETERS: PSALINK_LIST OUT - Link list definition.
376 ** PSALINK IN - Link to get next to
378 ** return PLINK - points to next link
379 ** agNULL if next link is head
381 ** SIDE EFFECTS & CAVEATS:
382 ** !!! assumes that fcllistInitialize has been called on the linklist
383 ** !!! if not, this function behavior is un-predictable
385 ** !!! No validation is made on the list or the validity of the link
386 ** !!! the caller must make sure that the link is in the list
390 ********************************************************************************
391 *******************************************************************************/
393 /*lint -emacro(613,saLlistGetNext) */
395 #define saLlistGetNext(pList, pLink) (((pLink)->pNext == (pList)->pHead) ? \
396 agNULL : (pLink)->pNext)
398 #define saLlistIOGetNext(pList, pLink) (((pLink)->pNext == (pList)->pHead) ? \
399 agNULL : (pLink)->pNext)
401 /*! \def saLlistGetPrev(pList, pLink)
402 * \brief saLlistGetPrev macro
404 * use to get the previous link in the list
406 /********************************************************************************
407 ********************************************************************************
409 ** MODULE NAME: saLlistGetPrev
411 ** PURPOSE: get the previous link in the list. (one toward head)
413 ** PARAMETERS: PSALINK_LIST OUT - Link list definition.
414 ** PSALINK IN - Link to get prev to
416 ** return PLINK - points to previous link
417 ** agNULL if previous link is head
419 ** SIDE EFFECTS & CAVEATS:
420 ** !!! assumes that fcllistInitialize has been called on the linklist
421 ** !!! if not, this function behavior is un-predictable
423 ** !!! No validation is made on the list or the validity of the link
424 ** !!! the caller must make sure that the link is in the list
428 ********************************************************************************
429 *******************************************************************************/
431 /*lint -emacro(613,saLlistGetPrev) */
433 #define saLlistGetPrev(pList, pLink) (((pLink)->pPrev == (pList)->pHead) ? \
434 agNULL : (pLink)->pPrev)
438 #define agObjectBase(baseType,fieldName,fieldPtr) \
439 (void * ) fieldPtr == (void *) 0 ? (baseType *) 0 : \
440 ((baseType *)((bit8 *)(fieldPtr) - ((bitptr)(&(((baseType *)0)->fieldName)))))
443 #endif /* #ifndef __SALLIST_H__*/