18 #ifndef _BOILERPLATE_SHARED_LIST_H
19 #define _BOILERPLATE_SHARED_LIST_H
21 #ifndef _BOILERPLATE_LIST_H
22 #error "Do not include this file directly. Use <boilerplate/list.h> instead."
25 #define __hoff(h, a) __memoff(h, a)
26 #define __hptr(h, v) ((struct holder *)__memptr(h, v))
27 #define __hchk(h, a) __memchk(h, a)
30 dref_type(
struct holder *) next;
31 dref_type(
struct holder *) prev;
38 static inline void __inith_nocheck(
void *heap,
struct holder *holder)
40 holder->next = __hoff(heap, holder);
41 holder->prev = __hoff(heap, holder);
44 static inline void __inith(
void *heap,
struct holder *holder)
46 assert(__hchk(heap, holder));
47 __inith_nocheck(heap, holder);
50 static inline void inith(
struct holder *holder)
52 __inith(__main_heap, holder);
55 static inline void __ath(
void *heap,
struct holder *head,
56 struct holder *holder)
59 holder->prev = __hoff(heap, head);
60 holder->next = head->next;
61 __hptr(heap, holder->next)->prev = __hoff(heap, holder);
62 head->next = __hoff(heap, holder);
65 static inline void ath(
struct holder *head,
struct holder *holder)
67 __ath(__main_heap, head, holder);
70 static inline void __dth(
void *heap,
struct holder *holder)
72 __hptr(heap, holder->prev)->next = holder->next;
73 __hptr(heap, holder->next)->prev = holder->prev;
76 static inline void dth(
struct holder *holder)
78 __dth(__main_heap, holder);
81 static inline void __list_init(
void *heap,
struct listobj *list)
83 __inith(heap, &list->head);
86 static inline void __list_init_nocheck(
void *heap,
struct listobj *list)
88 __inith_nocheck(heap, &list->head);
91 static inline void list_init(
struct listobj *list)
93 __list_init(__main_heap, list);
96 static inline void __holder_init(
void *heap,
struct holder *holder)
98 __inith(heap, holder);
101 static inline void __holder_init_nocheck(
void *heap,
struct holder *holder)
103 __inith_nocheck(heap, holder);
106 static inline void holder_init(
struct holder *holder)
111 static inline int __holder_linked(
void *heap,
const struct holder *holder)
113 return !(holder->prev == holder->next &&
114 holder->prev == __hoff(heap, holder));
121 static inline int holder_linked(
const struct holder *holder)
123 return __holder_linked(__main_heap, holder);
126 static inline void __list_prepend(
void *heap,
struct holder *holder,
127 struct listobj *list)
129 __ath(heap, &list->head, holder);
132 static inline void list_prepend(
struct holder *holder,
struct listobj *list)
134 __list_prepend(__main_heap, holder, list);
137 static inline void __list_append(
void *heap,
struct holder *holder,
138 struct listobj *list)
140 __ath(heap, __hptr(heap, list->head.prev), holder);
143 static inline void list_append(
struct holder *holder,
struct listobj *list)
145 __list_append(__main_heap, holder, list);
148 static inline void __list_insert(
void *heap,
struct holder *next,
struct holder *prev)
150 __ath(heap, prev, next);
153 static inline void list_insert(
struct holder *next,
struct holder *prev)
155 __list_insert(__main_heap, next, prev);
158 static inline void __list_join(
void *heap,
struct listobj *lsrc,
159 struct listobj *ldst)
161 struct holder *headsrc = __hptr(heap, lsrc->head.next);
162 struct holder *tailsrc = __hptr(heap, lsrc->head.prev);
163 struct holder *headdst = &ldst->head;
165 __hptr(heap, headsrc->prev)->next = tailsrc->next;
166 __hptr(heap, tailsrc->next)->prev = headsrc->prev;
167 headsrc->prev = __hoff(heap, headdst);
168 tailsrc->next = headdst->next;
169 __hptr(heap, headdst->next)->prev = __hoff(heap, tailsrc);
170 headdst->next = __hoff(heap, headsrc);
173 static inline void list_join(
struct listobj *lsrc,
struct listobj *ldst)
175 __list_join(__main_heap, lsrc, ldst);
178 static inline void __list_remove(
void *heap,
struct holder *holder)
183 static inline void list_remove(
struct holder *holder)
185 __list_remove(__main_heap, holder);
188 static inline void __list_remove_init(
void *heap,
struct holder *holder)
191 __inith(heap, holder);
194 static inline void list_remove_init(
struct holder *holder)
196 __list_remove_init(__main_heap, holder);
199 static inline int __list_empty(
void *heap,
const struct listobj *list)
201 return list->head.next == __hoff(heap, &list->head);
204 static inline int list_empty(
const struct listobj *list)
206 return __list_empty(__main_heap, list);
209 static inline struct holder *__list_pop(
void *heap,
struct listobj *list)
211 struct holder *holder = __hptr(heap, list->head.next);
212 __list_remove(heap, holder);
216 static inline struct holder *list_pop(
struct listobj *list)
218 return __list_pop(__main_heap, list);
221 static inline int __list_heading_p(
void *heap,
const struct holder *holder,
222 const struct listobj *list)
224 return list->head.next == __hoff(heap, holder);
227 static inline int list_heading_p(
const struct holder *holder,
228 const struct listobj *list)
230 return __list_heading_p(__main_heap, holder, list);
233 #define list_entry(ptr, type, member) \
234 container_of(ptr, type, member)
236 #define __list_first_entry(heap, list, type, member) \
237 list_entry(__hptr((heap), (list)->head.next), type, member)
239 #define list_first_entry(list, type, member) \
240 __list_first_entry(__main_heap, list, type, member)
242 #define __list_last_entry(heap, list, type, member) \
243 list_entry(__hptr((heap), (list)->head.prev), type, member)
245 #define list_last_entry(list, type, member) \
246 __list_last_entry(__main_heap, list, type, member)
248 #define __list_prev_entry(heap, pos, list, member) \
250 typeof(*pos) *__prev = NULL; \
251 if ((list)->head.next != __hoff(heap, &(pos)->member)) \
252 __prev = list_entry(__hptr((heap), \
253 (pos)->member.prev), typeof(*pos), member); \
257 #define list_prev_entry(pos, list, member) \
258 __list_prev_entry(__main_heap, pos, list, member)
260 #define __list_next_entry(heap, pos, list, member) \
262 typeof(*pos) *__next = NULL; \
263 if ((list)->head.prev != __hoff(heap, &(pos)->member)) \
264 __next = list_entry(__hptr((heap), \
265 (pos)->member.next), typeof(*pos), member); \
269 #define list_next_entry(pos, list, member) \
270 __list_next_entry(__main_heap, pos, list, member)
272 #define __list_pop_entry(heap, list, type, member) ({ \
273 struct holder *__holder = __list_pop((heap), list); \
274 list_entry(__holder, type, member); })
276 #define list_pop_entry(list, type, member) \
277 __list_pop_entry(__main_heap, list, type, member)
279 #define __list_for_each(heap, pos, list) \
280 for (pos = __hptr((heap), (list)->head.next); \
281 pos != &(list)->head; pos = __hptr((heap), (pos)->next))
283 #define list_for_each(pos, list) \
284 __list_for_each(__main_heap, pos, list)
286 #define __list_for_each_reverse(heap, pos, list) \
287 for (pos = __hptr((heap), (list)->head.prev); \
288 pos != &(list)->head; pos = __hptr((heap), (pos)->prev))
290 #define list_for_each_reverse(pos, list) \
291 __list_for_each_reverse(__main_heap, pos, list)
293 #define __list_for_each_safe(heap, pos, tmp, list) \
294 for (pos = __hptr((heap), (list)->head.next), \
295 tmp = __hptr((heap), (pos)->next); \
296 pos != &(list)->head; \
297 pos = tmp, tmp = __hptr((heap), (pos)->next))
299 #define list_for_each_safe(pos, tmp, list) \
300 __list_for_each_safe(__main_heap, pos, tmp, list)
302 #define __list_for_each_entry(heap, pos, list, member) \
303 for (pos = list_entry(__hptr((heap), (list)->head.next), \
304 typeof(*pos), member); \
305 &(pos)->member != &(list)->head; \
306 pos = list_entry(__hptr((heap), (pos)->member.next), \
307 typeof(*pos), member))
309 #define list_for_each_entry(pos, list, member) \
310 __list_for_each_entry(__main_heap, pos, list, member)
312 #define __list_for_each_entry_safe(heap, pos, tmp, list, member) \
313 for (pos = list_entry(__hptr((heap), (list)->head.next), \
314 typeof(*pos), member), \
315 tmp = list_entry(__hptr((heap), (pos)->member.next), \
316 typeof(*pos), member); \
317 &(pos)->member != &(list)->head; \
318 pos = tmp, tmp = list_entry(__hptr((heap), (pos)->member.next), \
319 typeof(*pos), member))
321 #define __list_for_each_entry_reverse_safe(heap, pos, tmp, list, member) \
322 for (pos = list_entry(__hptr((heap), (list)->head.prev), \
323 typeof(*pos), member), \
324 tmp = list_entry(__hptr((heap), (pos)->member.prev), \
325 typeof(*pos), member); \
326 &(pos)->member != &(list)->head; \
327 pos = tmp, tmp = list_entry(__hptr((heap), (pos)->member.prev), \
328 typeof(*pos), member))
330 #define list_for_each_entry_safe(pos, tmp, list, member) \
331 __list_for_each_entry_safe(__main_heap, pos, tmp, list, member)
333 #define __list_for_each_entry_reverse(heap, pos, list, member) \
334 for (pos = list_entry(__hptr((heap), (list)->head.prev), \
335 typeof(*pos), member); \
336 &pos->member != &(list)->head; \
337 pos = list_entry(__hptr((heap), pos->member.prev), \
338 typeof(*pos), member))
340 #define list_for_each_entry_reverse(pos, list, member) \
341 __list_for_each_entry_reverse(__main_heap, pos, list, member)
343 #define list_for_each_entry_reverse_safe(pos, tmp, list, member) \
344 __list_for_each_entry_reverse_safe(__main_heap, pos, tmp, list, member)