|
SASC
DVBSoftCAM
|
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