Whamcloud - gitweb
7b9f9cce2fd3b8694d3d43e6eb5d755f631f05e8
[fs/lustre-release.git] / libcfs / include / libcfs / list.h
1 #ifndef __LIBCFS_LIST_H__
2 #define __LIBCFS_LIST_H__
3
4 #if defined (__linux__) && defined(__KERNEL__)
5
6 #include <linux/list.h>
7
8 typedef struct list_head cfs_list_t;
9
10 #define __cfs_list_add(new, prev, next)      __list_add(new, prev, next)
11 #define cfs_list_add(new, head)              list_add(new, head)
12
13 #define cfs_list_add_tail(new, head)         list_add_tail(new, head)
14
15 #define __cfs_list_del(prev, next)           __list_del(prev, next)
16 #define cfs_list_del(entry)                  list_del(entry)
17 #define cfs_list_del_init(entry)             list_del_init(entry)
18
19 #define cfs_list_move(list, head)            list_move(list, head)
20 #define cfs_list_move_tail(list, head)       list_move_tail(list, head)
21
22 #define cfs_list_empty(head)                 list_empty(head)
23 #define cfs_list_empty_careful(head)         list_empty_careful(head)
24
25 #define __cfs_list_splice(list, head)        __list_splice(list, head)
26 #define cfs_list_splice(list, head)          list_splice(list, head)
27
28 #define cfs_list_splice_init(list, head)     list_splice_init(list, head)
29
30 #define cfs_list_entry(ptr, type, member)    list_entry(ptr, type, member)
31 #define cfs_list_for_each(pos, head)         list_for_each(pos, head)
32 #define cfs_list_for_each_safe(pos, n, head) list_for_each_safe(pos, n, head)
33 #define cfs_list_for_each_prev(pos, head)    list_for_each_prev(pos, head)
34 #define cfs_list_for_each_entry(pos, head, member) \
35         list_for_each_entry(pos, head, member)
36 #define cfs_list_for_each_entry_reverse(pos, head, member) \
37         list_for_each_entry_reverse(pos, head, member)
38 #define cfs_list_for_each_entry_safe(pos, n, head, member) \
39         list_for_each_entry_safe(pos, n, head, member)
40 #ifdef list_for_each_entry_safe_from
41 #define cfs_list_for_each_entry_safe_from(pos, n, head, member) \
42         list_for_each_entry_safe_from(pos, n, head, member)
43 #endif /* list_for_each_entry_safe_from */
44 #define cfs_list_for_each_entry_continue(pos, head, member) \
45         list_for_each_entry_continue(pos, head, member)
46
47 #define CFS_LIST_HEAD_INIT(n)                LIST_HEAD_INIT(n)
48 #define CFS_LIST_HEAD(n)                     LIST_HEAD(n)
49 #define CFS_INIT_LIST_HEAD(p)                INIT_LIST_HEAD(p)
50
51 typedef struct hlist_head cfs_hlist_head_t;
52 typedef struct hlist_node cfs_hlist_node_t;
53
54 #define cfs_hlist_unhashed(h)              hlist_unhashed(h)
55
56 #define cfs_hlist_empty(h)                 hlist_empty(h)
57
58 #define __cfs_hlist_del(n)                 __hlist_del(n)
59 #define cfs_hlist_del(n)                   hlist_del(n)
60 #define cfs_hlist_del_init(n)              hlist_del_init(n)
61
62 #define cfs_hlist_add_head(n, next)        hlist_add_head(n, next)
63 #define cfs_hlist_add_before(n, next)      hlist_add_before(n, next)
64 #define cfs_hlist_add_after(n, next)       hlist_add_after(n, next)
65
66 #define cfs_hlist_entry(ptr, type, member) hlist_entry(ptr, type, member)
67 #define cfs_hlist_for_each(pos, head)      hlist_for_each(pos, head)
68 #define cfs_hlist_for_each_safe(pos, n, head) \
69         hlist_for_each_safe(pos, n, head)
70 #define cfs_hlist_for_each_entry(tpos, pos, head, member) \
71         hlist_for_each_entry(tpos, pos, head, member)
72 #define cfs_hlist_for_each_entry_continue(tpos, pos, member) \
73         hlist_for_each_entry_continue(tpos, pos, member)
74 #define cfs_hlist_for_each_entry_from(tpos, pos, member) \
75         hlist_for_each_entry_from(tpos, pos, member)
76 #define cfs_hlist_for_each_entry_safe(tpos, pos, n, head, member) \
77         hlist_for_each_entry_safe(tpos, pos, n, head, member)
78
79 #define CFS_HLIST_HEAD_INIT                HLIST_HEAD_INIT
80 #define CFS_HLIST_HEAD(n)                  HLIST_HEAD(n)
81 #define CFS_INIT_HLIST_HEAD(p)             INIT_HLIST_HEAD(p)
82 #define CFS_INIT_HLIST_NODE(p)             INIT_HLIST_NODE(p)
83
84 #else /* !defined (__linux__) || !defined(__KERNEL__) */
85
86 /*
87  * Simple doubly linked list implementation.
88  *
89  * Some of the internal functions ("__xxx") are useful when
90  * manipulating whole lists rather than single entries, as
91  * sometimes we already know the next/prev entries and we can
92  * generate better code by using them directly rather than
93  * using the generic single-entry routines.
94  */
95
96 #define prefetch(a) ((void)a)
97
98 struct cfs_list_head {
99         struct cfs_list_head *next, *prev;
100 };
101
102 typedef struct cfs_list_head cfs_list_t;
103
104 #define CFS_LIST_HEAD_INIT(name) { &(name), &(name) }
105
106 #define CFS_LIST_HEAD(name) \
107         cfs_list_t name = CFS_LIST_HEAD_INIT(name)
108
109 #define CFS_INIT_LIST_HEAD(ptr) do { \
110         (ptr)->next = (ptr); (ptr)->prev = (ptr); \
111 } while (0)
112
113 /**
114  * Insert a new entry between two known consecutive entries.
115  *
116  * This is only for internal list manipulation where we know
117  * the prev/next entries already!
118  */
119 static inline void __cfs_list_add(cfs_list_t * new,
120                                   cfs_list_t * prev,
121                                   cfs_list_t * next)
122 {
123         next->prev = new;
124         new->next = next;
125         new->prev = prev;
126         prev->next = new;
127 }
128
129 /**
130  * Insert an entry at the start of a list.
131  * \param new  new entry to be inserted
132  * \param head list to add it to
133  *
134  * Insert a new entry after the specified head.
135  * This is good for implementing stacks.
136  */
137 static inline void cfs_list_add(cfs_list_t *new,
138                                 cfs_list_t *head)
139 {
140         __cfs_list_add(new, head, head->next);
141 }
142
143 /**
144  * Insert an entry at the end of a list.
145  * \param new  new entry to be inserted
146  * \param head list to add it to
147  *
148  * Insert a new entry before the specified head.
149  * This is useful for implementing queues.
150  */
151 static inline void cfs_list_add_tail(cfs_list_t *new,
152                                      cfs_list_t *head)
153 {
154         __cfs_list_add(new, head->prev, head);
155 }
156
157 /*
158  * Delete a list entry by making the prev/next entries
159  * point to each other.
160  *
161  * This is only for internal list manipulation where we know
162  * the prev/next entries already!
163  */
164 static inline void __cfs_list_del(cfs_list_t *prev,
165                                   cfs_list_t *next)
166 {
167         next->prev = prev;
168         prev->next = next;
169 }
170
171 /**
172  * Remove an entry from the list it is currently in.
173  * \param entry the entry to remove
174  * Note: list_empty(entry) does not return true after this, the entry is in an
175  * undefined state.
176  */
177 static inline void cfs_list_del(cfs_list_t *entry)
178 {
179         __cfs_list_del(entry->prev, entry->next);
180 }
181
182 /**
183  * Remove an entry from the list it is currently in and reinitialize it.
184  * \param entry the entry to remove.
185  */
186 static inline void cfs_list_del_init(cfs_list_t *entry)
187 {
188         __cfs_list_del(entry->prev, entry->next);
189         CFS_INIT_LIST_HEAD(entry);
190 }
191
192 /**
193  * Remove an entry from the list it is currently in and insert it at the start
194  * of another list.
195  * \param list the entry to move
196  * \param head the list to move it to
197  */
198 static inline void cfs_list_move(cfs_list_t *list,
199                                  cfs_list_t *head)
200 {
201         __cfs_list_del(list->prev, list->next);
202         cfs_list_add(list, head);
203 }
204
205 /**
206  * Remove an entry from the list it is currently in and insert it at the end of
207  * another list.
208  * \param list the entry to move
209  * \param head the list to move it to
210  */
211 static inline void cfs_list_move_tail(cfs_list_t *list,
212                                       cfs_list_t *head)
213 {
214         __cfs_list_del(list->prev, list->next);
215         cfs_list_add_tail(list, head);
216 }
217
218 /**
219  * Test whether a list is empty
220  * \param head the list to test.
221  */
222 static inline int cfs_list_empty(cfs_list_t *head)
223 {
224         return head->next == head;
225 }
226
227 /**
228  * Test whether a list is empty and not being modified
229  * \param head the list to test
230  *
231  * Tests whether a list is empty _and_ checks that no other CPU might be
232  * in the process of modifying either member (next or prev)
233  *
234  * NOTE: using cfs_list_empty_careful() without synchronization
235  * can only be safe if the only activity that can happen
236  * to the list entry is cfs_list_del_init(). Eg. it cannot be used
237  * if another CPU could re-list_add() it.
238  */
239 static inline int cfs_list_empty_careful(const cfs_list_t *head)
240 {
241         cfs_list_t *next = head->next;
242         return (next == head) && (next == head->prev);
243 }
244
245 static inline void __cfs_list_splice(cfs_list_t *list,
246                                      cfs_list_t *head)
247 {
248         cfs_list_t *first = list->next;
249         cfs_list_t *last = list->prev;
250         cfs_list_t *at = head->next;
251
252         first->prev = head;
253         head->next = first;
254
255         last->next = at;
256         at->prev = last;
257 }
258
259 /**
260  * Join two lists
261  * \param list the new list to add.
262  * \param head the place to add it in the first list.
263  *
264  * The contents of \a list are added at the start of \a head.  \a list is in an
265  * undefined state on return.
266  */
267 static inline void cfs_list_splice(cfs_list_t *list,
268                                    cfs_list_t *head)
269 {
270         if (!cfs_list_empty(list))
271                 __cfs_list_splice(list, head);
272 }
273
274 /**
275  * Join two lists and reinitialise the emptied list.
276  * \param list the new list to add.
277  * \param head the place to add it in the first list.
278  *
279  * The contents of \a list are added at the start of \a head.  \a list is empty
280  * on return.
281  */
282 static inline void cfs_list_splice_init(cfs_list_t *list,
283                                         cfs_list_t *head)
284 {
285         if (!cfs_list_empty(list)) {
286                 __cfs_list_splice(list, head);
287                 CFS_INIT_LIST_HEAD(list);
288         }
289 }
290
291 /**
292  * Get the container of a list
293  * \param ptr    the embedded list.
294  * \param type   the type of the struct this is embedded in.
295  * \param member the member name of the list within the struct.
296  */
297 #define cfs_list_entry(ptr, type, member) \
298         ((type *)((char *)(ptr)-(char *)(&((type *)0)->member)))
299
300 /**
301  * Iterate over a list
302  * \param pos   the iterator
303  * \param head  the list to iterate over
304  *
305  * Behaviour is undefined if \a pos is removed from the list in the body of the
306  * loop.
307  */
308 #define cfs_list_for_each(pos, head) \
309         for (pos = (head)->next, prefetch(pos->next); pos != (head); \
310                 pos = pos->next, prefetch(pos->next))
311
312 /**
313  * Iterate over a list safely
314  * \param pos   the iterator
315  * \param n     temporary storage
316  * \param head  the list to iterate over
317  *
318  * This is safe to use if \a pos could be removed from the list in the body of
319  * the loop.
320  */
321 #define cfs_list_for_each_safe(pos, n, head) \
322         for (pos = (head)->next, n = pos->next; pos != (head); \
323                 pos = n, n = pos->next)
324
325 /**
326  * Iterate over a list continuing after existing point
327  * \param pos    the type * to use as a loop counter
328  * \param head   the list head
329  * \param member the name of the list_struct within the struct  
330  */
331 #define cfs_list_for_each_entry_continue(pos, head, member)                 \
332         for (pos = cfs_list_entry(pos->member.next, typeof(*pos), member);  \
333              prefetch(pos->member.next), &pos->member != (head);            \
334              pos = cfs_list_entry(pos->member.next, typeof(*pos), member))
335
336 /**
337  * \defgroup hlist Hash List
338  * Double linked lists with a single pointer list head.
339  * Mostly useful for hash tables where the two pointer list head is too
340  * wasteful.  You lose the ability to access the tail in O(1).
341  * @{
342  */
343
344 typedef struct cfs_hlist_node {
345         struct cfs_hlist_node *next, **pprev;
346 } cfs_hlist_node_t;
347
348 typedef struct cfs_hlist_head {
349         cfs_hlist_node_t *first;
350 } cfs_hlist_head_t;
351
352 /* @} */
353
354 /*
355  * "NULL" might not be defined at this point
356  */
357 #ifdef NULL
358 #define NULL_P NULL
359 #else
360 #define NULL_P ((void *)0)
361 #endif
362
363 /**
364  * \addtogroup hlist
365  * @{
366  */
367
368 #define CFS_HLIST_HEAD_INIT { NULL_P }
369 #define CFS_HLIST_HEAD(name) cfs_hlist_head_t name = { NULL_P }
370 #define CFS_INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL_P)
371 #define CFS_INIT_HLIST_NODE(ptr) ((ptr)->next = NULL_P, (ptr)->pprev = NULL_P)
372
373 static inline int cfs_hlist_unhashed(const cfs_hlist_node_t *h)
374 {
375         return !h->pprev;
376 }
377
378 static inline int cfs_hlist_empty(const cfs_hlist_head_t *h)
379 {
380         return !h->first;
381 }
382
383 static inline void __cfs_hlist_del(cfs_hlist_node_t *n)
384 {
385         cfs_hlist_node_t *next = n->next;
386         cfs_hlist_node_t **pprev = n->pprev;
387         *pprev = next;
388         if (next)
389                 next->pprev = pprev;
390 }
391
392 static inline void cfs_hlist_del(cfs_hlist_node_t *n)
393 {
394         __cfs_hlist_del(n);
395 }
396
397 static inline void cfs_hlist_del_init(cfs_hlist_node_t *n)
398 {
399         if (n->pprev)  {
400                 __cfs_hlist_del(n);
401                 CFS_INIT_HLIST_NODE(n);
402         }
403 }
404
405 static inline void cfs_hlist_add_head(cfs_hlist_node_t *n,
406                                       cfs_hlist_head_t *h)
407 {
408         cfs_hlist_node_t *first = h->first;
409         n->next = first;
410         if (first)
411                 first->pprev = &n->next;
412         h->first = n;
413         n->pprev = &h->first;
414 }
415
416 /* next must be != NULL */
417 static inline void cfs_hlist_add_before(cfs_hlist_node_t *n,
418                                         cfs_hlist_node_t *next)
419 {
420         n->pprev = next->pprev;
421         n->next = next;
422         next->pprev = &n->next;
423         *(n->pprev) = n;
424 }
425
426 static inline void cfs_hlist_add_after(cfs_hlist_node_t *n,
427                                        cfs_hlist_node_t *next)
428 {
429         next->next = n->next;
430         n->next = next;
431         next->pprev = &n->next;
432
433         if(next->next)
434                 next->next->pprev  = &next->next;
435 }
436
437 #define cfs_hlist_entry(ptr, type, member) container_of(ptr,type,member)
438
439 #define cfs_hlist_for_each(pos, head) \
440         for (pos = (head)->first; pos && (prefetch(pos->next), 1); \
441              pos = pos->next)
442
443 #define cfs_hlist_for_each_safe(pos, n, head) \
444         for (pos = (head)->first; pos && (n = pos->next, 1); \
445              pos = n)
446
447 /**
448  * Iterate over an hlist of given type
449  * \param tpos   the type * to use as a loop counter.
450  * \param pos    the &struct hlist_node to use as a loop counter.
451  * \param head   the head for your list.
452  * \param member the name of the hlist_node within the struct.
453  */
454 #define cfs_hlist_for_each_entry(tpos, pos, head, member)                    \
455         for (pos = (head)->first;                                            \
456              pos && ({ prefetch(pos->next); 1;}) &&                          \
457                 ({ tpos = cfs_hlist_entry(pos, typeof(*tpos), member); 1;}); \
458              pos = pos->next)
459
460 /**
461  * Iterate over an hlist continuing after existing point
462  * \param tpos   the type * to use as a loop counter.
463  * \param pos    the &struct hlist_node to use as a loop counter.
464  * \param member the name of the hlist_node within the struct.
465  */
466 #define cfs_hlist_for_each_entry_continue(tpos, pos, member)                 \
467         for (pos = (pos)->next;                                              \
468              pos && ({ prefetch(pos->next); 1;}) &&                          \
469                 ({ tpos = cfs_hlist_entry(pos, typeof(*tpos), member); 1;}); \
470              pos = pos->next)
471
472 /**
473  * Iterate over an hlist continuing from an existing point
474  * \param tpos   the type * to use as a loop counter.
475  * \param pos    the &struct hlist_node to use as a loop counter.
476  * \param member the name of the hlist_node within the struct.
477  */
478 #define cfs_hlist_for_each_entry_from(tpos, pos, member)                         \
479         for (; pos && ({ prefetch(pos->next); 1;}) &&                        \
480                 ({ tpos = cfs_hlist_entry(pos, typeof(*tpos), member); 1;}); \
481              pos = pos->next)
482
483 /**
484  * Iterate over an hlist of given type safe against removal of list entry
485  * \param tpos   the type * to use as a loop counter.
486  * \param pos    the &struct hlist_node to use as a loop counter.
487  * \param n      another &struct hlist_node to use as temporary storage
488  * \param head   the head for your list.
489  * \param member the name of the hlist_node within the struct.
490  */
491 #define cfs_hlist_for_each_entry_safe(tpos, pos, n, head, member)            \
492         for (pos = (head)->first;                                            \
493              pos && ({ n = pos->next; 1; }) &&                               \
494                 ({ tpos = cfs_hlist_entry(pos, typeof(*tpos), member); 1;}); \
495              pos = n)
496
497 /* @} */
498
499 #endif /* __linux__ && __KERNEL__ */
500
501 #ifndef cfs_list_for_each_prev
502 /**
503  * Iterate over a list in reverse order
504  * \param pos   the &struct list_head to use as a loop counter.
505  * \param head  the head for your list.
506  */
507 #define cfs_list_for_each_prev(pos, head) \
508         for (pos = (head)->prev, prefetch(pos->prev); pos != (head);     \
509                 pos = pos->prev, prefetch(pos->prev))
510
511 #endif /* cfs_list_for_each_prev */
512
513 #ifndef cfs_list_for_each_entry
514 /**
515  * Iterate over a list of given type
516  * \param pos        the type * to use as a loop counter.
517  * \param head       the head for your list.
518  * \param member     the name of the list_struct within the struct.
519  */
520 #define cfs_list_for_each_entry(pos, head, member)                          \
521         for (pos = cfs_list_entry((head)->next, typeof(*pos), member),      \
522                      prefetch(pos->member.next);                            \
523              &pos->member != (head);                                        \
524              pos = cfs_list_entry(pos->member.next, typeof(*pos), member),  \
525              prefetch(pos->member.next))
526 #endif /* cfs_list_for_each_entry */
527
528 #ifndef cfs_list_for_each_entry_reverse
529 /**
530  * Iterate backwards over a list of given type.
531  * \param pos        the type * to use as a loop counter.
532  * \param head       the head for your list.
533  * \param member     the name of the list_struct within the struct.
534  */
535 #define cfs_list_for_each_entry_reverse(pos, head, member)                  \
536         for (pos = cfs_list_entry((head)->prev, typeof(*pos), member);      \
537              prefetch(pos->member.prev), &pos->member != (head);            \
538              pos = cfs_list_entry(pos->member.prev, typeof(*pos), member))
539 #endif /* cfs_list_for_each_entry_reverse */
540
541 #ifndef cfs_list_for_each_entry_safe
542 /**
543  * Iterate over a list of given type safe against removal of list entry
544  * \param pos        the type * to use as a loop counter.
545  * \param n          another type * to use as temporary storage
546  * \param head       the head for your list.
547  * \param member     the name of the list_struct within the struct.
548  */
549 #define cfs_list_for_each_entry_safe(pos, n, head, member)                   \
550         for (pos = cfs_list_entry((head)->next, typeof(*pos), member),       \
551                 n = cfs_list_entry(pos->member.next, typeof(*pos), member);  \
552              &pos->member != (head);                                         \
553              pos = n, n = cfs_list_entry(n->member.next, typeof(*n), member))
554
555 #endif /* cfs_list_for_each_entry_safe */
556
557 #ifndef cfs_list_for_each_entry_safe_from
558 /**
559  * Iterate over a list continuing from an existing point
560  * \param pos        the type * to use as a loop cursor.
561  * \param n          another type * to use as temporary storage
562  * \param head       the head for your list.
563  * \param member     the name of the list_struct within the struct.
564  *
565  * Iterate over list of given type from current point, safe against
566  * removal of list entry.
567  */
568 #define cfs_list_for_each_entry_safe_from(pos, n, head, member)             \
569         for (n = cfs_list_entry(pos->member.next, typeof(*pos), member);    \
570              &pos->member != (head);                                        \
571              pos = n, n = cfs_list_entry(n->member.next, typeof(*n), member))
572 #endif /* cfs_list_for_each_entry_safe_from */
573
574 #define cfs_list_for_each_entry_typed(pos, head, type, member)          \
575         for (pos = cfs_list_entry((head)->next, type, member),          \
576                      prefetch(pos->member.next);                        \
577              &pos->member != (head);                                    \
578              pos = cfs_list_entry(pos->member.next, type, member),      \
579              prefetch(pos->member.next))
580
581 #define cfs_list_for_each_entry_reverse_typed(pos, head, type, member)  \
582         for (pos = cfs_list_entry((head)->prev, type, member);          \
583              prefetch(pos->member.prev), &pos->member != (head);        \
584              pos = cfs_list_entry(pos->member.prev, type, member))
585
586 #define cfs_list_for_each_entry_safe_typed(pos, n, head, type, member)  \
587     for (pos = cfs_list_entry((head)->next, type, member),              \
588                 n = cfs_list_entry(pos->member.next, type, member);     \
589              &pos->member != (head);                                    \
590              pos = n, n = cfs_list_entry(n->member.next, type, member))
591
592 #define cfs_list_for_each_entry_safe_from_typed(pos, n, head, type, member)  \
593         for (n = cfs_list_entry(pos->member.next, type, member);             \
594              &pos->member != (head);                                         \
595              pos = n, n = cfs_list_entry(n->member.next, type, member))
596
597 #define cfs_hlist_for_each_entry_typed(tpos, pos, head, type, member)   \
598         for (pos = (head)->first;                                       \
599              pos && (prefetch(pos->next), 1) &&                         \
600                 (tpos = cfs_hlist_entry(pos, type, member), 1);         \
601              pos = pos->next)
602
603 #define cfs_hlist_for_each_entry_safe_typed(tpos, pos, n, head, type, member) \
604         for (pos = (head)->first;                                             \
605              pos && (n = pos->next, 1) &&                                     \
606                 (tpos = cfs_hlist_entry(pos, type, member), 1);               \
607              pos = n)
608
609 #endif /* __LIBCFS_LUSTRE_LIST_H__ */