xref: /kvm-unit-tests/lib/list.h (revision 9f0ae3012430ed7072d04247fb674125c616a6b4)
1 #ifndef _LIST_H_
2 #define _LIST_H_
3 
4 #include <stdbool.h>
5 
6 /*
7  * Circular doubly-linked list. The pointer to the list is a list item itself,
8  * like in the kernel implementation.
9  */
10 struct linked_list {
11 	struct linked_list *prev;
12 	struct linked_list *next;
13 };
14 
15 /*
16  * An empty list is a list item whose prev and next both point to itself.
17  * Returns true if the list is empty.
18  */
is_list_empty(struct linked_list * p)19 static inline bool is_list_empty(struct linked_list *p)
20 {
21 	return !p->next || !p->prev || p == p->next || p == p->prev;
22 }
23 
24 /*
25  * Remove the given element from the list, if the list is not already empty.
26  * The removed element is returned.
27  */
list_remove(struct linked_list * l)28 static inline struct linked_list *list_remove(struct linked_list *l)
29 {
30 	if (is_list_empty(l))
31 		return NULL;
32 
33 	l->prev->next = l->next;
34 	l->next->prev = l->prev;
35 	l->prev = l->next = NULL;
36 
37 	return l;
38 }
39 
40 /*
41  * Add the given element after the given list head.
42  */
list_add(struct linked_list * head,struct linked_list * li)43 static inline void list_add(struct linked_list *head, struct linked_list *li)
44 {
45 	assert(li);
46 	assert(head);
47 	li->prev = head;
48 	li->next = head->next;
49 	head->next->prev = li;
50 	head->next = li;
51 }
52 
53 /*
54  * Add the given element before the given list head.
55  */
list_add_tail(struct linked_list * head,struct linked_list * li)56 static inline void list_add_tail(struct linked_list *head, struct linked_list *li)
57 {
58 	assert(head);
59 	list_add(head->prev, li);
60 }
61 
62 #endif
63