| #ifndef LIST_H |
| #define LIST_H |
| |
| #include <stdbool.h> |
| |
| /* |
| * Circular doubly-linked list. The pointer to the list is a list item itself, |
| * like in the kernel implementation. |
| */ |
| struct linked_list { |
| struct linked_list *prev; |
| struct linked_list *next; |
| }; |
| |
| /* |
| * An empty list is a list item whose prev and next both point to itself. |
| * Returns true if the list is empty. |
| */ |
| static inline bool is_list_empty(struct linked_list *p) |
| { |
| return !p->next || !p->prev || p == p->next || p == p->prev; |
| } |
| |
| /* |
| * Remove the given element from the list, if the list is not already empty. |
| * The removed element is returned. |
| */ |
| static inline struct linked_list *list_remove(struct linked_list *l) |
| { |
| if (is_list_empty(l)) |
| return NULL; |
| |
| l->prev->next = l->next; |
| l->next->prev = l->prev; |
| l->prev = l->next = NULL; |
| |
| return l; |
| } |
| |
| /* |
| * Add the given element after the given list head. |
| */ |
| static inline void list_add(struct linked_list *head, struct linked_list *li) |
| { |
| assert(li); |
| assert(head); |
| li->prev = head; |
| li->next = head->next; |
| head->next->prev = li; |
| head->next = li; |
| } |
| |
| /* |
| * Add the given element before the given list head. |
| */ |
| static inline void list_add_tail(struct linked_list *head, struct linked_list *li) |
| { |
| assert(head); |
| list_add(head->prev, li); |
| } |
| |
| #endif |