dl_list.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. //------------------------------------------------------------------------------
  2. // <copyright file="dl_list.h" company="Atheros">
  3. // Copyright (c) 2004-2008 Atheros Corporation. All rights reserved.
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License version 2 as
  7. // published by the Free Software Foundation;
  8. //
  9. // Software distributed under the License is distributed on an "AS
  10. // IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  11. // implied. See the License for the specific language governing
  12. // rights and limitations under the License.
  13. //
  14. //
  15. //------------------------------------------------------------------------------
  16. //==============================================================================
  17. // Double-link list definitions (adapted from Atheros SDIO stack)
  18. //
  19. // Author(s): ="Atheros"
  20. //==============================================================================
  21. #ifndef __DL_LIST_H___
  22. #define __DL_LIST_H___
  23. #define A_CONTAINING_STRUCT(address, struct_type, field_name)\
  24. ((struct_type *)((A_UINT32)(address) - (A_UINT32)(&((struct_type *)0)->field_name)))
  25. /* list functions */
  26. /* pointers for the list */
  27. typedef struct _DL_LIST {
  28. struct _DL_LIST *pPrev;
  29. struct _DL_LIST *pNext;
  30. }DL_LIST, *PDL_LIST;
  31. /*
  32. * DL_LIST_INIT , initialize doubly linked list
  33. */
  34. #define DL_LIST_INIT(pList)\
  35. {(pList)->pPrev = pList; (pList)->pNext = pList;}
  36. #define DL_LIST_IS_EMPTY(pList) (((pList)->pPrev == (pList)) && ((pList)->pNext == (pList)))
  37. #define DL_LIST_GET_ITEM_AT_HEAD(pList) (pList)->pNext
  38. #define DL_LIST_GET_ITEM_AT_TAIL(pList) (pList)->pPrev
  39. /*
  40. * ITERATE_OVER_LIST pStart is the list, pTemp is a temp list member
  41. * NOT: do not use this function if the items in the list are deleted inside the
  42. * iteration loop
  43. */
  44. #define ITERATE_OVER_LIST(pStart, pTemp) \
  45. for((pTemp) =(pStart)->pNext; pTemp != (pStart); (pTemp) = (pTemp)->pNext)
  46. /* safe iterate macro that allows the item to be removed from the list
  47. * the iteration continues to the next item in the list
  48. */
  49. #define ITERATE_OVER_LIST_ALLOW_REMOVE(pStart,pItem,st,offset) \
  50. { \
  51. PDL_LIST pTemp; \
  52. pTemp = (pStart)->pNext; \
  53. while (pTemp != (pStart)) { \
  54. (pItem) = A_CONTAINING_STRUCT(pTemp,st,offset); \
  55. pTemp = pTemp->pNext; \
  56. #define ITERATE_END }}
  57. /*
  58. * DL_ListInsertTail - insert pAdd to the end of the list
  59. */
  60. static INLINE PDL_LIST DL_ListInsertTail(PDL_LIST pList, PDL_LIST pAdd) {
  61. /* insert at tail */
  62. pAdd->pPrev = pList->pPrev;
  63. pAdd->pNext = pList;
  64. pList->pPrev->pNext = pAdd;
  65. pList->pPrev = pAdd;
  66. return pAdd;
  67. }
  68. /*
  69. * DL_ListInsertHead - insert pAdd into the head of the list
  70. */
  71. static INLINE PDL_LIST DL_ListInsertHead(PDL_LIST pList, PDL_LIST pAdd) {
  72. /* insert at head */
  73. pAdd->pPrev = pList;
  74. pAdd->pNext = pList->pNext;
  75. pList->pNext->pPrev = pAdd;
  76. pList->pNext = pAdd;
  77. return pAdd;
  78. }
  79. #define DL_ListAdd(pList,pItem) DL_ListInsertHead((pList),(pItem))
  80. /*
  81. * DL_ListRemove - remove pDel from list
  82. */
  83. static INLINE PDL_LIST DL_ListRemove(PDL_LIST pDel) {
  84. pDel->pNext->pPrev = pDel->pPrev;
  85. pDel->pPrev->pNext = pDel->pNext;
  86. /* point back to itself just to be safe, incase remove is called again */
  87. pDel->pNext = pDel;
  88. pDel->pPrev = pDel;
  89. return pDel;
  90. }
  91. /*
  92. * DL_ListRemoveItemFromHead - get a list item from the head
  93. */
  94. static INLINE PDL_LIST DL_ListRemoveItemFromHead(PDL_LIST pList) {
  95. PDL_LIST pItem = NULL;
  96. if (pList->pNext != pList) {
  97. pItem = pList->pNext;
  98. /* remove the first item from head */
  99. DL_ListRemove(pItem);
  100. }
  101. return pItem;
  102. }
  103. #endif /* __DL_LIST_H___ */