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 <zephyr/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 (head != NULL && tail != NULL) { \ 119 if (sys_ ## __lname ## _peek_tail(list) == NULL) { \ 120 z_ ## __lname ## _head_set(list, \ 121 (sys_ ## __nname ## _t *)head); \ 122 } else { \ 123 z_ ## __nname ## _next_set( \ 124 sys_ ## __lname ## _peek_tail(list), \ 125 (sys_ ## __nname ## _t *)head); \ 126 } \ 127 z_ ## __lname ## _tail_set(list, \ 128 (sys_ ## __nname ## _t *)tail); \ 129 } \ 130 } 131 132 #define Z_GENLIST_MERGE_LIST(__lname, __nname) \ 133 static inline void \ 134 sys_ ## __lname ## _merge_ ## __lname ( \ 135 sys_ ## __lname ## _t *list, \ 136 sys_ ## __lname ## _t *list_to_append) \ 137 { \ 138 sys_ ## __nname ## _t *head, *tail; \ 139 head = sys_ ## __lname ## _peek_head(list_to_append); \ 140 tail = sys_ ## __lname ## _peek_tail(list_to_append); \ 141 sys_ ## __lname ## _append_list(list, head, tail); \ 142 sys_ ## __lname ## _init(list_to_append); \ 143 } 144 145 #define Z_GENLIST_INSERT(__lname, __nname) \ 146 static inline void \ 147 sys_ ## __lname ## _insert(sys_ ## __lname ## _t *list, \ 148 sys_ ## __nname ## _t *prev, \ 149 sys_ ## __nname ## _t *node) \ 150 { \ 151 if (prev == NULL) { \ 152 sys_ ## __lname ## _prepend(list, node); \ 153 } else if (z_ ## __nname ## _next_peek(prev) == NULL) { \ 154 sys_ ## __lname ## _append(list, node); \ 155 } else { \ 156 z_ ## __nname ## _next_set(node, \ 157 z_ ## __nname ## _next_peek(prev)); \ 158 z_ ## __nname ## _next_set(prev, node); \ 159 } \ 160 } 161 162 #define Z_GENLIST_GET_NOT_EMPTY(__lname, __nname) \ 163 static inline sys_ ## __nname ## _t * \ 164 sys_ ## __lname ## _get_not_empty(sys_ ## __lname ## _t *list) \ 165 { \ 166 sys_ ## __nname ## _t *node = \ 167 sys_ ## __lname ## _peek_head(list); \ 168 \ 169 z_ ## __lname ## _head_set(list, \ 170 z_ ## __nname ## _next_peek(node)); \ 171 if (sys_ ## __lname ## _peek_tail(list) == node) { \ 172 z_ ## __lname ## _tail_set(list, \ 173 sys_ ## __lname ## _peek_head(list)); \ 174 } \ 175 \ 176 return node; \ 177 } 178 179 #define Z_GENLIST_GET(__lname, __nname) \ 180 static inline sys_ ## __nname ## _t * \ 181 sys_ ## __lname ## _get(sys_ ## __lname ## _t *list) \ 182 { \ 183 return sys_ ## __lname ## _is_empty(list) ? NULL : \ 184 sys_ ## __lname ## _get_not_empty(list); \ 185 } 186 187 #define Z_GENLIST_REMOVE(__lname, __nname) \ 188 static inline void \ 189 sys_ ## __lname ## _remove(sys_ ## __lname ## _t *list, \ 190 sys_ ## __nname ## _t *prev_node, \ 191 sys_ ## __nname ## _t *node) \ 192 { \ 193 if (prev_node == NULL) { \ 194 z_ ## __lname ## _head_set(list, \ 195 z_ ## __nname ## _next_peek(node)); \ 196 \ 197 /* Was node also the tail? */ \ 198 if (sys_ ## __lname ## _peek_tail(list) == node) { \ 199 z_ ## __lname ## _tail_set(list, \ 200 sys_ ## __lname ## _peek_head(list)); \ 201 } \ 202 } else { \ 203 z_ ## __nname ## _next_set(prev_node, \ 204 z_ ## __nname ## _next_peek(node)); \ 205 \ 206 /* Was node the tail? */ \ 207 if (sys_ ## __lname ## _peek_tail(list) == node) { \ 208 z_ ## __lname ## _tail_set(list, \ 209 prev_node); \ 210 } \ 211 } \ 212 \ 213 z_ ## __nname ## _next_set(node, NULL); \ 214 } 215 216 #define Z_GENLIST_FIND_AND_REMOVE(__lname, __nname) \ 217 static inline bool \ 218 sys_ ## __lname ## _find_and_remove(sys_ ## __lname ## _t *list, \ 219 sys_ ## __nname ## _t *node) \ 220 { \ 221 sys_ ## __nname ## _t *prev = NULL; \ 222 sys_ ## __nname ## _t *test; \ 223 \ 224 Z_GENLIST_FOR_EACH_NODE(__lname, list, test) { \ 225 if (test == node) { \ 226 sys_ ## __lname ## _remove(list, prev, \ 227 node); \ 228 return true; \ 229 } \ 230 \ 231 prev = test; \ 232 } \ 233 \ 234 return false; \ 235 } 236 237 #endif /* ZEPHYR_INCLUDE_SYS_LIST_GEN_H_ */ 238