• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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