21 #ifndef SRC_VPPINFRA_CLIB_LLIST_H_ 22 #define SRC_VPPINFRA_CLIB_LLIST_H_ 35 #define CLIB_LLIST_INVALID_INDEX ((u32)~0) 40 #define _ll_var(v) _llist_##v 44 #define _lnext(E,name) ((E)->name).next 45 #define _lprev(E,name) ((E)->name).prev 53 #define clib_llist_entry_index(LP,E) ((E) - (LP)) 61 #define clib_llist_prev_index(E,name) _lprev(E,name) 69 #define clib_llist_next_index(E,name) _lnext(E,name) 78 #define clib_llist_next(LP,name,E) pool_elt_at_index((LP),_lnext((E),name)) 87 #define clib_llist_prev(LP,name,E) pool_elt_at_index((LP),_lprev((E),name)) 95 #define clib_llist_anchor_init(LP,name,E) \ 97 _lprev ((E),name) = clib_llist_entry_index ((LP), (E)); \ 98 _lnext ((E),name) = _lprev ((E),name); \ 106 #define clib_llist_make_head(LP,name) \ 108 typeof (LP) _ll_var (head); \ 109 pool_get_zero ((LP), _ll_var (head)); \ 110 clib_llist_anchor_init ((LP),name,_ll_var (head)); \ 111 clib_llist_entry_index ((LP), _ll_var (head)); \ 121 #define clib_llist_is_empty(LP,name,H) \ 122 (clib_llist_entry_index (LP,H) == (H)->name.next) 129 #define clib_llist_elt_is_linked(E,name) \ 130 ((E)->name.next != CLIB_LLIST_INVALID_INDEX \ 131 && (E)->name.prev != CLIB_LLIST_INVALID_INDEX) 143 #define _llist_insert(LP,name,E,P,N) \ 145 _lprev (E,name) = _lprev(N,name); \ 146 _lnext (E,name) = _lnext(P,name); \ 147 _lprev ((N),name) = clib_llist_entry_index ((LP),(E)); \ 148 _lnext ((P),name) = clib_llist_entry_index ((LP),(E)); \ 158 #define clib_llist_insert(LP,name,E,P) \ 160 typeof (LP) _ll_var (N) = clib_llist_next (LP,name,P); \ 161 _llist_insert ((LP),name,(E),(P), _ll_var (N)); \ 172 #define clib_llist_add(LP,name,E,H) clib_llist_insert ((LP),name,(E),(H)) 181 #define clib_llist_add_tail(LP,name,E,H) \ 183 typeof (LP) _ll_var (P) = clib_llist_prev ((LP),name,(H)); \ 184 _llist_insert ((LP),name,(E),_ll_var (P),(H)); \ 193 #define clib_llist_remove(LP,name,E) \ 195 ASSERT ((E) != clib_llist_next (LP,name,E));\ 196 ASSERT (_lnext (E,name) != CLIB_LLIST_INVALID_INDEX); \ 197 ASSERT (_lprev (E,name) != CLIB_LLIST_INVALID_INDEX); \ 198 typeof (LP) _ll_var (P) = clib_llist_prev ((LP),name,E); \ 199 typeof (LP) _ll_var (N) = clib_llist_next ((LP),name,E); \ 200 _lnext (_ll_var (P),name) = _lnext (E,name); \ 201 _lprev (_ll_var (N),name) = _lprev (E,name); \ 202 _lnext (E,name) = _lprev (E,name) = CLIB_LLIST_INVALID_INDEX; \ 215 #define clib_llist_pop_first(LP,name,E,H) \ 217 E = clib_llist_next (LP,name,H); \ 218 clib_llist_remove (LP,name,E); \ 231 #define clib_llist_splice(LP,name,P,H) \ 233 typeof (LP) _ll_var (fe) = clib_llist_next (LP,name,H); \ 234 if (_ll_var (fe) != (H)) \ 236 typeof (LP) _ll_var (le) = clib_llist_prev (LP,name,H); \ 237 typeof (LP) _ll_var (ne) = clib_llist_next (LP,name,P); \ 238 _lprev (_ll_var (fe),name) = clib_llist_entry_index(LP,P); \ 239 _lnext (_ll_var (le),name) = clib_llist_entry_index(LP,_ll_var (ne));\ 240 _lnext (P,name) = clib_llist_entry_index (LP,_ll_var (fe)); \ 241 _lprev (_ll_var (ne),name) = clib_llist_entry_index(LP,_ll_var (le));\ 242 _lnext (H,name) = clib_llist_entry_index(LP,H); \ 243 _lprev (H,name) = _lnext (H,name); \ 255 #define clib_llist_foreach(LP,name,H,E,body) \ 257 typeof (LP) _ll_var (n); \ 258 (E) = clib_llist_next (LP,name,H); \ 261 _ll_var (n) = clib_llist_next (LP,name,E); \ 262 do { body; } while (0); \ 275 #define clib_llist_foreach_safe(LP,name,H,E,body) \ 277 clib_llist_index_t _ll_var (HI) = clib_llist_entry_index (LP, H); \ 278 clib_llist_index_t _ll_var (EI), _ll_var (NI); \ 279 _ll_var (EI) = _lnext ((H),name); \ 280 while (_ll_var (EI) != _ll_var (HI)) \ 282 (E) = pool_elt_at_index (LP, _ll_var (EI)); \ 283 _ll_var (NI) = _lnext ((E),name); \ 284 do { body; } while (0); \ 285 _ll_var (EI) = _ll_var (NI); \ 297 #define clib_llist_foreach_reverse(LP,name,H,E,body) \ 299 typeof (LP) _ll_var (p); \ 300 (E) = clib_llist_prev (LP,name,H); \ 303 _ll_var (p) = clib_llist_prev (LP,name,E); \ 304 do { body; } while (0); \
Fixed length block allocator.
struct clib_llist_anchor clib_llist_anchor_t