list.h 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. #ifndef LIST_H
  2. #define LIST_H
  3. #include "fw.h"
  4. typedef uint32_t key_t;
  5. /* --- Doubly linked list (head node assumed) --- */
  6. struct dll {
  7. struct dll *prev, *next;
  8. };
  9. static inline void dll_init(struct dll *head)
  10. {
  11. head->prev = head->next = head;
  12. }
  13. static inline struct dll *dll_find_offs(struct dll *head, key_t key,
  14. ptrdiff_t key_offset)
  15. {
  16. for (const struct dll *nh = head->next; nh != head; nh = nh->next) {
  17. const key_t *node_key = (const key_t *)((const char *)nh + key_offset);
  18. if (*node_key == key)
  19. return (struct dll *)nh;
  20. }
  21. return NULL;
  22. }
  23. #define dll_find(head,what,struc,list,key) \
  24. ({ \
  25. struct dll *node = dll_find_offs(head, what, offset_diff(struc,key,list)); \
  26. (struc *)(node ? container_of(node, struc, list) : NULL); \
  27. })
  28. /* Remove from linked list */
  29. static inline void dll_remove(struct dll *node)
  30. {
  31. node->prev->next = node->next;
  32. node->next->prev = node->prev;
  33. }
  34. /* Add to linked list */
  35. static inline void dll_insert_head(struct dll *head, struct dll *node)
  36. {
  37. node->prev = head;
  38. node->next = head->next;
  39. head->next = node;
  40. node->next->prev = node;
  41. }
  42. static inline void dll_insert_tail(struct dll *head, struct dll *node)
  43. {
  44. node->next = head;
  45. node->prev = head->prev;
  46. head->prev = node;
  47. node->prev->next = node;
  48. }
  49. /* Move to beginning of linked list */
  50. static inline void dll_promote(struct dll *head, struct dll *node)
  51. {
  52. dll_remove(node);
  53. dll_insert_head(head, node);
  54. }
  55. /* Move to end of linked list */
  56. static inline void dll_demote(struct dll *head, struct dll *node)
  57. {
  58. dll_remove(node);
  59. dll_insert_tail(head, node);
  60. }
  61. #endif /* LIST_H */