SASC-NG
DVBSoftCAM

list.h

Go to the documentation of this file.
00001 #ifndef _LIST_
00002 #define _LIST_
00003 
00004 /*
00005  * These are non-NULL pointers that will result in page faults
00006  * under normal circumstances, used to verify that nobody uses
00007  * non-initialized list entries.
00008  */
00009 #define LIST_POISON1  ((void *) 0x00100100)
00010 #define LIST_POISON2  ((void *) 0x00200200)
00011 
00012 struct list_head {
00013         struct list_head *next, *prev;
00014         unsigned int priority;
00015 };
00016 
00017 #define LIST_HEAD_INIT(name) { &(name), &(name), (unsigned int)-1 }
00018 
00019 #define LIST_HEAD(name) \
00020         struct list_head name = LIST_HEAD_INIT(name)
00021 
00022 #define INIT_LIST_HEAD(ptr) do { \
00023         (ptr)->next = (ptr); (ptr)->prev = (ptr); (ptr)->priority = (unsigned int)-1;\
00024 } while (0)
00025 
00026 /*
00027  * Insert a new entry between two known consecutive entries. 
00028  *
00029  * This is only for internal list manipulation where we know
00030  * the prev/next entries already!
00031  */
00032 static inline void __list_add(struct list_head *_new,
00033                               struct list_head *_prev,
00034                               struct list_head *_next)
00035 {
00036         _next->prev = _new;
00037         _new->next = _next;
00038         _new->prev = _prev;
00039         _prev->next = _new;
00040 }
00041 
00050 static inline void list_add(struct list_head *_new, struct list_head *_head)
00051 {
00052         __list_add(_new, _head, _head->next);
00053 }
00054 
00063 static inline void list_add_tail(struct list_head *_new,
00064                                  struct list_head *_head)
00065 {
00066         __list_add(_new, _head->prev, _head);
00067 }
00068 
00069 static inline void list_add_priority(struct list_head *_new,
00070                                      struct list_head *_head,
00071                                      int priority)
00072 {
00073         struct list_head *pos = _head;
00074         _new->priority = priority;
00075         for (pos = _head->next; pos != _head; pos = pos->next)
00076           if((unsigned int)priority <= pos->priority) {
00077             __list_add(_new, pos->prev, pos);
00078             return;
00079           }
00080         __list_add(_new, _head, _head->next);
00081 }
00082 
00083 /*
00084  * Delete a list entry by making the prev/next entries
00085  * point to each other.
00086  *
00087  * This is only for internal list manipulation where we know
00088  * the prev/next entries already!
00089  */
00090 static inline void __list_del(struct list_head * prev, struct list_head * next)
00091 {
00092         next->prev = prev;
00093         prev->next = next;
00094 }
00095 
00102 static inline void list_del(struct list_head *entry)
00103 {
00104         __list_del(entry->prev, entry->next);
00105         entry->next = (struct list_head *)LIST_POISON1;
00106         entry->prev = (struct list_head *)LIST_POISON2;
00107 }
00108 
00113 static inline int list_empty(const struct list_head *head)
00114 {
00115         return head->next == head;
00116 }
00117 
00124 #define list_entry(ptr, type) ((type *)ptr)
00125 
00131 #define list_for_each(pos, head) \
00132         for (pos = (head)->next; pos != (head); pos = pos->next)
00133 
00134 #define list_for_each_safe(pos, n, head) \
00135         for (pos = (head)->next, n = pos->next; pos != (head); \
00136                 pos = n, n = pos->next)
00137 
00138 #define list_add_l(_var, _ll, _lock) {\
00139   pthread_mutex_lock(_lock);            \
00140   list_add(_var, _ll);                  \
00141   pthread_mutex_unlock(_lock);          \
00142 }
00143   
00144 #define pop_entry_from_queue_l(_var, _ll, _type, _lock) {\
00145   pthread_mutex_lock(_lock);            \
00146   if(list_empty(_ll))  {                        \
00147     _var = (_type *)calloc(1, sizeof(_type));   \
00148   } else {                                      \
00149     _var = list_entry((_ll)->next, _type);      \
00150     list_del(&_var->list);                      \
00151   }                                             \
00152   pthread_mutex_unlock(_lock);          \
00153 }
00154 
00155 #define pop_entry_from_queue(_var, _ll, _type) {\
00156   if(list_empty(_ll))  {                        \
00157     _var = (_type *)calloc(1, sizeof(_type));   \
00158   } else {                                      \
00159     _var = list_entry((_ll)->next, _type);      \
00160     list_del(&_var->list);                      \
00161   }                                             \
00162 }
00163 
00164 #define ll_find_elem(elem, lhead, item, value, type) {  \
00165   struct list_head *lptr;                               \
00166   type *ptr;                                            \
00167   elem = NULL;                                          \
00168   list_for_each(lptr, &lhead) {                         \
00169     ptr = list_entry(lptr, type);                       \
00170     if(ptr->item == value)                              \
00171       elem = ptr;                                       \
00172   }                                                     \
00173 }
00174 
00175 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines