| 1 | // SPDX-License-Identifier: MIT |
| 2 | /* |
| 3 | * Copyright 2022 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> |
| 4 | */ |
| 5 | |
| 6 | #ifndef _SIDE_RCULIST_H |
| 7 | #define _SIDE_RCULIST_H |
| 8 | |
| 9 | #include "list_types.h" |
| 10 | #include "rcu.h" |
| 11 | |
| 12 | static inline |
| 13 | void side_list_insert_node_tail_rcu(struct side_list_head *head, struct side_list_node *node) |
| 14 | { |
| 15 | node->next = &head->node; |
| 16 | node->prev = head->node.prev; |
| 17 | head->node.prev = node; |
| 18 | side_rcu_assign_pointer(node->prev->next, node); |
| 19 | } |
| 20 | |
| 21 | static inline |
| 22 | void side_list_insert_node_head_rcu(struct side_list_head *head, struct side_list_node *node) |
| 23 | { |
| 24 | node->next = head->node.next; |
| 25 | node->prev = &head->node; |
| 26 | node->next->prev = node; |
| 27 | side_rcu_assign_pointer(head->node.next, node); |
| 28 | } |
| 29 | |
| 30 | static inline |
| 31 | void side_list_remove_node_rcu(struct side_list_node *node) |
| 32 | { |
| 33 | node->next->prev = node->prev; |
| 34 | __atomic_store_n(&node->prev->next, node->next, __ATOMIC_RELAXED); |
| 35 | } |
| 36 | |
| 37 | #define side_list_for_each_entry_rcu(_entry, _head, _member) \ |
| 38 | for ((_entry) = side_container_of(side_rcu_dereference((_head)->node.next), __typeof__(*(_entry)), _member); \ |
| 39 | &(_entry)->_member != &(_head)->node; \ |
| 40 | (_entry) = side_container_of(side_rcu_dereference((_entry)->_member.next), __typeof__(*(_entry)), _member)) |
| 41 | |
| 42 | #endif /* _SIDE_RCULIST_H */ |