Zephyr API Documentation  2.7.0-rc2
A Scalable Open Source RTOS
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
7#ifndef ZEPHYR_INCLUDE_SYS_LIST_GEN_H_
8#define ZEPHYR_INCLUDE_SYS_LIST_GEN_H_
9
10#include <stddef.h>
11#include <stdbool.h>
12#include <sys/util.h>
13
14#define Z_GENLIST_FOR_EACH_NODE(__lname, __l, __sn) \
15 for (__sn = sys_ ## __lname ## _peek_head(__l); __sn != NULL; \
16 __sn = sys_ ## __lname ## _peek_next(__sn))
17
18
19#define Z_GENLIST_ITERATE_FROM_NODE(__lname, __l, __sn) \
20 for (__sn = __sn ? sys_ ## __lname ## _peek_next_no_check(__sn) \
21 : sys_ ## __lname ## _peek_head(__l); \
22 __sn != NULL; \
23 __sn = sys_ ## __lname ## _peek_next(__sn))
24
25#define Z_GENLIST_FOR_EACH_NODE_SAFE(__lname, __l, __sn, __sns) \
26 for (__sn = sys_ ## __lname ## _peek_head(__l), \
27 __sns = sys_ ## __lname ## _peek_next(__sn); \
28 __sn != NULL ; __sn = __sns, \
29 __sns = sys_ ## __lname ## _peek_next(__sn))
30
31#define Z_GENLIST_CONTAINER(__ln, __cn, __n) \
32 ((__ln) ? CONTAINER_OF((__ln), __typeof__(*(__cn)), __n) : NULL)
33
34#define Z_GENLIST_PEEK_HEAD_CONTAINER(__lname, __l, __cn, __n) \
35 Z_GENLIST_CONTAINER(sys_ ## __lname ## _peek_head(__l), __cn, __n)
36
37#define Z_GENLIST_PEEK_TAIL_CONTAINER(__lname, __l, __cn, __n) \
38 Z_GENLIST_CONTAINER(sys_ ## __lname ## _peek_tail(__l), __cn, __n)
39
40#define Z_GENLIST_PEEK_NEXT_CONTAINER(__lname, __cn, __n) \
41 ((__cn) ? Z_GENLIST_CONTAINER( \
42 sys_ ## __lname ## _peek_next(&((__cn)->__n)), \
43 __cn, __n) : NULL)
44
45#define Z_GENLIST_FOR_EACH_CONTAINER(__lname, __l, __cn, __n) \
46 for (__cn = Z_GENLIST_PEEK_HEAD_CONTAINER(__lname, __l, __cn, \
47 __n); \
48 __cn != NULL; \
49 __cn = Z_GENLIST_PEEK_NEXT_CONTAINER(__lname, __cn, __n))
50
51#define Z_GENLIST_FOR_EACH_CONTAINER_SAFE(__lname, __l, __cn, __cns, __n) \
52 for (__cn = Z_GENLIST_PEEK_HEAD_CONTAINER(__lname, __l, __cn, __n), \
53 __cns = Z_GENLIST_PEEK_NEXT_CONTAINER(__lname, __cn, __n); \
54 __cn != NULL; __cn = __cns, \
55 __cns = Z_GENLIST_PEEK_NEXT_CONTAINER(__lname, __cn, __n))
56
57#define Z_GENLIST_IS_EMPTY(__lname) \
58 static inline bool \
59 sys_ ## __lname ## _is_empty(sys_ ## __lname ## _t *list) \
60 { \
61 return (sys_ ## __lname ## _peek_head(list) == NULL); \
62 }
63
64#define Z_GENLIST_PEEK_NEXT_NO_CHECK(__lname, __nname) \
65 static inline sys_ ## __nname ## _t * \
66 sys_ ## __lname ## _peek_next_no_check(sys_ ## __nname ## _t *node) \
67 { \
68 return z_ ## __nname ## _next_peek(node); \
69 }
70
71#define Z_GENLIST_PEEK_NEXT(__lname, __nname) \
72 static inline sys_ ## __nname ## _t * \
73 sys_ ## __lname ## _peek_next(sys_ ## __nname ## _t *node) \
74 { \
75 return node != NULL ? \
76 sys_ ## __lname ## _peek_next_no_check(node) : \
77 NULL; \
78 }
79
80#define Z_GENLIST_PREPEND(__lname, __nname) \
81 static inline void \
82 sys_ ## __lname ## _prepend(sys_ ## __lname ## _t *list, \
83 sys_ ## __nname ## _t *node) \
84 { \
85 z_ ## __nname ## _next_set(node, \
86 sys_ ## __lname ## _peek_head(list)); \
87 z_ ## __lname ## _head_set(list, node); \
88 \
89 if (sys_ ## __lname ## _peek_tail(list) == NULL) { \
90 z_ ## __lname ## _tail_set(list, \
91 sys_ ## __lname ## _peek_head(list)); \
92 } \
93 }
94
95#define Z_GENLIST_APPEND(__lname, __nname) \
96 static inline void \
97 sys_ ## __lname ## _append(sys_ ## __lname ## _t *list, \
98 sys_ ## __nname ## _t *node) \
99 { \
100 z_ ## __nname ## _next_set(node, NULL); \
101 \
102 if (sys_ ## __lname ## _peek_tail(list) == NULL) { \
103 z_ ## __lname ## _tail_set(list, node); \
104 z_ ## __lname ## _head_set(list, node); \
105 } else { \
106 z_ ## __nname ## _next_set( \
107 sys_ ## __lname ## _peek_tail(list), \
108 node); \
109 z_ ## __lname ## _tail_set(list, node); \
110 } \
111 }
112
113#define Z_GENLIST_APPEND_LIST(__lname, __nname) \
114 static inline void \
115 sys_ ## __lname ## _append_list(sys_ ## __lname ## _t *list, \
116 void *head, void *tail) \
117{ \
118 if (sys_ ## __lname ## _peek_tail(list) == NULL) { \
119 z_ ## __lname ## _head_set(list, \
120 (sys_ ## __nname ## _t *)head); \
121 } else { \
122 z_ ## __nname ## _next_set( \
123 sys_ ## __lname ## _peek_tail(list), \
124 (sys_ ## __nname ## _t *)head); \
125 } \
126 z_ ## __lname ## _tail_set(list, \
127 (sys_ ## __nname ## _t *)tail); \
128}
129
130#define Z_GENLIST_MERGE_LIST(__lname, __nname) \
131 static inline void \
132 sys_ ## __lname ## _merge_ ## __lname ( \
133 sys_ ## __lname ## _t *list, \
134 sys_ ## __lname ## _t *list_to_append) \
135 { \
136 sys_ ## __nname ## _t *head, *tail; \
137 head = sys_ ## __lname ## _peek_head(list_to_append); \
138 tail = sys_ ## __lname ## _peek_tail(list_to_append); \
139 sys_ ## __lname ## _append_list(list, head, tail); \
140 sys_ ## __lname ## _init(list_to_append); \
141 }
142
143#define Z_GENLIST_INSERT(__lname, __nname) \
144 static inline void \
145 sys_ ## __lname ## _insert(sys_ ## __lname ## _t *list, \
146 sys_ ## __nname ## _t *prev, \
147 sys_ ## __nname ## _t *node) \
148 { \
149 if (prev == NULL) { \
150 sys_ ## __lname ## _prepend(list, node); \
151 } else if (z_ ## __nname ## _next_peek(prev) == NULL) { \
152 sys_ ## __lname ## _append(list, node); \
153 } else { \
154 z_ ## __nname ## _next_set(node, \
155 z_ ## __nname ## _next_peek(prev)); \
156 z_ ## __nname ## _next_set(prev, node); \
157 } \
158 }
159
160#define Z_GENLIST_GET_NOT_EMPTY(__lname, __nname) \
161 static inline sys_ ## __nname ## _t * \
162 sys_ ## __lname ## _get_not_empty(sys_ ## __lname ## _t *list) \
163 { \
164 sys_ ## __nname ## _t *node = \
165 sys_ ## __lname ## _peek_head(list); \
166 \
167 z_ ## __lname ## _head_set(list, \
168 z_ ## __nname ## _next_peek(node)); \
169 if (sys_ ## __lname ## _peek_tail(list) == node) { \
170 z_ ## __lname ## _tail_set(list, \
171 sys_ ## __lname ## _peek_head(list)); \
172 } \
173 \
174 return node; \
175 }
176
177#define Z_GENLIST_GET(__lname, __nname) \
178 static inline sys_ ## __nname ## _t * \
179 sys_ ## __lname ## _get(sys_ ## __lname ## _t *list) \
180 { \
181 return sys_ ## __lname ## _is_empty(list) ? NULL : \
182 sys_ ## __lname ## _get_not_empty(list); \
183 }
184
185#define Z_GENLIST_REMOVE(__lname, __nname) \
186 static inline void \
187 sys_ ## __lname ## _remove(sys_ ## __lname ## _t *list, \
188 sys_ ## __nname ## _t *prev_node, \
189 sys_ ## __nname ## _t *node) \
190 { \
191 if (prev_node == NULL) { \
192 z_ ## __lname ## _head_set(list, \
193 z_ ## __nname ## _next_peek(node)); \
194 \
195 /* Was node also the tail? */ \
196 if (sys_ ## __lname ## _peek_tail(list) == node) { \
197 z_ ## __lname ## _tail_set(list, \
198 sys_ ## __lname ## _peek_head(list)); \
199 } \
200 } else { \
201 z_ ## __nname ## _next_set(prev_node, \
202 z_ ## __nname ## _next_peek(node)); \
203 \
204 /* Was node the tail? */ \
205 if (sys_ ## __lname ## _peek_tail(list) == node) { \
206 z_ ## __lname ## _tail_set(list, \
207 prev_node); \
208 } \
209 } \
210 \
211 z_ ## __nname ## _next_set(node, NULL); \
212 }
213
214#define Z_GENLIST_FIND_AND_REMOVE(__lname, __nname) \
215 static inline bool \
216 sys_ ## __lname ## _find_and_remove(sys_ ## __lname ## _t *list, \
217 sys_ ## __nname ## _t *node) \
218 { \
219 sys_ ## __nname ## _t *prev = NULL; \
220 sys_ ## __nname ## _t *test; \
221 \
222 Z_GENLIST_FOR_EACH_NODE(__lname, list, test) { \
223 if (test == node) { \
224 sys_ ## __lname ## _remove(list, prev, \
225 node); \
226 return true; \
227 } \
228 \
229 prev = test; \
230 } \
231 \
232 return false; \
233 }
234
235#endif /* ZEPHYR_INCLUDE_SYS_LIST_GEN_H_ */
Misc utilities.