#ifndef LIST_H #define LIST_H #include "fw.h" typedef uint32_t key_t; /* --- Doubly linked list (head node assumed) --- */ struct dll { struct dll *prev, *next; }; static inline void dll_init(struct dll *head) { head->prev = head->next = head; } static inline struct dll *dll_find_offs(struct dll *head, key_t key, ptrdiff_t key_offset) { for (const struct dll *nh = head->next; nh != head; nh = nh->next) { const key_t *node_key = (const key_t *)((const char *)nh + key_offset); if (*node_key == key) return (struct dll *)nh; } return NULL; } #define dll_find(head,what,struc,list,key) \ ({ \ struct dll *node = dll_find_offs(head, what, offset_diff(struc,key,list)); \ (struc *)(node ? container_of(node, struc, list) : NULL); \ }) /* Remove from linked list */ static inline void dll_remove(struct dll *node) { node->prev->next = node->next; node->next->prev = node->prev; } /* Add to linked list */ static inline void dll_insert_head(struct dll *head, struct dll *node) { node->prev = head; node->next = head->next; head->next = node; node->next->prev = node; } static inline void dll_insert_tail(struct dll *head, struct dll *node) { node->next = head; node->prev = head->prev; head->prev = node; node->prev->next = node; } /* Move to beginning of linked list */ static inline void dll_promote(struct dll *head, struct dll *node) { dll_remove(node); dll_insert_head(head, node); } /* Move to end of linked list */ static inline void dll_demote(struct dll *head, struct dll *node) { dll_remove(node); dll_insert_tail(head, node); } #endif /* LIST_H */