xref: /aosp_15_r20/external/wmediumd/wmediumd/inc/usfstl/list.h (revision 621120a22a0cd8ba80b131fe8bcb37c86ff453e3)
1 /*
2  * Copyright (C) 2019 - 2020 Intel Corporation
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 #ifndef _USFSTL_LIST_H_
7 #define _USFSTL_LIST_H_
8 #include <stddef.h>
9 #include <stdbool.h>
10 
11 #ifndef offsetof
12 #define offsetof __builtin_offsetof
13 #endif
14 
15 #ifndef container_of
16 #define container_of(ptr, type, member) ((type *)(void *)((char *)ptr - offsetof(type, member)))
17 #endif
18 
19 struct usfstl_list_entry {
20 	struct usfstl_list_entry *next, *prev;
21 };
22 
23 struct usfstl_list {
24 	struct usfstl_list_entry list;
25 };
26 
27 #define USFSTL_LIST_INIT(name) {	\
28 	.list.next = &(name).list,	\
29 	.list.prev = &(name).list,	\
30 }
31 #define USFSTL_LIST(name) struct usfstl_list name = USFSTL_LIST_INIT(name)
32 
usfstl_list_init(struct usfstl_list * list)33 static inline void usfstl_list_init(struct usfstl_list *list)
34 {
35 	list->list.next = &list->list;
36 	list->list.prev = &list->list;
37 }
38 
usfstl_list_insert_before(struct usfstl_list_entry * existing,struct usfstl_list_entry * new_entry)39 static inline void usfstl_list_insert_before(struct usfstl_list_entry *existing,
40 					     struct usfstl_list_entry *new_entry)
41 {
42 	new_entry->prev = existing->prev;
43 	existing->prev->next = new_entry;
44 	existing->prev = new_entry;
45 	new_entry->next = existing;
46 }
47 
usfstl_list_append(struct usfstl_list * list,struct usfstl_list_entry * new_entry)48 static inline void usfstl_list_append(struct usfstl_list *list,
49 				      struct usfstl_list_entry *new_entry)
50 {
51 	usfstl_list_insert_before(&list->list, new_entry);
52 }
53 
54 #define usfstl_list_item(element, type, member) \
55 	((type *)container_of(element, type, member))
56 
57 #define usfstl_next_item(_list, entry, type, member) \
58 	((entry)->member.next != &(_list)->list ? \
59 		usfstl_list_item((entry)->member.next, type, member) :\
60 		NULL)
61 
62 #define usfstl_for_each_list_item(item, _list, member) \
63 	for (item = usfstl_list_first_item(_list, typeof(*item), member); \
64 	     item; \
65 	     item = usfstl_next_item(_list, item, typeof(*item), member))
66 
67 #define usfstl_for_each_list_item_safe(item, next, _list, member) \
68 	for (item = usfstl_list_first_item(_list, typeof(*item), member), \
69 	     next = item ? usfstl_next_item(_list, item, typeof(*next), member) : NULL; \
70 	     item; \
71 	     item = next, \
72 	     next = item ? usfstl_next_item(_list, next, typeof(*next), member) : NULL)
73 
74 #define usfstl_for_each_list_item_continue_safe(item, next, _list, member) \
75 	for (item = item ? usfstl_next_item(_list, item, typeof(*item), member) : \
76 			   usfstl_list_first_item(_list, typeof(*item), member), \
77 	     next = item ? usfstl_next_item(_list, item, typeof(*item), member) : NULL; \
78 	     item; \
79 	     item = next, next = item ? usfstl_next_item(_list, next, typeof(*item), member) : NULL)
80 
usfstl_list_empty(const struct usfstl_list * list)81 static inline bool usfstl_list_empty(const struct usfstl_list *list)
82 {
83 	return list->list.next == &list->list;
84 }
85 
86 #define usfstl_list_first_item(_list, type, member) \
87 	(usfstl_list_empty(_list) ? NULL : usfstl_list_item((_list)->list.next, type, member))
88 
usfstl_list_item_remove(struct usfstl_list_entry * entry)89 static inline void usfstl_list_item_remove(struct usfstl_list_entry *entry)
90 {
91 	entry->next->prev = entry->prev;
92 	entry->prev->next = entry->next;
93 	entry->next = NULL;
94 	entry->prev = NULL;
95 }
96 
97 #endif // _USFSTL_LIST_H_
98