19 #ifndef _BOILERPLATE_PRIVATE_LIST_H 20 #define _BOILERPLATE_PRIVATE_LIST_H 22 #ifndef _BOILERPLATE_LIST_H 23 #error "Do not include this file directly. Use <boilerplate/list.h> instead." 27 struct pvholder *next;
28 struct pvholder *prev;
35 #define PRIVATE_LIST_INITIALIZER(__name) \ 36 { .head = { .next = &((__name).head), .prev = &((__name).head) } } 38 #define DEFINE_PRIVATE_LIST(__name) \ 39 struct pvlistobj __name = PRIVATE_LIST_INITIALIZER(__name) 41 static inline void initpvh(
struct pvholder *holder)
43 holder->next = holder;
44 holder->prev = holder;
47 static inline void atpvh(
struct pvholder *head,
struct pvholder *holder)
51 holder->next = head->next;
52 holder->next->prev = holder;
56 static inline void dtpvh(
struct pvholder *holder)
58 holder->prev->next = holder->next;
59 holder->next->prev = holder->prev;
62 static inline void pvlist_init(
struct pvlistobj *list)
67 static inline void pvholder_init(
struct pvholder *holder)
76 static inline int pvholder_linked(
const struct pvholder *holder)
78 return !(holder->prev == holder->next &&
79 holder->prev == holder);
82 static inline void pvlist_prepend(
struct pvholder *holder,
struct pvlistobj *list)
84 atpvh(&list->head, holder);
87 static inline void pvlist_append(
struct pvholder *holder,
struct pvlistobj *list)
89 atpvh(list->head.prev, holder);
92 static inline void pvlist_insert(
struct pvholder *next,
struct pvholder *prev)
97 static inline void pvlist_join(
struct pvlistobj *lsrc,
struct pvlistobj *ldst)
99 struct pvholder *headsrc = lsrc->head.next;
100 struct pvholder *tailsrc = lsrc->head.prev;
101 struct pvholder *headdst = &ldst->head;
103 headsrc->prev->next = tailsrc->next;
104 tailsrc->next->prev = headsrc->prev;
105 headsrc->prev = headdst;
106 tailsrc->next = headdst->next;
107 headdst->next->prev = tailsrc;
108 headdst->next = headsrc;
111 static inline void pvlist_remove(
struct pvholder *holder)
116 static inline void pvlist_remove_init(
struct pvholder *holder)
122 static inline int pvlist_empty(
const struct pvlistobj *list)
124 return list->head.next == &list->head;
127 static inline struct pvholder *pvlist_pop(
struct pvlistobj *list)
129 struct pvholder *holder = list->head.next;
130 pvlist_remove(holder);
134 static inline int pvlist_heading_p(
const struct pvholder *holder,
135 const struct pvlistobj *list)
137 return list->head.next == holder;
140 #define pvlist_entry(ptr, type, member) \ 141 container_of(ptr, type, member) 143 #define pvlist_first_entry(list, type, member) \ 144 pvlist_entry((list)->head.next, type, member) 146 #define pvlist_last_entry(list, type, member) \ 147 pvlist_entry((list)->head.prev, type, member) 149 #define pvlist_prev_entry(pos, list, member) \ 151 typeof(*pos) *__prev = NULL; \ 152 if ((list)->head.next != &(pos)->member) \ 153 __prev = pvlist_entry((pos)->member.prev, \ 154 typeof(*pos), member); \ 158 #define pvlist_next_entry(pos, list, member) \ 160 typeof(*pos) *__next = NULL; \ 161 if ((list)->head.prev != &(pos)->member) \ 162 __next = pvlist_entry((pos)->member.next, \ 163 typeof(*pos), member); \ 167 #define pvlist_pop_entry(list, type, member) ({ \ 168 struct pvholder *__holder = pvlist_pop(list); \ 169 pvlist_entry(__holder, type, member); }) 171 #define pvlist_for_each(pos, list) \ 172 for (pos = (list)->head.next; \ 173 pos != &(list)->head; pos = (pos)->next) 175 #define pvlist_for_each_reverse(pos, list) \ 176 for (pos = (list)->head.prev; \ 177 pos != &(list)->head; pos = (pos)->prev) 179 #define pvlist_for_each_safe(pos, tmp, list) \ 180 for (pos = (list)->head.next, \ 182 pos != &(list)->head; \ 183 pos = tmp, tmp = (pos)->next) 185 #define pvlist_for_each_entry(pos, list, member) \ 186 for (pos = pvlist_entry((list)->head.next, \ 187 typeof(*pos), member); \ 188 &(pos)->member != &(list)->head; \ 189 pos = pvlist_entry((pos)->member.next, \ 190 typeof(*pos), member)) 192 #define pvlist_for_each_entry_safe(pos, tmp, list, member) \ 193 for (pos = pvlist_entry((list)->head.next, \ 194 typeof(*pos), member), \ 195 tmp = pvlist_entry((pos)->member.next, \ 196 typeof(*pos), member); \ 197 &(pos)->member != &(list)->head; \ 198 pos = tmp, tmp = pvlist_entry((pos)->member.next, \ 199 typeof(*pos), member)) 201 #define pvlist_for_each_entry_reverse(pos, list, member) \ 202 for (pos = pvlist_entry((list)->head.prev, \ 203 typeof(*pos), member); \ 204 &pos->member != &(list)->head; \ 205 pos = pvlist_entry(pos->member.prev, \ 206 typeof(*pos), member)) 208 #define pvlist_for_each_entry_reverse_safe(pos, tmp, list, member) \ 209 for (pos = pvlist_entry((list)->head.prev, \ 210 typeof(*pos), member), \ 211 tmp = pvlist_entry((pos)->member.prev, \ 212 typeof(*pos), member); \ 213 &(pos)->member != &(list)->head; \ 214 pos = tmp, tmp = pvlist_entry((pos)->member.prev, \ 215 typeof(*pos), member))