00001
00046 #ifndef SLIST_H_INCLUDED
00047 #define SLIST_H_INCLUDED
00048
00049 #include <assert.h>
00050 #include <types.h>
00051
00055 struct slist_node {
00056 struct slist_node *next;
00057 };
00058
00062 struct slist {
00067 struct slist_node first;
00072 struct slist_node *last;
00073 };
00074
00078 static inline void slist_init(struct slist *list)
00079 {
00080 list->first.next = &list->first;
00081 list->last = &list->first;
00082 }
00083
00090 static inline bool slist_is_empty(struct slist *list)
00091 {
00092 return list->first.next == &list->first;
00093 }
00094
00100 static inline bool slist_node_is_last(struct slist *list,
00101 struct slist_node *node)
00102 {
00103 return node == list->last;
00104 }
00105
00113 static inline bool slist_node_is_valid(struct slist *list,
00114 struct slist_node *node)
00115 {
00116 return node != &list->first;
00117 }
00118
00127 #define slist_entry(node, type, member) \
00128 container_of(node, type, member)
00129
00133 static inline void slist_insert_head(struct slist *list,
00134 struct slist_node *node)
00135 {
00136 node->next = list->first.next;
00137 if (list->last == &list->first)
00138 list->last = node;
00139 list->first.next = node;
00140 }
00141
00145 static inline void slist_insert_tail(struct slist *list,
00146 struct slist_node *node)
00147 {
00148 node->next = &list->first;
00149 list->last->next = node;
00150 list->last = node;
00151 }
00152
00167 static inline void slist_borrow_to_tail(struct slist *to, struct slist *from)
00168 {
00169 assert(!slist_is_empty(from));
00170
00171 from->last->next = &to->first;
00172 to->last->next = from->first.next;
00173 to->last = from->last;
00174 }
00175
00188 static inline void slist_give_back_head(struct slist *to, struct slist *from)
00189 {
00190 from->first.next = to->last->next;
00191 if (from->first.next == &from->first)
00192 from->last = &from->first;
00193 to->last->next = &to->first;
00194 }
00195
00201 static inline void slist_move_to_tail(struct slist *to, struct slist *from)
00202 {
00203 slist_borrow_to_tail(to, from);
00204 slist_init(from);
00205 }
00206
00210 static inline struct slist_node *slist_peek_head_node(struct slist *list)
00211 {
00212 assert(list);
00213 return list->first.next;
00214 }
00215
00222 #define slist_peek_head(list, type, member) \
00223 slist_entry(slist_peek_head_node(list), type, member)
00224
00228 static inline struct slist_node *slist_peek_tail_node(struct slist *list)
00229 {
00230 assert(list);
00231 return list->last;
00232 }
00233
00240 #define slist_peek_tail(list, type, member) \
00241 slist_entry(slist_peek_tail_node(list), type, member)
00242
00246 static inline struct slist_node *slist_peek_next_node(struct slist_node *node)
00247 {
00248 assert(node);
00249 return node->next;
00250 }
00251
00258 #define slist_peek_next(node, type, member) \
00259 slist_entry(slist_peek_next_node(node), type, member)
00260
00265 static inline struct slist_node *slist_pop_head_node(struct slist *list)
00266 {
00267 struct slist_node *node;
00268
00269 assert(list);
00270 assert(list->first.next != &list->first);
00271
00272 node = list->first.next;
00273 list->first.next = node->next;
00274 if (list->last == node)
00275 list->last = &list->first;
00276
00277 return node;
00278 }
00279
00287 #define slist_pop_head(list, type, member) \
00288 container_of(slist_pop_head_node(list), type, member)
00289
00293 #define slist_for_each_node(list, node) \
00294 for (node = (list)->first.next; node != &(list)->first; \
00295 node = node->next)
00296
00304 #define slist_for_each_node_safe(list, node, tmp) \
00305 for (node = (list)->first.next, tmp = node->next; \
00306 node != &(list)->first; \
00307 node = tmp, tmp = node->next)
00308
00315 #define slist_for_each(list, item, member) \
00316 for (item = slist_peek_head(list, typeof(*item), member); \
00317 &item->node != &(list)->first; \
00318 item = slist_peek_next(&item->member, \
00319 typeof(*item), member))
00320
00329 #define slist_for_each_safe(list, item, tmp, member) \
00330 for (item = slist_peek_head(list, typeof(*item), member), \
00331 tmp = slist_peek_next(&item->member, \
00332 typeof(*item), member); \
00333 &item->node != &(list)->first; \
00334 item = tmp, \
00335 tmp = slist_peek_next(&item->member, \
00336 typeof(*item), member)) \
00337
00338 #endif