1 #ifndef _LIST_H_ 2 #define _LIST_H_ 3 4 #include <stddef.h> 5 6 #ifndef offsetof 7 #define offsetof(type, md) ((size_t)&((type *)0)->md) 8 #endif 9 10 #ifndef container_of 11 #define container_of(ptr, type, member) \ 12 ((type *)((char *)(ptr) - offsetof(type, member))) 13 #endif 14 15 struct list_item { 16 struct list_item *next; 17 struct list_item *prev; 18 }; 19 20 struct list { 21 struct list_item *head; 22 struct list_item *tail; 23 }; 24 25 #define LIST_INIT(name) { 0, 0 } 26 27 #define LIST(name) \ 28 struct list name = LIST_INIT(name) 29 30 #define list_entry(ptr, type, member) \ 31 container_of(ptr, type, member) 32 list_init(struct list * list)33 static inline void list_init(struct list *list) 34 { 35 list->head = 0; 36 list->tail = 0; 37 } 38 list_append(struct list * list,struct list_item * item)39 static inline void list_append(struct list *list, struct list_item *item) 40 { 41 item->next = 0; 42 item->prev = list->tail; 43 if (list->tail != 0) 44 list->tail->next = item; 45 else 46 list->head = item; 47 list->tail = item; 48 } 49 list_prepend(struct list * list,struct list_item * item)50 static inline void list_prepend(struct list *list, struct list_item *item) 51 { 52 item->prev = 0; 53 item->next = list->head; 54 if (list->head == 0) 55 list->tail = item; 56 list->head = item; 57 } 58 list_insert(struct list * list,struct list_item * after,struct list_item * item)59 static inline void list_insert(struct list *list, struct list_item *after, struct list_item *item) 60 { 61 if (after == 0) { 62 list_prepend(list, item); 63 return; 64 } 65 item->prev = after; 66 item->next = after->next; 67 after->next = item; 68 if (item->next) 69 item->next->prev = item; 70 if (list->tail == after) 71 list->tail = item; 72 } 73 list_remove(struct list * list,struct list_item * item)74 static inline void list_remove(struct list *list, struct list_item *item) 75 { 76 if (item->next) 77 item->next->prev = item->prev; 78 if (list->head == item) { 79 list->head = item->next; 80 if (list->head == 0) 81 list->tail = 0; 82 } else { 83 item->prev->next = item->next; 84 if (list->tail == item) 85 list->tail = item->prev; 86 } 87 item->prev = item->next = 0; 88 } 89 list_pop(struct list * list)90 static inline struct list_item *list_pop(struct list *list) 91 { 92 struct list_item *item; 93 item = list->head; 94 if (item == 0) 95 return 0; 96 list_remove(list, item); 97 return item; 98 } 99 list_last(struct list * list)100 static inline struct list_item *list_last(struct list *list) 101 { 102 return list->tail; 103 } 104 list_first(struct list * list)105 static inline struct list_item *list_first(struct list *list) 106 { 107 return list->head; 108 } 109 110 list_next(struct list_item * item)111 static inline struct list_item *list_next(struct list_item *item) 112 { 113 return item->next; 114 } 115 116 #define list_push list_append 117 118 #define list_for_each(_list, _iter) \ 119 for (_iter = (_list)->head; (_iter) != 0; _iter = (_iter)->next) 120 121 #define list_for_each_after(_node, _iter) \ 122 for (_iter = (_node)->next; (_iter) != 0; _iter = (_iter)->next) 123 124 #define list_for_each_safe(_list, _iter, _bkup) \ 125 for (_iter = (_list)->head; (_iter) != 0 && ((_bkup = (_iter)->next) || 1); _iter = (_bkup)) 126 127 #define list_for_each_safe_after(_node, _iter, _bkup) \ 128 for (_iter = (_node)->next; (_iter) != 0 && ((_bkup = (_iter)->next) || 1); _iter = (_bkup)) 129 130 #endif 131