Zephyr API Documentation 4.4.99
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
list_gen.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2016 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
11
12#ifndef ZEPHYR_INCLUDE_SYS_LIST_GEN_H_
13#define ZEPHYR_INCLUDE_SYS_LIST_GEN_H_
14
15#include <stddef.h>
16#include <stdbool.h>
17#include <zephyr/sys/util.h>
18
19#define Z_GENLIST_FOR_EACH_NODE(__lname, __l, __sn) \
20 for ((__sn) = sys_ ## __lname ## _peek_head(__l); (__sn) != NULL; \
21 (__sn) = sys_ ## __lname ## _peek_next(__sn))
22
23
24#define Z_GENLIST_ITERATE_FROM_NODE(__lname, __l, __sn) \
25 for ((__sn) = (__sn) ? sys_ ## __lname ## _peek_next_no_check(__sn) \
26 : sys_ ## __lname ## _peek_head(__l); \
27 (__sn) != NULL; \
28 (__sn) = sys_ ## __lname ## _peek_next(__sn))
29
30#define Z_GENLIST_FOR_EACH_NODE_SAFE(__lname, __l, __sn, __sns) \
31 for ((__sn) = sys_ ## __lname ## _peek_head(__l), \
32 (__sns) = sys_ ## __lname ## _peek_next(__sn); \
33 (__sn) != NULL ; (__sn) = (__sns), \
34 (__sns) = sys_ ## __lname ## _peek_next(__sn))
35
36#define Z_GENLIST_CONTAINER(__ln, __cn, __n) \
37 ((__ln) ? CONTAINER_OF((__ln), __typeof__(*(__cn)), __n) : NULL)
38
39#define Z_GENLIST_PEEK_HEAD_CONTAINER(__lname, __l, __cn, __n) \
40 Z_GENLIST_CONTAINER(sys_ ## __lname ## _peek_head(__l), __cn, __n)
41
42#define Z_GENLIST_PEEK_TAIL_CONTAINER(__lname, __l, __cn, __n) \
43 Z_GENLIST_CONTAINER(sys_ ## __lname ## _peek_tail(__l), __cn, __n)
44
45#define Z_GENLIST_PEEK_NEXT_CONTAINER(__lname, __cn, __n) \
46 ((__cn) ? Z_GENLIST_CONTAINER( \
47 sys_ ## __lname ## _peek_next(&((__cn)->__n)), \
48 __cn, __n) : NULL)
49
50#define Z_GENLIST_FOR_EACH_CONTAINER(__lname, __l, __cn, __n) \
51 for ((__cn) = Z_GENLIST_PEEK_HEAD_CONTAINER(__lname, __l, __cn, \
52 __n); \
53 (__cn) != NULL; \
54 (__cn) = Z_GENLIST_PEEK_NEXT_CONTAINER(__lname, __cn, __n))
55
56#define Z_GENLIST_FOR_EACH_CONTAINER_SAFE(__lname, __l, __cn, __cns, __n) \
57 for ((__cn) = Z_GENLIST_PEEK_HEAD_CONTAINER(__lname, __l, __cn, __n), \
58 (__cns) = Z_GENLIST_PEEK_NEXT_CONTAINER(__lname, __cn, __n); \
59 (__cn) != NULL; (__cn) = (__cns), \
60 (__cns) = Z_GENLIST_PEEK_NEXT_CONTAINER(__lname, __cn, __n))
61
62#define Z_GENLIST_IS_EMPTY(__lname) \
63 static inline bool \
64 sys_ ## __lname ## _is_empty(const sys_ ## __lname ## _t *list) \
65 { \
66 return (sys_ ## __lname ## _peek_head(list) == NULL); \
67 }
68
69#define Z_GENLIST_PEEK_NEXT_NO_CHECK(__lname, __nname) \
70 static inline sys_ ## __nname ## _t * \
71 sys_ ## __lname ## _peek_next_no_check(const sys_ ## __nname ## _t *node) \
72 { \
73 return z_ ## __nname ## _next_peek(node); \
74 }
75
76#define Z_GENLIST_PEEK_NEXT(__lname, __nname) \
77 static inline sys_ ## __nname ## _t * \
78 sys_ ## __lname ## _peek_next(const sys_ ## __nname ## _t *node) \
79 { \
80 return (node != NULL) ? \
81 sys_ ## __lname ## _peek_next_no_check(node) : \
82 NULL; \
83 }
84
85#define Z_GENLIST_PREPEND(__lname, __nname) \
86 static inline void \
87 sys_ ## __lname ## _prepend(sys_ ## __lname ## _t *list, \
88 sys_ ## __nname ## _t *node) \
89 { \
90 z_ ## __nname ## _next_set(node, \
91 sys_ ## __lname ## _peek_head(list)); \
92 z_ ## __lname ## _head_set(list, node); \
93 \
94 if (sys_ ## __lname ## _peek_tail(list) == NULL) { \
95 z_ ## __lname ## _tail_set(list, \
96 sys_ ## __lname ## _peek_head(list)); \
97 } \
98 }
99
100#define Z_GENLIST_APPEND(__lname, __nname) \
101 static inline void \
102 sys_ ## __lname ## _append(sys_ ## __lname ## _t *list, \
103 sys_ ## __nname ## _t *node) \
104 { \
105 z_ ## __nname ## _next_set(node, NULL); \
106 \
107 if (sys_ ## __lname ## _peek_tail(list) == NULL) { \
108 z_ ## __lname ## _tail_set(list, node); \
109 z_ ## __lname ## _head_set(list, node); \
110 } else { \
111 z_ ## __nname ## _next_set( \
112 sys_ ## __lname ## _peek_tail(list), \
113 node); \
114 z_ ## __lname ## _tail_set(list, node); \
115 } \
116 }
117
118#define Z_GENLIST_APPEND_LIST(__lname, __nname) \
119 static inline void \
120 sys_ ## __lname ## _append_list(sys_ ## __lname ## _t *list, \
121 void *head, void *tail) \
122{ \
123 if (head != NULL && tail != NULL) { \
124 if (sys_ ## __lname ## _peek_tail(list) == NULL) { \
125 z_ ## __lname ## _head_set(list, \
126 (sys_ ## __nname ## _t *)head); \
127 } else { \
128 z_ ## __nname ## _next_set( \
129 sys_ ## __lname ## _peek_tail(list), \
130 (sys_ ## __nname ## _t *)head); \
131 } \
132 z_ ## __lname ## _tail_set(list, \
133 (sys_ ## __nname ## _t *)tail); \
134 } \
135}
136
137#define Z_GENLIST_MERGE_LIST(__lname, __nname) \
138 static inline void \
139 sys_ ## __lname ## _merge_ ## __lname ( \
140 sys_ ## __lname ## _t *list, \
141 sys_ ## __lname ## _t *list_to_append) \
142 { \
143 sys_ ## __nname ## _t *head, *tail; \
144 head = sys_ ## __lname ## _peek_head(list_to_append); \
145 tail = sys_ ## __lname ## _peek_tail(list_to_append); \
146 sys_ ## __lname ## _append_list(list, head, tail); \
147 sys_ ## __lname ## _init(list_to_append); \
148 }
149
150#define Z_GENLIST_INSERT(__lname, __nname) \
151 static inline void \
152 sys_ ## __lname ## _insert(sys_ ## __lname ## _t *list, \
153 sys_ ## __nname ## _t *prev, \
154 sys_ ## __nname ## _t *node) \
155 { \
156 if (prev == NULL) { \
157 sys_ ## __lname ## _prepend(list, node); \
158 } else if (z_ ## __nname ## _next_peek(prev) == NULL) { \
159 sys_ ## __lname ## _append(list, node); \
160 } else { \
161 z_ ## __nname ## _next_set(node, \
162 z_ ## __nname ## _next_peek(prev)); \
163 z_ ## __nname ## _next_set(prev, node); \
164 } \
165 }
166
167#define Z_GENLIST_GET_NOT_EMPTY(__lname, __nname) \
168 static inline sys_ ## __nname ## _t * \
169 sys_ ## __lname ## _get_not_empty(sys_ ## __lname ## _t *list) \
170 { \
171 sys_ ## __nname ## _t *node = \
172 sys_ ## __lname ## _peek_head(list); \
173 \
174 z_ ## __lname ## _head_set(list, \
175 z_ ## __nname ## _next_peek(node)); \
176 if (sys_ ## __lname ## _peek_tail(list) == node) { \
177 z_ ## __lname ## _tail_set(list, \
178 sys_ ## __lname ## _peek_head(list)); \
179 } \
180 \
181 return node; \
182 }
183
184#define Z_GENLIST_GET(__lname, __nname) \
185 static inline sys_ ## __nname ## _t * \
186 sys_ ## __lname ## _get(sys_ ## __lname ## _t *list) \
187 { \
188 return sys_ ## __lname ## _is_empty(list) ? NULL : \
189 sys_ ## __lname ## _get_not_empty(list); \
190 }
191
192#define Z_GENLIST_REMOVE(__lname, __nname) \
193 static inline void \
194 sys_ ## __lname ## _remove(sys_ ## __lname ## _t *list, \
195 sys_ ## __nname ## _t *prev_node, \
196 sys_ ## __nname ## _t *node) \
197 { \
198 if (prev_node == NULL) { \
199 z_ ## __lname ## _head_set(list, \
200 z_ ## __nname ## _next_peek(node)); \
201 \
202 /* Was node also the tail? */ \
203 if (sys_ ## __lname ## _peek_tail(list) == node) { \
204 z_ ## __lname ## _tail_set(list, \
205 sys_ ## __lname ## _peek_head(list)); \
206 } \
207 } else { \
208 z_ ## __nname ## _next_set(prev_node, \
209 z_ ## __nname ## _next_peek(node)); \
210 \
211 /* Was node the tail? */ \
212 if (sys_ ## __lname ## _peek_tail(list) == node) { \
213 z_ ## __lname ## _tail_set(list, \
214 prev_node); \
215 } \
216 } \
217 \
218 z_ ## __nname ## _next_set(node, NULL); \
219 }
220
221#define Z_GENLIST_FIND_AND_REMOVE(__lname, __nname) \
222 static inline bool \
223 sys_ ## __lname ## _find_and_remove(sys_ ## __lname ## _t *list, \
224 sys_ ## __nname ## _t *node) \
225 { \
226 sys_ ## __nname ## _t *prev = NULL; \
227 sys_ ## __nname ## _t *test; \
228 \
229 Z_GENLIST_FOR_EACH_NODE(__lname, list, test) { \
230 if (test == node) { \
231 sys_ ## __lname ## _remove(list, prev, \
232 node); \
233 return true; \
234 } \
235 \
236 prev = test; \
237 } \
238 \
239 return false; \
240 }
241
242#define Z_GENLIST_FIND(__lname, __nname) \
243 static inline bool sys_##__lname##_find( \
244 const sys_##__lname##_t *list, const sys_##__nname##_t *node, \
245 sys_##__nname##_t **prev) \
246 { \
247 sys_##__nname##_t *current = NULL; \
248 sys_##__nname##_t *previous = NULL; \
249 \
250 Z_GENLIST_FOR_EACH_NODE(__lname, list, current) { \
251 if (current == node) { \
252 if (prev != NULL) { \
253 *prev = previous; \
254 } \
255 return true; \
256 } \
257 \
258 previous = current; \
259 } \
260 \
261 if (prev != NULL) { \
262 *prev = previous; \
263 } \
264 \
265 return false; \
266 }
267
268#define Z_GENLIST_LEN(__lname, __nname) \
269 static inline size_t sys_##__lname##_len(const sys_##__lname##_t *list) \
270 { \
271 size_t len = 0; \
272 sys_##__nname##_t *node; \
273 Z_GENLIST_FOR_EACH_NODE(__lname, list, node) { \
274 len++; \
275 } \
276 return len; \
277 }
278
279#endif /* ZEPHYR_INCLUDE_SYS_LIST_GEN_H_ */
Misc utilities.