1 /*
2 * list.h
3 *
4 * This is a subset of linux's list.h intended to be used in user-space.
5 * XXX The namespace conflicts with NetBSD's <sys/queue.h>
6 *
7 */
8
9 #ifndef __LIST_H__
10 #define __LIST_H__
11
12 #define LIST_POISON1 ((void *) 0x00100100)
13 #define LIST_POISON2 ((void *) 0x00200200)
14
15 struct list_head {
16 struct list_head *next, *prev;
17 };
18
19 /* XXX workaround for conflicts. The list API should use its own
20 * namespace prefix, i.e. BLK_
21 */
22 #ifdef LIST_HEAD_INIT
23 #undef LIST_HEAD_INIT
24 #endif
25 #ifndef LIST_HEAD
26 #undef LIST_HEAD
27 #endif
28
29 #define LIST_HEAD_INIT(name) { &(name), &(name) }
30
31 #define LIST_HEAD(name) \
32 struct list_head name = LIST_HEAD_INIT(name)
33
INIT_LIST_HEAD(struct list_head * list)34 static inline void INIT_LIST_HEAD(struct list_head *list)
35 {
36 list->next = list;
37 list->prev = list;
38 }
39
__list_add(struct list_head * new,struct list_head * prev,struct list_head * next)40 static inline void __list_add(struct list_head *new,
41 struct list_head *prev,
42 struct list_head *next)
43 {
44 next->prev = new;
45 new->next = next;
46 new->prev = prev;
47 prev->next = new;
48 }
49
list_add(struct list_head * new,struct list_head * head)50 static inline void list_add(struct list_head *new, struct list_head *head)
51 {
52 __list_add(new, head, head->next);
53 }
54
list_add_tail(struct list_head * new,struct list_head * head)55 static inline void list_add_tail(struct list_head *new, struct list_head *head)
56 {
57 __list_add(new, head->prev, head);
58 }
59
__list_del(struct list_head * prev,struct list_head * next)60 static inline void __list_del(struct list_head * prev, struct list_head * next)
61 {
62 next->prev = prev;
63 prev->next = next;
64 }
65
list_del(struct list_head * entry)66 static inline void list_del(struct list_head *entry)
67 {
68 __list_del(entry->prev, entry->next);
69 entry->next = LIST_POISON1;
70 entry->prev = LIST_POISON2;
71 }
72
list_del_init(struct list_head * entry)73 static inline void list_del_init(struct list_head *entry)
74 {
75 __list_del(entry->prev, entry->next);
76 INIT_LIST_HEAD(entry);
77 }
78
list_empty(const struct list_head * head)79 static inline int list_empty(const struct list_head *head)
80 {
81 return head->next == head;
82 }
83
list_is_last(const struct list_head * list,const struct list_head * head)84 static inline int list_is_last(const struct list_head *list,
85 const struct list_head *head)
86 {
87 return list->next == head;
88 }
89
__list_splice(const struct list_head * list,struct list_head * prev,struct list_head * next)90 static inline void __list_splice(const struct list_head *list,
91 struct list_head *prev,
92 struct list_head *next)
93 {
94 struct list_head *first = list->next;
95 struct list_head *last = list->prev;
96
97 first->prev = prev;
98 prev->next = first;
99
100 last->next = next;
101 next->prev = last;
102 }
103
list_splice(const struct list_head * list,struct list_head * head)104 static inline void list_splice(const struct list_head *list,
105 struct list_head *head)
106 {
107 if (!list_empty(list))
108 __list_splice(list, head, head->next);
109 }
110
111 #define list_entry(ptr, type, member) \
112 ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
113
114 #define list_for_each_entry(pos, head, member) \
115 for (pos = list_entry((head)->next, typeof(*pos), member); \
116 &pos->member != (head); \
117 pos = list_entry(pos->member.next, typeof(*pos), member))
118
119 #define list_for_each_entry_safe(pos, n, head, member) \
120 for (pos = list_entry((head)->next, typeof(*pos), member), \
121 n = list_entry(pos->member.next, typeof(*pos), member); \
122 &pos->member != (head); \
123 pos = n, n = list_entry(n->member.next, typeof(*n), member))
124
125 #endif /* __LIST_H__ */
126