summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2018-03-28 00:29:24 +0200
committerRichard Braun <rbraun@sceen.net>2018-03-28 00:38:37 +0200
commit8be065e69f2bfbac12297fa22f56901e2fbc60ab (patch)
treeb98e0400681bf1365b9438eb2c81ea10ad6a21a0 /src
parent6fb44164ecdb2227be73344724be10eb9b50a6e1 (diff)
list: fix RCU walking
Diffstat (limited to 'src')
-rw-r--r--src/list.h29
1 files changed, 19 insertions, 10 deletions
diff --git a/src/list.h b/src/list.h
index 7d280cd..51d46b6 100644
--- a/src/list.h
+++ b/src/list.h
@@ -24,6 +24,8 @@
*
*
* Doubly-linked list.
+ *
+ * TODO Tests.
*/
#ifndef LIST_H
@@ -503,12 +505,12 @@ list_rcu_remove(struct list *node)
* the node pointer can only be read once, preventing the combination
* of lockless list_empty()/list_first_entry() variants.
*/
-#define list_rcu_first_entry(list, type, member) \
+#define list_rcu_first_entry(head, type, member) \
MACRO_BEGIN \
struct list *list___; \
struct list *first___; \
\
- list___ = (list); \
+ list___ = (head); \
first___ = list_rcu_first(list___); \
list_end(list___, first___) \
? NULL \
@@ -522,8 +524,17 @@ MACRO_END
* the node pointer can only be read once, preventing the combination
* of lockless list_empty()/list_next_entry() variants.
*/
-#define list_rcu_next_entry(entry, member) \
- list_rcu_first_entry(&entry->member, typeof(*entry), member)
+#define list_rcu_next_entry(head, entry, member) \
+MACRO_BEGIN \
+ struct list *list___; \
+ struct list *next___; \
+ \
+ list___ = (head); \
+ next___ = list_rcu_next(&entry->member); \
+ list_end(list___, next___) \
+ ? NULL \
+ : list_entry(next___, typeof(*entry), member); \
+MACRO_END
/*
* Forge a loop to process all nodes of a list.
@@ -540,12 +551,10 @@ for (node = list_rcu_first(list); \
*
* The entry node must not be altered during the loop.
*/
-#define list_rcu_for_each_entry(list, entry, member) \
-for (entry = list_rcu_entry(list_first(list), \
- typeof(*entry), member); \
- !list_end(list, &entry->member); \
- entry = list_rcu_entry(list_next(&entry->member), \
- typeof(*entry), member))
+#define list_rcu_for_each_entry(list, entry, member) \
+for (entry = list_rcu_first_entry(list, typeof(*entry), member); \
+ entry != NULL; \
+ entry = list_rcu_next_entry(list, entry, member))
/*
* Sort a list.