Whamcloud - gitweb
- merge 0.7rc1 from b_devel to HEAD (20030612 merge point)
[fs/lustre-release.git] / lustre / portals / include / portals / list.h
1 #ifndef _LINUX_LIST_H
2 #define _LINUX_LIST_H
3
4
5 /*
6  * Simple doubly linked list implementation.
7  *
8  * Some of the internal functions ("__xxx") are useful when
9  * manipulating whole lists rather than single entries, as
10  * sometimes we already know the next/prev entries and we can
11  * generate better code by using them directly rather than
12  * using the generic single-entry routines.
13  */
14
15 #define prefetch(a) ((void)a)
16
17 struct list_head {
18         struct list_head *next, *prev;
19 };
20
21 #define LIST_HEAD_INIT(name) { &(name), &(name) }
22
23 #define LIST_HEAD(name) \
24         struct list_head name = LIST_HEAD_INIT(name)
25
26 #define INIT_LIST_HEAD(ptr) do { \
27         (ptr)->next = (ptr); (ptr)->prev = (ptr); \
28 } while (0)
29
30 /*
31  * Insert a new entry between two known consecutive entries.
32  *
33  * This is only for internal list manipulation where we know
34  * the prev/next entries already!
35  */
36 static inline void __list_add(struct list_head * new,
37                               struct list_head * prev,
38                               struct list_head * next)
39 {
40         next->prev = new;
41         new->next = next;
42         new->prev = prev;
43         prev->next = new;
44 }
45
46 /**
47  * list_add - add a new entry
48  * @new: new entry to be added
49  * @head: list head to add it after
50  *
51  * Insert a new entry after the specified head.
52  * This is good for implementing stacks.
53  */
54 static inline void list_add(struct list_head *new, struct list_head *head)
55 {
56         __list_add(new, head, head->next);
57 }
58
59 /**
60  * list_add_tail - add a new entry
61  * @new: new entry to be added
62  * @head: list head to add it before
63  *
64  * Insert a new entry before the specified head.
65  * This is useful for implementing queues.
66  */
67 static inline void list_add_tail(struct list_head *new, struct list_head *head)
68 {
69         __list_add(new, head->prev, head);
70 }
71
72 /*
73  * Delete a list entry by making the prev/next entries
74  * point to each other.
75  *
76  * This is only for internal list manipulation where we know
77  * the prev/next entries already!
78  */
79 static inline void __list_del(struct list_head * prev, struct list_head * next)
80 {
81         next->prev = prev;
82         prev->next = next;
83 }
84
85 /**
86  * list_del - deletes entry from list.
87  * @entry: the element to delete from the list.
88  * Note: list_empty on entry does not return true after this, the entry is in an undefined state.
89  */
90 static inline void list_del(struct list_head *entry)
91 {
92         __list_del(entry->prev, entry->next);
93 }
94
95 /**
96  * list_del_init - deletes entry from list and reinitialize it.
97  * @entry: the element to delete from the list.
98  */
99 static inline void list_del_init(struct list_head *entry)
100 {
101         __list_del(entry->prev, entry->next);
102         INIT_LIST_HEAD(entry);
103 }
104
105 /**
106  * list_move - delete from one list and add as another's head
107  * @list: the entry to move
108  * @head: the head that will precede our entry
109  */
110 static inline void list_move(struct list_head *list, struct list_head *head)
111 {
112         __list_del(list->prev, list->next);
113         list_add(list, head);
114 }
115
116 /**
117  * list_move_tail - delete from one list and add as another's tail
118  * @list: the entry to move
119  * @head: the head that will follow our entry
120  */
121 static inline void list_move_tail(struct list_head *list,
122                                   struct list_head *head)
123 {
124         __list_del(list->prev, list->next);
125         list_add_tail(list, head);
126 }
127
128 /**
129  * list_empty - tests whether a list is empty
130  * @head: the list to test.
131  */
132 static inline int list_empty(struct list_head *head)
133 {
134         return head->next == head;
135 }
136
137 static inline void __list_splice(struct list_head *list,
138                                  struct list_head *head)
139 {
140         struct list_head *first = list->next;
141         struct list_head *last = list->prev;
142         struct list_head *at = head->next;
143
144         first->prev = head;
145         head->next = first;
146
147         last->next = at;
148         at->prev = last;
149 }
150
151 /**
152  * list_splice - join two lists
153  * @list: the new list to add.
154  * @head: the place to add it in the first list.
155  */
156 static inline void list_splice(struct list_head *list, struct list_head *head)
157 {
158         if (!list_empty(list))
159                 __list_splice(list, head);
160 }
161
162 /**
163  * list_splice_init - join two lists and reinitialise the emptied list.
164  * @list: the new list to add.
165  * @head: the place to add it in the first list.
166  *
167  * The list at @list is reinitialised
168  */
169 static inline void list_splice_init(struct list_head *list,
170                                     struct list_head *head)
171 {
172         if (!list_empty(list)) {
173                 __list_splice(list, head);
174                 INIT_LIST_HEAD(list);
175         }
176 }
177
178 /**
179  * list_entry - get the struct for this entry
180  * @ptr:        the &struct list_head pointer.
181  * @type:       the type of the struct this is embedded in.
182  * @member:     the name of the list_struct within the struct.
183  */
184 #define list_entry(ptr, type, member) \
185         ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
186
187 /**
188  * list_for_each        -       iterate over a list
189  * @pos:        the &struct list_head to use as a loop counter.
190  * @head:       the head for your list.
191  */
192 #define list_for_each(pos, head) \
193         for (pos = (head)->next, prefetch(pos->next); pos != (head); \
194                 pos = pos->next, prefetch(pos->next))
195
196 /**
197  * list_for_each_prev   -       iterate over a list in reverse order
198  * @pos:        the &struct list_head to use as a loop counter.
199  * @head:       the head for your list.
200  */
201 #define list_for_each_prev(pos, head) \
202         for (pos = (head)->prev, prefetch(pos->prev); pos != (head); \
203                 pos = pos->prev, prefetch(pos->prev))
204
205 /**
206  * list_for_each_safe   -       iterate over a list safe against removal of list entry
207  * @pos:        the &struct list_head to use as a loop counter.
208  * @n:          another &struct list_head to use as temporary storage
209  * @head:       the head for your list.
210  */
211 #define list_for_each_safe(pos, n, head) \
212         for (pos = (head)->next, n = pos->next; pos != (head); \
213                 pos = n, n = pos->next)
214
215 #endif
216
217 #ifndef list_for_each_entry
218 /**
219  * list_for_each_entry  -       iterate over list of given type
220  * @pos:        the type * to use as a loop counter.
221  * @head:       the head for your list.
222  * @member:     the name of the list_struct within the struct.
223  */
224 #define list_for_each_entry(pos, head, member)                          \
225         for (pos = list_entry((head)->next, typeof(*pos), member),      \
226                      prefetch(pos->member.next);                        \
227              &pos->member != (head);                                    \
228              pos = list_entry(pos->member.next, typeof(*pos), member),  \
229              prefetch(pos->member.next))
230 #endif
231
232 #ifndef list_for_each_entry_safe
233 /**
234  * list_for_each_entry_safe  -       iterate over list of given type safe against removal of list entry
235  * @pos:        the type * to use as a loop counter.
236  * @n:          another type * to use as temporary storage
237  * @head:       the head for your list.
238  * @member:     the name of the list_struct within the struct.
239  */
240 #define list_for_each_entry_safe(pos, n, head, member)                  \
241         for (pos = list_entry((head)->next, typeof(*pos), member),      \
242                 n = list_entry(pos->member.next, typeof(*pos), member); \
243              &pos->member != (head);                                    \
244              pos = n, n = list_entry(n->member.next, typeof(*n), member))
245 #endif