1 #ifndef _LINUX_HLIST_H 2 #define _LINUX_HLIST_H 3 4 /* 5 * Double linked lists with a single pointer list head. 6 * Mostly useful for hash tables where the two pointer list head is 7 * too wasteful. 8 * You lose the ability to access the tail in O(1). 9 */ 10 11 struct hlist_head { 12 struct hlist_node *first; 13 }; 14 15 struct hlist_node { 16 struct hlist_node *next, **pprev; 17 }; 18 19 #ifndef offsetof 20 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 21 #endif 22 23 #ifndef container_of 24 /** 25 * container_of - cast a member of a structure out to the containing structure 26 * @ptr: the pointer to the member. 27 * @type: the type of the container struct this is embedded in. 28 * @member: the name of the member within the struct. 29 * 30 */ 31 #define container_of(ptr, type, member) ({ 32 const typeof(((type *)0)->member) * __mptr = (ptr); 33 (type *)((char *)__mptr - offsetof(type, member)); }) 34 #endif 35 36 #define HLIST_HEAD_INIT { .first = NULL } 37 #define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } 38 #define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) 39 static inline void INIT_HLIST_NODE(struct hlist_node *h) 40 { 41 h->next = NULL; 42 h->pprev = NULL; 43 } 44 45 static inline int hlist_unhashed(const struct hlist_node *h) 46 { 47 return !h->pprev; 48 } 49 50 static inline int hlist_empty(const struct hlist_head *h) 51 { 52 return !h->first; 53 } 54 55 static inline void __hlist_del(struct hlist_node *n) 56 { 57 struct hlist_node *next = n->next; 58 struct hlist_node **pprev = n->pprev; 59 *pprev = next; 60 if (next) 61 next->pprev = pprev; 62 } 63 64 static inline void hlist_del(struct hlist_node *n) 65 { 66 __hlist_del(n); 67 INIT_HLIST_NODE(n); 68 } 69 70 static inline void hlist_del_init(struct hlist_node *n) 71 { 72 if (!hlist_unhashed(n)) { 73 __hlist_del(n); 74 INIT_HLIST_NODE(n); 75 } 76 } 77 78 static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) 79 { 80 struct hlist_node *first = h->first; 81 n->next = first; 82 if (first) 83 first->pprev = &n->next; 84 h->first = n; 85 n->pprev = &h->first; 86 } 87 88 /* next must be != NULL */ 89 static inline void hlist_add_before(struct hlist_node *n, 90 struct hlist_node *next) 91 { 92 n->pprev = next->pprev; 93 n->next = next; 94 next->pprev = &n->next; 95 *(n->pprev) = n; 96 } 97 98 static inline void hlist_add_after(struct hlist_node *n, 99 struct hlist_node *next) 100 { 101 next->next = n->next; 102 n->next = next; 103 next->pprev = &n->next; 104 105 if(next->next) 106 next->next->pprev = &next->next; 107 } 108 109 /* after that we‘ll appear to be on some hlist and hlist_del will work */ 110 static inline void hlist_add_fake(struct hlist_node *n) 111 { 112 n->pprev = &n->next; 113 } 114 115 /* 116 * Move a list from one list head to another. Fixup the pprev 117 * reference of the first entry if it exists. 118 */ 119 static inline void hlist_move_list(struct hlist_head *old, 120 struct hlist_head *new) 121 { 122 new->first = old->first; 123 if (new->first) 124 new->first->pprev = &new->first; 125 old->first = NULL; 126 } 127 128 #define hlist_entry(ptr, type, member) container_of(ptr,type,member) 129 130 #define hlist_for_each(pos, head) 131 for (pos = (head)->first; pos ; pos = pos->next) 132 133 #define hlist_for_each_safe(pos, n, head) 134 for (pos = (head)->first; pos && ({ n = pos->next; 1; }); 135 pos = n) 136 137 /** 138 * hlist_for_each_entry - iterate over list of given type 139 * @tpos: the type * to use as a loop cursor. 140 * @pos: the &struct hlist_node to use as a loop cursor. 141 * @head: the head for your list. 142 * @member: the name of the hlist_node within the struct. 143 */ 144 #define hlist_for_each_entry(tpos, pos, head, member) 145 for (pos = (head)->first; 146 pos && 147 ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); 148 pos = pos->next) 149 150 /** 151 * hlist_for_each_entry_continue - iterate over a hlist continuing after current point 152 * @tpos: the type * to use as a loop cursor. 153 * @pos: the &struct hlist_node to use as a loop cursor. 154 * @member: the name of the hlist_node within the struct. 155 */ 156 #define hlist_for_each_entry_continue(tpos, pos, member) 157 for (pos = (pos)->next; 158 pos && 159 ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); 160 pos = pos->next) 161 162 /** 163 * hlist_for_each_entry_from - iterate over a hlist continuing from current point 164 * @tpos: the type * to use as a loop cursor. 165 * @pos: the &struct hlist_node to use as a loop cursor. 166 * @member: the name of the hlist_node within the struct. 167 */ 168 #define hlist_for_each_entry_from(tpos, pos, member) 169 for (; pos && 170 ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); 171 pos = pos->next) 172 173 /** 174 * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry 175 * @tpos: the type * to use as a loop cursor. 176 * @pos: the &struct hlist_node to use as a loop cursor. 177 * @n: another &struct hlist_node to use as temporary storage 178 * @head: the head for your list. 179 * @member: the name of the hlist_node within the struct. 180 */ 181 #define hlist_for_each_entry_safe(tpos, pos, n, head, member) 182 for (pos = (head)->first; 183 pos && ({ n = pos->next; 1; }) && 184 ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); 185 pos = n) 186 187 #endif
时间: 2024-10-19 05:26:53