2
0

list.h 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. #ifndef LIST_H
  2. #define LIST_H
  3. #include "common.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. node->next = node;
  34. node->prev = node;
  35. }
  36. /* Add to linked list */
  37. static inline void dll_insert_head(struct dll *head, struct dll *node)
  38. {
  39. node->prev = head;
  40. node->next = head->next;
  41. head->next = node;
  42. node->next->prev = node;
  43. }
  44. static inline void dll_insert_tail(struct dll *head, struct dll *node)
  45. {
  46. node->next = head;
  47. node->prev = head->prev;
  48. head->prev = node;
  49. node->prev->next = node;
  50. }
  51. /* Move to beginning of linked list */
  52. static inline void dll_promote(struct dll *head, struct dll *node)
  53. {
  54. dll_remove(node);
  55. dll_insert_head(head, node);
  56. }
  57. /* Move to end of linked list */
  58. static inline void dll_demote(struct dll *head, struct dll *node)
  59. {
  60. dll_remove(node);
  61. dll_insert_tail(head, node);
  62. }
  63. #endif /* LIST_H */