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_pop_entry(heap, list, type, member) ({ \
249 struct holder *__holder = __list_pop((heap), list); \
250 list_entry(__holder, type, member); })
252 #define list_pop_entry(list, type, member) \
253 __list_pop_entry(__main_heap, list, type, member)
255 #define __list_for_each(heap, pos, list) \
256 for (pos = __hptr((heap), (list)->head.next); \
257 pos != &(list)->head; pos = __hptr((heap), (pos)->next))
259 #define list_for_each(pos, list) \
260 __list_for_each(__main_heap, pos, list)
262 #define __list_for_each_reverse(heap, pos, list) \
263 for (pos = __hptr((heap), (list)->head.prev); \
264 pos != &(list)->head; pos = __hptr((heap), (pos)->prev))
266 #define list_for_each_reverse(pos, list) \
267 __list_for_each_reverse(__main_heap, pos, list)
269 #define __list_for_each_safe(heap, pos, tmp, list) \
270 for (pos = __hptr((heap), (list)->head.next), \
271 tmp = __hptr((heap), (pos)->next); \
272 pos != &(list)->head; \
273 pos = tmp, tmp = __hptr((heap), (pos)->next))
275 #define list_for_each_safe(pos, tmp, list) \
276 __list_for_each_safe(__main_heap, pos, tmp, list)
278 #define __list_for_each_entry(heap, pos, list, member) \
279 for (pos = list_entry(__hptr((heap), (list)->head.next), \
280 typeof(*pos), member); \
281 &(pos)->member != &(list)->head; \
282 pos = list_entry(__hptr((heap), (pos)->member.next), \
283 typeof(*pos), member))
285 #define list_for_each_entry(pos, list, member) \
286 __list_for_each_entry(__main_heap, pos, list, member)
288 #define __list_for_each_entry_safe(heap, pos, tmp, list, member) \
289 for (pos = list_entry(__hptr((heap), (list)->head.next), \
290 typeof(*pos), member), \
291 tmp = list_entry(__hptr((heap), (pos)->member.next), \
292 typeof(*pos), member); \
293 &(pos)->member != &(list)->head; \
294 pos = tmp, tmp = list_entry(__hptr((heap), (pos)->member.next), \
295 typeof(*pos), member))
297 #define __list_for_each_entry_reverse_safe(heap, pos, tmp, list, member) \
298 for (pos = list_entry(__hptr((heap), (list)->head.prev), \
299 typeof(*pos), member), \
300 tmp = list_entry(__hptr((heap), (pos)->member.prev), \
301 typeof(*pos), member); \
302 &(pos)->member != &(list)->head; \
303 pos = tmp, tmp = list_entry(__hptr((heap), (pos)->member.prev), \
304 typeof(*pos), member))
306 #define list_for_each_entry_safe(pos, tmp, list, member) \
307 __list_for_each_entry_safe(__main_heap, pos, tmp, list, member)
309 #define __list_for_each_entry_reverse(heap, pos, list, member) \
310 for (pos = list_entry(__hptr((heap), (list)->head.prev), \
311 typeof(*pos), member); \
312 &pos->member != &(list)->head; \
313 pos = list_entry(__hptr((heap), pos->member.prev), \
314 typeof(*pos), member))
316 #define list_for_each_entry_reverse(pos, list, member) \
317 __list_for_each_entry_reverse(__main_heap, pos, list, member)
319 #define list_for_each_entry_reverse_safe(pos, tmp, list, member) \
320 __list_for_each_entry_reverse_safe(__main_heap, pos, tmp, list, member)