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