-
Notifications
You must be signed in to change notification settings - Fork 80
/
rculist.h
87 lines (68 loc) · 2.46 KB
/
rculist.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/* concurrency linked list */
#pragma once
#include <stddef.h>
/* Reuse the RCU from thread-rcu */
#include "../thread-rcu/rcu.h"
#define __allow_unused __attribute__((unused))
#define container_of(ptr, type, member) \
__extension__({ \
const __typeof__(((type *) 0)->member) *__mptr = (ptr); \
(type *) ((char *) __mptr - offsetof(type, member)); \
})
#define list_entry_rcu(ptr, type, member) \
container_of(READ_ONCE(ptr), type, member)
#define list_next_rcu(n) (*((struct list_head __rcu **) (&(n)->next)))
struct list_head {
struct list_head *next, *prev;
};
static inline void list_init_rcu(struct list_head *node)
{
node->next = node;
barrier();
node->prev = node;
}
static inline void __list_add_rcu(struct list_head *new,
struct list_head *prev,
struct list_head *next)
{
next->prev = new;
new->next = next;
new->prev = prev;
barrier();
rcu_assign_pointer(list_next_rcu(prev), new);
}
static inline void list_add_rcu(struct list_head *new, struct list_head *head)
{
__list_add_rcu(new, head, head->next);
}
static inline void list_add_tail_rcu(struct list_head *new,
struct list_head *head)
{
__list_add_rcu(new, head->prev, head);
}
static inline void __list_del_rcu(struct list_head *prev,
struct list_head *next)
{
next->prev = prev;
barrier();
rcu_assign_pointer(list_next_rcu(prev), next);
}
static inline void list_del_rcu(struct list_head *node)
{
__list_del_rcu(node->prev, node->next);
list_init_rcu(node);
}
/*
* For the write side only (i.e., it should hold the lock when we use the
* non-rcu postfix for loop API).
*/
#define list_for_each(n, head) for (n = (head)->next; n != (head); n = n->next)
#define list_for_each_from(pos, head) for (; pos != (head); pos = pos->next)
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
/* The read side should only use the following API. */
#define list_for_each_entry_rcu(pos, head, member) \
for (pos = list_entry_rcu((head)->next, __typeof__(*pos), member); \
&pos->member != (head); \
pos = list_entry_rcu(pos->member.next, __typeof__(*pos), member))