util_double_list.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /*
  2. * SPDX-FileCopyrightText: 2006 Tungsten Graphics, Inc., Bismarck, ND. USA.
  3. * SPDX-License-Identifier: MIT
  4. */
  5. /**
  6. * \file
  7. * List macros heavily inspired by the Linux kernel
  8. * list handling. No list looping yet.
  9. *
  10. * Is not threadsafe, so common operations need to
  11. * be protected using an external mutex.
  12. */
  13. #ifndef _U_DOUBLE_LIST_H_
  14. #define _U_DOUBLE_LIST_H_
  15. #include <stddef.h>
  16. struct list_head
  17. {
  18. struct list_head *prev;
  19. struct list_head *next;
  20. };
  21. static inline void list_inithead(struct list_head *item)
  22. {
  23. item->prev = item;
  24. item->next = item;
  25. }
  26. static inline void list_add(struct list_head *item, struct list_head *list)
  27. {
  28. item->prev = list;
  29. item->next = list->next;
  30. list->next->prev = item;
  31. list->next = item;
  32. }
  33. static inline void list_addtail(struct list_head *item, struct list_head *list)
  34. {
  35. item->next = list;
  36. item->prev = list->prev;
  37. list->prev->next = item;
  38. list->prev = item;
  39. }
  40. static inline void list_replace(struct list_head *from, struct list_head *to)
  41. {
  42. to->prev = from->prev;
  43. to->next = from->next;
  44. from->next->prev = to;
  45. from->prev->next = to;
  46. }
  47. static inline void list_del(struct list_head *item)
  48. {
  49. item->prev->next = item->next;
  50. item->next->prev = item->prev;
  51. }
  52. static inline void list_delinit(struct list_head *item)
  53. {
  54. item->prev->next = item->next;
  55. item->next->prev = item->prev;
  56. item->next = item;
  57. item->prev = item;
  58. }
  59. #define LIST_INITHEAD(__item) list_inithead(__item)
  60. #define LIST_ADD(__item, __list) list_add(__item, __list)
  61. #define LIST_ADDTAIL(__item, __list) list_addtail(__item, __list)
  62. #define LIST_REPLACE(__from, __to) list_replace(__from, __to)
  63. #define LIST_DEL(__item) list_del(__item)
  64. #define LIST_DELINIT(__item) list_delinit(__item)
  65. #define LIST_ENTRY(__type, __item, __field) \
  66. ((__type *)(((char *)(__item)) - offsetof(__type, __field)))
  67. #define LIST_FIRST_ENTRY(__ptr, __type, __field) \
  68. LIST_ENTRY(__type, (__ptr)->next, __field)
  69. #define LIST_LAST_ENTRY(__ptr, __type, __field) \
  70. LIST_ENTRY(__type, (__ptr)->prev, __field)
  71. #define LIST_IS_EMPTY(__list) \
  72. ((__list)->next == (__list))
  73. #ifndef container_of
  74. #define container_of(ptr, sample, member) \
  75. (void *)((char *)(ptr) \
  76. - ((char *)&((__typeof__(sample))0)->member))
  77. #endif
  78. #define LIST_FOR_EACH_ENTRY(pos, head, member) \
  79. for (pos = container_of((head)->next, pos, member); \
  80. &pos->member != (head); \
  81. pos = container_of(pos->member.next, pos, member))
  82. #define LIST_FOR_EACH_ENTRY_SAFE(pos, storage, head, member) \
  83. for (pos = container_of((head)->next, pos, member), \
  84. storage = container_of(pos->member.next, pos, member); \
  85. &pos->member != (head); \
  86. pos = storage, storage = container_of(storage->member.next, storage, member))
  87. #define LIST_FOR_EACH_ENTRY_SAFE_REV(pos, storage, head, member) \
  88. for (pos = container_of((head)->prev, pos, member), \
  89. storage = container_of(pos->member.prev, pos, member); \
  90. &pos->member != (head); \
  91. pos = storage, storage = container_of(storage->member.prev, storage, member))
  92. #define LIST_FOR_EACH_ENTRY_FROM(pos, start, head, member) \
  93. for (pos = container_of((start), pos, member); \
  94. &pos->member != (head); \
  95. pos = container_of(pos->member.next, pos, member))
  96. #define LIST_FOR_EACH_ENTRY_FROM_REV(pos, start, head, member) \
  97. for (pos = container_of((start), pos, member); \
  98. &pos->member != (head); \
  99. pos = container_of(pos->member.prev, pos, member))
  100. #endif /*_U_DOUBLE_LIST_H_*/