1*9f0ae301SCornelia Huck #ifndef _LIST_H_ 2*9f0ae301SCornelia Huck #define _LIST_H_ 34fa2b92fSClaudio Imbrenda 44fa2b92fSClaudio Imbrenda #include <stdbool.h> 54fa2b92fSClaudio Imbrenda 64fa2b92fSClaudio Imbrenda /* 74fa2b92fSClaudio Imbrenda * Circular doubly-linked list. The pointer to the list is a list item itself, 84fa2b92fSClaudio Imbrenda * like in the kernel implementation. 94fa2b92fSClaudio Imbrenda */ 104fa2b92fSClaudio Imbrenda struct linked_list { 114fa2b92fSClaudio Imbrenda struct linked_list *prev; 124fa2b92fSClaudio Imbrenda struct linked_list *next; 134fa2b92fSClaudio Imbrenda }; 144fa2b92fSClaudio Imbrenda 154fa2b92fSClaudio Imbrenda /* 164fa2b92fSClaudio Imbrenda * An empty list is a list item whose prev and next both point to itself. 174fa2b92fSClaudio Imbrenda * Returns true if the list is empty. 184fa2b92fSClaudio Imbrenda */ is_list_empty(struct linked_list * p)194fa2b92fSClaudio Imbrendastatic inline bool is_list_empty(struct linked_list *p) 204fa2b92fSClaudio Imbrenda { 214fa2b92fSClaudio Imbrenda return !p->next || !p->prev || p == p->next || p == p->prev; 224fa2b92fSClaudio Imbrenda } 234fa2b92fSClaudio Imbrenda 244fa2b92fSClaudio Imbrenda /* 254fa2b92fSClaudio Imbrenda * Remove the given element from the list, if the list is not already empty. 264fa2b92fSClaudio Imbrenda * The removed element is returned. 274fa2b92fSClaudio Imbrenda */ list_remove(struct linked_list * l)284fa2b92fSClaudio Imbrendastatic inline struct linked_list *list_remove(struct linked_list *l) 294fa2b92fSClaudio Imbrenda { 304fa2b92fSClaudio Imbrenda if (is_list_empty(l)) 314fa2b92fSClaudio Imbrenda return NULL; 324fa2b92fSClaudio Imbrenda 334fa2b92fSClaudio Imbrenda l->prev->next = l->next; 344fa2b92fSClaudio Imbrenda l->next->prev = l->prev; 354fa2b92fSClaudio Imbrenda l->prev = l->next = NULL; 364fa2b92fSClaudio Imbrenda 374fa2b92fSClaudio Imbrenda return l; 384fa2b92fSClaudio Imbrenda } 394fa2b92fSClaudio Imbrenda 404fa2b92fSClaudio Imbrenda /* 414fa2b92fSClaudio Imbrenda * Add the given element after the given list head. 424fa2b92fSClaudio Imbrenda */ list_add(struct linked_list * head,struct linked_list * li)434fa2b92fSClaudio Imbrendastatic inline void list_add(struct linked_list *head, struct linked_list *li) 444fa2b92fSClaudio Imbrenda { 454fa2b92fSClaudio Imbrenda assert(li); 464fa2b92fSClaudio Imbrenda assert(head); 474fa2b92fSClaudio Imbrenda li->prev = head; 484fa2b92fSClaudio Imbrenda li->next = head->next; 494fa2b92fSClaudio Imbrenda head->next->prev = li; 504fa2b92fSClaudio Imbrenda head->next = li; 514fa2b92fSClaudio Imbrenda } 524fa2b92fSClaudio Imbrenda 53a7eb7780SClaudio Imbrenda /* 54a7eb7780SClaudio Imbrenda * Add the given element before the given list head. 55a7eb7780SClaudio Imbrenda */ list_add_tail(struct linked_list * head,struct linked_list * li)56a7eb7780SClaudio Imbrendastatic inline void list_add_tail(struct linked_list *head, struct linked_list *li) 57a7eb7780SClaudio Imbrenda { 58a7eb7780SClaudio Imbrenda assert(head); 59a7eb7780SClaudio Imbrenda list_add(head->prev, li); 60a7eb7780SClaudio Imbrenda } 61a7eb7780SClaudio Imbrenda 624fa2b92fSClaudio Imbrenda #endif 63