1 /*
2 *
3 * linux-like bidirectional lists
4 */
5
6 #ifndef _MYLIST_H
7 #define _MYLIST_H
8 /* not just a head, also the link field for a list entry */
9 struct list_head {
10 struct list_head *prev, *next;
11 };
12
13 #define INIT_LIST_HEAD(l) do { (l)->prev = (l)->next = (l); } while (0)
14 #define list_empty(l) ( (l)->next == l )
15 static inline void
__list_add(struct list_head * o,struct list_head * prev,struct list_head * next)16 __list_add(struct list_head *o, struct list_head *prev,
17 struct list_head *next)
18 {
19 next->prev = o;
20 o->next = next;
21 o->prev = prev;
22 prev->next = o;
23 }
24
25 static inline void
list_add_tail(struct list_head * o,struct list_head * head)26 list_add_tail(struct list_head *o, struct list_head *head)
27 {
28 __list_add(o, head->prev, head);
29 }
30
31 #define list_first_entry(pL, ty, member) \
32 (ty *)((char *)((pL)->next) - offsetof(ty, member))
33
34 static inline void
__list_del(struct list_head * prev,struct list_head * next)35 __list_del(struct list_head *prev, struct list_head *next)
36 {
37 next->prev = prev;
38 prev->next = next;
39 }
40
41 static inline void
list_del(struct list_head * entry)42 list_del(struct list_head *entry)
43 {
44 ND("called on %p", entry);
45 __list_del(entry->prev, entry->next);
46 entry->next = entry->prev = NULL;
47 }
48
49 #endif /* _MYLIST_H */
50