#ifndef __USER_LIST_H #define __USER_LIST_H #include #include #define DEBUG_LIST #ifdef DEBUG_LIST #include #include #ifndef LIST_BUG #define LIST_BUG() do { printf(">>>>> list bug <<<< at %d\n",__LINE__); kill(getpid(),SIGSEGV); } while(0) #endif #define __LIST_MAGIC 0xdeabbeef #define __LIST_MAGIC_POISON 0xbeefdead #define __LIST_MAGIC_COMMA , __LIST_MAGIC #define __LIST_MAGIC_ASSIGN(x) (x).magic = __LIST_MAGIC; #else #define __LIST_MAGIC #define __LIST_MAGIC_COMMA #define __LIST_MAGIC_ASSIGN(x) #endif #define __LIST_POISON ((struct list_head *)-1) struct list_head { struct list_head *next; struct list_head *prev; #ifdef DEBUG_LIST int magic; #endif }; #define LIST_HEAD_INIT(x) { &x, &x __LIST_MAGIC_COMMA} #define LIST_HEAD_DECLARE(x) struct list_head x = LIST_HEAD_INIT(x) #define INIT_LIST_HEAD(x) do { (x).next = &x; (x).prev = &x; __LIST_MAGIC_ASSIGN(x)} while (0) #define list_for_each(p,list) for(p=(list)->next; p != list; p=p->next) #define list_for_each_reverse(p,list) for(p=(list)->prev; p != list; p=p->prev) #define list_for_each_safe(p,n,list) for(p=(list)->next,n=p->next; p != list; p=n,n=p->next) #ifdef DEBUG_LIST static inline void list_check(struct list_head *x) { struct list_head *p; list_for_each_reverse(p,x) { if (p->magic != __LIST_MAGIC) LIST_BUG(); } list_for_each(p,x) { if (p->magic != __LIST_MAGIC) LIST_BUG(); } } #endif static inline void list_add(struct list_head *x,struct list_head *list) { #ifdef DEBUG_LIST if (x->magic == __LIST_MAGIC_POISON && (x->next != __LIST_POISON || x->prev != __LIST_POISON)) LIST_BUG(); #endif x->next = list->next; x->prev = list; list->next->prev = x; list->next = x; #ifdef DEBUG_LIST x->magic = __LIST_MAGIC; list_check(list); #endif } static inline void list_add_tail(struct list_head *x, struct list_head *list) { #ifdef DEBUG_LIST if (x->magic == __LIST_MAGIC && (x->next != __LIST_POISON || x->prev != __LIST_POISON)) LIST_BUG(); #endif x->prev = list->prev; x->next = list; list->prev->next = x; list->prev = x; #ifdef DEBUG_LIST x->magic = __LIST_MAGIC; list_check(list); #endif } #define list_entry(p,type,list) ((type*)(((char*)(p))-((char*)&(((type*)NULL)->list)))) #define list_empty(list) ((list)->next == (list)) #define list_head(list) ((list)->next) static inline void list_del(struct list_head *x) { #ifdef DEBUG_LIST if (x->magic != __LIST_MAGIC) LIST_BUG(); list_check(x); x->magic = __LIST_MAGIC_POISON; #endif x->prev->next = x->next; x->next->prev = x->prev; x->next = __LIST_POISON; x->prev = __LIST_POISON; } static inline struct list_head * pop_list_head(struct list_head *head) { struct list_head *p; if (list_empty(head)) return NULL; p = head->next; list_del(p); #ifdef DEBUG_LIST list_check(head); #endif return p; } #endif /* __USER_LIST_H */