| 1 | // SPDX-License-Identifier: MIT |
| 2 | /* |
| 3 | * Copyright 2022 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> |
| 4 | */ |
| 5 | |
| 6 | #ifndef _SIDE_LIST_H |
| 7 | #define _SIDE_LIST_H |
| 8 | |
| 9 | struct side_list_node { |
| 10 | struct side_list_node *next; |
| 11 | struct side_list_node *prev; |
| 12 | }; |
| 13 | |
| 14 | struct side_list_head { |
| 15 | struct side_list_node node; |
| 16 | }; |
| 17 | |
| 18 | #define DEFINE_SIDE_LIST_HEAD(_identifier) \ |
| 19 | struct side_list_head _identifier = { \ |
| 20 | .node = { \ |
| 21 | .next = &(_identifier).node, \ |
| 22 | .prev = &(_identifier).node, \ |
| 23 | }, \ |
| 24 | } |
| 25 | |
| 26 | static inline |
| 27 | void side_list_insert_node_tail(struct side_list_head *head, struct side_list_node *node) |
| 28 | { |
| 29 | node->next = &head->node; |
| 30 | node->prev = head->node.prev; |
| 31 | node->prev->next = node; |
| 32 | head->node.prev = node; |
| 33 | } |
| 34 | |
| 35 | static inline |
| 36 | void side_list_insert_node_head(struct side_list_head *head, struct side_list_node *node) |
| 37 | { |
| 38 | node->next = head->node.next; |
| 39 | node->prev = &head->node; |
| 40 | node->next->prev = node; |
| 41 | head->node.next = node; |
| 42 | } |
| 43 | |
| 44 | static inline |
| 45 | void side_list_remove_node(struct side_list_node *node) |
| 46 | { |
| 47 | node->next->prev = node->prev; |
| 48 | node->prev->next = node->next; |
| 49 | } |
| 50 | |
| 51 | #define side_list_for_each_entry(_entry, _head, _member) \ |
| 52 | for ((_entry) = side_container_of((_head)->node.next, __typeof__(*(_entry)), _member); \ |
| 53 | &(_entry)->_member != &(_head)->node; \ |
| 54 | (_entry) = side_container_of((_entry)->_member.next, __typeof__(*(_entry)), _member)) |
| 55 | |
| 56 | /* List iteration, safe against node reclaim while iterating. */ |
| 57 | #define side_list_for_each_entry_safe(_entry, _next_entry, _head, _member) \ |
| 58 | for ((_entry) = side_container_of((_head)->node.next, __typeof__(*(_entry)), _member), \ |
| 59 | (_next_entry) = side_container_of((_entry)->_member.next, __typeof__(*(_entry)), _member); \ |
| 60 | &(_entry)->_member != &(_head)->node; \ |
| 61 | (_entry) = side_container_of((_next_entry)->_member.next, __typeof__(*(_entry)), _member), \ |
| 62 | (_next_entry) = side_container_of((_entry)->_member.next, __typeof__(*(_entry)), _member)) |
| 63 | |
| 64 | #endif /* _SIDE_LIST_H */ |