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_ */ 236