00001
00043 #ifndef SLIST_H_INCLUDED
00044 #define SLIST_H_INCLUDED
00045
00046 #include <assert.h>
00047 #include <types.h>
00048
00052 struct slist_node {
00053 struct slist_node *next;
00054 };
00055
00059 struct slist {
00064 struct slist_node first;
00069 struct slist_node *last;
00070 };
00071
00075 static inline void slist_init(struct slist *list)
00076 {
00077 list->first.next = &list->first;
00078 list->last = &list->first;
00079 }
00080
00087 static inline bool slist_is_empty(struct slist *list)
00088 {
00089 return list->first.next == &list->first;
00090 }
00091
00097 static inline bool slist_node_is_last(struct slist *list,
00098 struct slist_node *node)
00099 {
00100 return node == list->last;
00101 }
00102
00110 static inline bool slist_node_is_valid(struct slist *list,
00111 struct slist_node *node)
00112 {
00113 return node != &list->first;
00114 }
00115
00124 #define slist_entry(node, type, member) \
00125 container_of(node, type, member)
00126
00130 static inline void slist_insert_head(struct slist *list,
00131 struct slist_node *node)
00132 {
00133 node->next = list->first.next;
00134 if (list->last == &list->first)
00135 list->last = node;
00136 list->first.next = node;
00137 }
00138
00142 static inline void slist_insert_tail(struct slist *list,
00143 struct slist_node *node)
00144 {
00145 node->next = &list->first;
00146 list->last->next = node;
00147 list->last = node;
00148 }
00149
00164 static inline void slist_borrow_to_tail(struct slist *to, struct slist *from)
00165 {
00166 assert(!slist_is_empty(from));
00167
00168 from->last->next = &to->first;
00169 to->last->next = from->first.next;
00170 to->last = from->last;
00171 }
00172
00185 static inline void slist_give_back_head(struct slist *to, struct slist *from)
00186 {
00187 from->first.next = to->last->next;
00188 if (from->first.next == &from->first)
00189 from->last = &from->first;
00190 to->last->next = &to->first;
00191 }
00192
00198 static inline void slist_move_to_tail(struct slist *to, struct slist *from)
00199 {
00200 slist_borrow_to_tail(to, from);
00201 slist_init(from);
00202 }
00203
00209 static inline void slist_move_to_head(struct slist *to, struct slist *from)
00210 {
00211 assert(!slist_is_empty(from));
00212
00213 from->last->next = to->first.next;
00214 to->first.next = from->first.next;
00215 if (to->last == &to->first)
00216 to->last = from->last;
00217 slist_init(from);
00218 }
00219
00223 static inline struct slist_node *slist_peek_head_node(struct slist *list)
00224 {
00225 assert(list);
00226 return list->first.next;
00227 }
00228
00235 #define slist_peek_head(list, type, member) \
00236 slist_entry(slist_peek_head_node(list), type, member)
00237
00241 static inline struct slist_node *slist_peek_tail_node(struct slist *list)
00242 {
00243 assert(list);
00244 return list->last;
00245 }
00246
00253 #define slist_peek_tail(list, type, member) \
00254 slist_entry(slist_peek_tail_node(list), type, member)
00255
00259 static inline struct slist_node *slist_peek_next_node(struct slist_node *node)
00260 {
00261 assert(node);
00262 return node->next;
00263 }
00264
00271 #define slist_peek_next(node, type, member) \
00272 slist_entry(slist_peek_next_node(node), type, member)
00273
00278 static inline struct slist_node *slist_pop_head_node(struct slist *list)
00279 {
00280 struct slist_node *node;
00281
00282 assert(list);
00283 assert(list->first.next != &list->first);
00284
00285 node = list->first.next;
00286 list->first.next = node->next;
00287 if (list->last == node)
00288 list->last = &list->first;
00289
00290 return node;
00291 }
00292
00300 #define slist_pop_head(list, type, member) \
00301 container_of(slist_pop_head_node(list), type, member)
00302
00303 #endif