1 // Copyright (C) 2022 Beken Corporation
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #pragma once
16
17 #ifdef __cplusplus
18 extern "C" {
19 #endif
20
21 #ifndef offsetof
22 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
23 #endif
24 #ifdef list_entry
25 #undef list_entry
26 #endif
27 #define list_entry(ptr, type, member) ((type *)((char *)ptr - offsetof(type,member)))
28
29 #ifndef __BK_INLINE
30 #define __BK_INLINE static inline
31 #endif
32
33 /*
34 * Simple doubly linked list implementation.
35 *
36 * Some of the internal functions ("__xxx") are useful when
37 * manipulating whole lists rather than single entries, as
38 * sometimes we already know the next/prev entries and we can
39 * generate better code by using them directly rather than
40 * using the generic single-entry routines.
41 */
42 typedef struct list_head
43 {
44 struct list_head *next, *prev;
45 }LIST_HEADER_T;
46
47 #define LIST_HEAD_INIT(name) { &(name), &(name) }
48
49 #define LIST_HEAD_DEFINE(name) \
50 struct list_head name = LIST_HEAD_INIT(name)
51
52 #define INIT_LIST_HEAD(ptr) do { \
53 (ptr)->next = (ptr); (ptr)->prev = (ptr); \
54 } while (0)
55
56 /*
57 * Insert a new_node entry between two known consecutive entries.
58 *
59 * This is only for internal list manipulation where we know
60 * the prev/next entries already!
61 */
__list_add(struct list_head * new_node,struct list_head * prev,struct list_head * next)62 __BK_INLINE void __list_add(struct list_head *new_node, struct list_head *prev, struct list_head *next)
63 {
64 next->prev = new_node;
65 new_node->next = next;
66 new_node->prev = prev;
67 prev->next = new_node;
68 }
69
70 /**
71 * list_add - add a new_node entry
72 * @new_node: new_node entry to be added
73 * @head: list head to add it after
74 *
75 * Insert a new_node entry after the specified head.
76 * This is good for implementing stacks.
77 */
list_add_head(struct list_head * new_node,struct list_head * head)78 __BK_INLINE void list_add_head(struct list_head *new_node, struct list_head *head)
79 {
80 __list_add(new_node, head, head->next);
81 }
82
83 /**
84 * list_add_tail - add a new_node entry
85 * @new_node: new_node entry to be added
86 * @head: list head to add it before
87 *
88 * Insert a new_node entry before the specified head.
89 * This is useful for implementing queues.
90 */
list_add_tail(struct list_head * new_node,struct list_head * head)91 __BK_INLINE void list_add_tail(struct list_head *new_node, struct list_head *head)
92 {
93 __list_add(new_node, head->prev, head);
94 }
95
96 /*
97 * Delete a list entry by making the prev/next entries
98 * point to each other.
99 *
100 * This is only for internal list manipulation where we know
101 * the prev/next entries already!
102 */
__list_del(struct list_head * prev,struct list_head * next)103 __BK_INLINE void __list_del(struct list_head * prev, struct list_head * next)
104 {
105 next->prev = prev;
106 prev->next = next;
107 }
108
109 /**
110 * list_del - deletes entry from list.
111 * @entry: the element to delete from the list.
112 * Note: list_empty on entry does not return true after this, the entry is
113 * in an undefined state.
114 */
list_del(struct list_head * entry)115 __BK_INLINE void list_del(struct list_head *entry)
116 {
117 __list_del(entry->prev, entry->next);
118 }
119
120 /**
121 * list_del_init - deletes entry from list and reinitialize it.
122 * @entry: the element to delete from the list.
123 */
list_del_init(struct list_head * entry)124 __BK_INLINE void list_del_init(struct list_head *entry)
125 {
126 __list_del(entry->prev, entry->next);
127 INIT_LIST_HEAD(entry);
128 }
129
130 /**
131 * list_move - delete from one list and add as another's head
132 * @list: the entry to move
133 * @head: the head that will precede our entry
134 */
list_move(struct list_head * list,struct list_head * head)135 __BK_INLINE void list_move(struct list_head *list, struct list_head *head)
136 {
137 __list_del(list->prev, list->next);
138 list_add_head(list, head);
139 }
140
141 /**
142 * list_move_tail - delete from one list and add as another's tail
143 * @list: the entry to move
144 * @head: the head that will follow our entry
145 */
list_move_tail(struct list_head * list,struct list_head * head)146 __BK_INLINE void list_move_tail(struct list_head *list,
147 struct list_head *head)
148 {
149 __list_del(list->prev, list->next);
150 list_add_tail(list, head);
151 }
152
153 /**
154 * list_empty - tests whether a list is empty
155 * @head: the list to test.
156 */
list_empty(const struct list_head * head)157 __BK_INLINE unsigned int list_empty(const struct list_head *head)
158 {
159 return head->next == head;
160 }
161
__list_splice(struct list_head * list,struct list_head * head)162 __BK_INLINE void __list_splice(struct list_head *list,
163 struct list_head *head)
164 {
165 struct list_head *first = list->next;
166 struct list_head *last = list->prev;
167 struct list_head *at = head->next;
168
169 first->prev = head;
170 head->next = first;
171
172 last->next = at;
173 at->prev = last;
174 }
175
176 /**
177 * list_splice - join two lists
178 * @list: the new_node list to add.
179 * @head: the place to add it in the first list.
180 */
list_splice(struct list_head * list,struct list_head * head)181 __BK_INLINE void list_splice(struct list_head *list, struct list_head *head)
182 {
183 if (!list_empty(list))
184 __list_splice(list, head);
185 }
186
187 /**
188 * list_splice_init - join two lists and reinitialise the emptied list.
189 * @list: the new_node list to add.
190 * @head: the place to add it in the first list.
191 *
192 * The list at @list is reinitialised
193 */
list_splice_init(struct list_head * list,struct list_head * head)194 __BK_INLINE void list_splice_init(struct list_head *list,
195 struct list_head *head)
196 {
197 if (!list_empty(list)) {
198 __list_splice(list, head);
199 INIT_LIST_HEAD(list);
200 }
201 }
202
list_switch(struct list_head ** list1,struct list_head ** list2)203 __BK_INLINE void list_switch(struct list_head **list1,
204 struct list_head ** list2)
205 {
206 struct list_head * temp;
207
208 temp = *list1;
209 *list1 = *list2;
210 *list2 = temp;
211 }
212
213
214
215 /**
216 * list_for_each - iterate over a list
217 * @pos: the &struct list_head to use as a loop counter.
218 * @head: the head for your list.
219 */
220 #define list_for_each(pos, head) \
221 for (pos = (head)->next; pos != (head); pos = pos->next)
222
223
224 /**
225 * list_for_each_safe - iterate over a list safe against removal of list entry
226 * @pos: the &struct list_head to use as a loop counter.
227 * @n: another &struct list_head to use as temporary storage
228 * @head: the head for your list.
229 */
230 #define list_for_each_safe(pos, n, head) \
231 for (pos = (head)->next, n = pos->next; pos != (head); \
232 pos = n, n = pos->next)
233
234 #define prefetch(x) __builtin_prefetch(x)
235
236 /**
237 * list_for_each_entry - iterate over list of given type
238 * @pos: the type * to use as a loop counter.
239 * @head: the head for your list.
240 * @member: the name of the list_struct within the struct.
241 */
242 #define list_for_each_entry(pos, head, member) \
243 for (pos = list_entry((head)->next, __typeof__(*pos), member); \
244 prefetch(pos->member.next), &pos->member != (head); \
245 pos = list_entry(pos->member.next, __typeof__(*pos), member))
246
247 /**
248 * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
249 * @pos: the type * to use as a loop counter.
250 * @n: another type * to use as temporary storage
251 * @head: the head for your list.
252 * @member: the name of the list_struct within the struct.
253 */
254 #define list_for_each_entry_safe(pos, n, head, member) \
255 for (pos = list_entry((head)->next, __typeof__(*pos), member), \
256 n = list_entry(pos->member.next, __typeof__(*pos), member); \
257 &pos->member != (head); \
258 pos = n, n = list_entry(n->member.next, __typeof__(*n), member))
259
260 /**
261 * list_size
262 * @head: the head for your list.
263 */
list_size(struct list_head * list)264 __BK_INLINE unsigned int list_size(struct list_head *list) {
265 unsigned int num_of_list=0;
266 struct list_head *n, *pos;
267
268 list_for_each_safe(pos, n, list)
269 num_of_list++;
270
271 return num_of_list;
272 }
273
274 #ifdef __cplusplus
275 }
276 #endif
277