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