linuxlist.h

Go to the documentation of this file.
00001 #ifndef _LINUX_LLIST_H
00002 #define _LINUX_LLIST_H
00003 
00004 #include <stddef.h>
00005 
00006 #ifndef inline
00007 #define inline __inline__
00008 #endif
00009 
00012 static inline void prefetch(const void *x) {;}
00013 
00022 #define container_of(ptr, type, member) ({                      \
00023         const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
00024         (type *)( (char *)__mptr - offsetof(type,member) );})
00025 
00026 
00027 /*
00028  * These are non-NULL pointers that will result in page faults
00029  * under normal circumstances, used to verify that nobody uses
00030  * non-initialized llist entries.
00031  */
00032 #define LLIST_POISON1  ((void *) 0x00100100)
00033 #define LLIST_POISON2  ((void *) 0x00200200)
00034 
00035 /*
00036  * Simple doubly linked llist implementation.
00037  *
00038  * Some of the internal functions ("__xxx") are useful when
00039  * manipulating whole llists rather than single entries, as
00040  * sometimes we already know the next/prev entries and we can
00041  * generate better code by using them directly rather than
00042  * using the generic single-entry routines.
00043  */
00044 
00045 struct llist_head {
00046         struct llist_head *next, *prev;
00047 };
00048 
00049 #define LLIST_HEAD_INIT(name) { &(name), &(name) }
00050 
00051 #define LLIST_HEAD(name) \
00052         struct llist_head name = LLIST_HEAD_INIT(name)
00053 
00054 #define INIT_LLIST_HEAD(ptr) do { \
00055         (ptr)->next = (ptr); (ptr)->prev = (ptr); \
00056 } while (0)
00057 
00058 /*
00059  * Insert a new entry between two known consecutive entries.
00060  *
00061  * This is only for internal llist manipulation where we know
00062  * the prev/next entries already!
00063  */
00064 static inline void __llist_add(struct llist_head *new,
00065                                 struct llist_head *prev,
00066                                 struct llist_head *next)
00067 {
00068         next->prev = new;
00069         new->next = next;
00070         new->prev = prev;
00071         prev->next = new;
00072 }
00073 
00082 static inline void llist_add(struct llist_head *new, struct llist_head *head)
00083 {
00084         __llist_add(new, head, head->next);
00085 }
00086 
00095 static inline void llist_add_tail(struct llist_head *new, struct llist_head *head)
00096 {
00097         __llist_add(new, head->prev, head);
00098 }
00099 
00100 /*
00101  * Delete a llist entry by making the prev/next entries
00102  * point to each other.
00103  *
00104  * This is only for internal llist manipulation where we know
00105  * the prev/next entries already!
00106  */
00107 static inline void __llist_del(struct llist_head * prev, struct llist_head * next)
00108 {
00109         next->prev = prev;
00110         prev->next = next;
00111 }
00112 
00119 static inline void llist_del(struct llist_head *entry)
00120 {
00121         __llist_del(entry->prev, entry->next);
00122         entry->next = LLIST_POISON1;
00123         entry->prev = LLIST_POISON2;
00124 }
00125 
00130 static inline void llist_del_init(struct llist_head *entry)
00131 {
00132         __llist_del(entry->prev, entry->next);
00133         INIT_LLIST_HEAD(entry);
00134 }
00135 
00141 static inline void llist_move(struct llist_head *llist, struct llist_head *head)
00142 {
00143         __llist_del(llist->prev, llist->next);
00144         llist_add(llist, head);
00145 }
00146 
00152 static inline void llist_move_tail(struct llist_head *llist,
00153                                   struct llist_head *head)
00154 {
00155         __llist_del(llist->prev, llist->next);
00156         llist_add_tail(llist, head);
00157 }
00158 
00163 static inline int llist_empty(const struct llist_head *head)
00164 {
00165         return head->next == head;
00166 }
00167 
00168 static inline void __llist_splice(struct llist_head *llist,
00169                                  struct llist_head *head)
00170 {
00171         struct llist_head *first = llist->next;
00172         struct llist_head *last = llist->prev;
00173         struct llist_head *at = head->next;
00174 
00175         first->prev = head;
00176         head->next = first;
00177 
00178         last->next = at;
00179         at->prev = last;
00180 }
00181 
00187 static inline void llist_splice(struct llist_head *llist, struct llist_head *head)
00188 {
00189         if (!llist_empty(llist))
00190                 __llist_splice(llist, head);
00191 }
00192 
00200 static inline void llist_splice_init(struct llist_head *llist,
00201                                     struct llist_head *head)
00202 {
00203         if (!llist_empty(llist)) {
00204                 __llist_splice(llist, head);
00205                 INIT_LLIST_HEAD(llist);
00206         }
00207 }
00208 
00215 #define llist_entry(ptr, type, member) \
00216         container_of(ptr, type, member)
00217 
00223 #define llist_for_each(pos, head) \
00224         for (pos = (head)->next, prefetch(pos->next); pos != (head); \
00225                 pos = pos->next, prefetch(pos->next))
00226 
00237 #define __llist_for_each(pos, head) \
00238         for (pos = (head)->next; pos != (head); pos = pos->next)
00239 
00245 #define llist_for_each_prev(pos, head) \
00246         for (pos = (head)->prev, prefetch(pos->prev); pos != (head); \
00247                 pos = pos->prev, prefetch(pos->prev))
00248 
00255 #define llist_for_each_safe(pos, n, head) \
00256         for (pos = (head)->next, n = pos->next; pos != (head); \
00257                 pos = n, n = pos->next)
00258 
00265 #define llist_for_each_entry(pos, head, member)                         \
00266         for (pos = llist_entry((head)->next, typeof(*pos), member),     \
00267                         prefetch(pos->member.next);                     \
00268                 &pos->member != (head);                                         \
00269                 pos = llist_entry(pos->member.next, typeof(*pos), member),      \
00270                         prefetch(pos->member.next))
00271 
00278 #define llist_for_each_entry_reverse(pos, head, member)                 \
00279         for (pos = llist_entry((head)->prev, typeof(*pos), member),     \
00280                         prefetch(pos->member.prev);                     \
00281                 &pos->member != (head);                                         \
00282                 pos = llist_entry(pos->member.prev, typeof(*pos), member),      \
00283                         prefetch(pos->member.prev))
00284 
00292 #define llist_for_each_entry_continue(pos, head, member)                \
00293         for (pos = llist_entry(pos->member.next, typeof(*pos), member), \
00294                         prefetch(pos->member.next);                     \
00295                 &pos->member != (head);                                 \
00296                 pos = llist_entry(pos->member.next, typeof(*pos), member),      \
00297                         prefetch(pos->member.next))
00298 
00306 #define llist_for_each_entry_safe(pos, n, head, member)                 \
00307         for (pos = llist_entry((head)->next, typeof(*pos), member),     \
00308                 n = llist_entry(pos->member.next, typeof(*pos), member);        \
00309                 &pos->member != (head);                                         \
00310                 pos = n, n = llist_entry(n->member.next, typeof(*n), member))
00311 
00317 #define llist_for_each_rcu(pos, head) \
00318         for (pos = (head)->next, prefetch(pos->next); pos != (head); \
00319                 pos = pos->next, ({ smp_read_barrier_depends(); 0;}), prefetch(pos->next))
00320 
00321 #define __llist_for_each_rcu(pos, head) \
00322         for (pos = (head)->next; pos != (head); \
00323                 pos = pos->next, ({ smp_read_barrier_depends(); 0;}))
00324 
00332 #define llist_for_each_safe_rcu(pos, n, head) \
00333         for (pos = (head)->next, n = pos->next; pos != (head); \
00334                 pos = n, ({ smp_read_barrier_depends(); 0;}), n = pos->next)
00335 
00342 #define llist_for_each_entry_rcu(pos, head, member)                     \
00343         for (pos = llist_entry((head)->next, typeof(*pos), member),     \
00344                         prefetch(pos->member.next);                     \
00345                 &pos->member != (head);                                         \
00346                 pos = llist_entry(pos->member.next, typeof(*pos), member),      \
00347                         ({ smp_read_barrier_depends(); 0;}),            \
00348                         prefetch(pos->member.next))
00349 
00350 
00357 #define llist_for_each_continue_rcu(pos, head) \
00358         for ((pos) = (pos)->next, prefetch((pos)->next); (pos) != (head); \
00359                 (pos) = (pos)->next, ({ smp_read_barrier_depends(); 0;}), prefetch((pos)->next))
00360 
00361 
00362 #endif
00363 

Generated on Sat Nov 22 04:00:37 2008 for NuFW by  doxygen 1.4.7