summaryrefslogtreecommitdiff
path: root/backport-include/linux/rculist.h
diff options
context:
space:
mode:
Diffstat (limited to 'backport-include/linux/rculist.h')
-rw-r--r--backport-include/linux/rculist.h57
1 files changed, 57 insertions, 0 deletions
diff --git a/backport-include/linux/rculist.h b/backport-include/linux/rculist.h
new file mode 100644
index 0000000..9671e7c
--- /dev/null
+++ b/backport-include/linux/rculist.h
@@ -0,0 +1,57 @@
+#ifndef __BACKPORT_RCULIST_H
+#define __BACKPORT_RCULIST_H
+#include_next <linux/rculist.h>
+
+#if LINUX_VERSION_IS_LESS(3,9,0)
+#include <backport/magic.h>
+#define hlist_for_each_entry_rcu4(tpos, pos, head, member) \
+ for (pos = rcu_dereference_raw(hlist_first_rcu(head)); \
+ pos && \
+ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; });\
+ pos = rcu_dereference_raw(hlist_next_rcu(pos)))
+
+#define hlist_for_each_entry_rcu3(pos, head, member) \
+ for (pos = hlist_entry_safe (rcu_dereference_raw(hlist_first_rcu(head)),\
+ typeof(*(pos)), member); \
+ pos; \
+ pos = hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu( \
+ &(pos)->member)), typeof(*(pos)), member))
+
+#undef hlist_for_each_entry_rcu
+#define hlist_for_each_entry_rcu(...) \
+ macro_dispatcher(hlist_for_each_entry_rcu, __VA_ARGS__)(__VA_ARGS__)
+#endif /* < 3.9 */
+
+#ifndef list_for_each_entry_continue_rcu
+#define list_for_each_entry_continue_rcu(pos, head, member) \
+ for (pos = list_entry_rcu(pos->member.next, typeof(*pos), member); \
+ prefetch(pos->member.next), &pos->member != (head); \
+ pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
+#endif
+
+#ifndef list_entry_rcu
+#define list_entry_rcu(ptr, type, member) \
+ container_of(rcu_dereference(ptr), type, member)
+#endif
+
+#ifndef list_first_or_null_rcu
+/**
+ * list_first_or_null_rcu - get the first element from a list
+ * @ptr: the list head to take the element from.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Note that if the list is empty, it returns NULL.
+ *
+ * This primitive may safely run concurrently with the _rcu list-mutation
+ * primitives such as list_add_rcu() as long as it's guarded by rcu_read_lock().
+ */
+#define list_first_or_null_rcu(ptr, type, member) \
+({ \
+ struct list_head *__ptr = (ptr); \
+ struct list_head *__next = ACCESS_ONCE(__ptr->next); \
+ likely(__ptr != __next) ? list_entry_rcu(__next, type, member) : NULL; \
+})
+#endif /* list_first_or_null_rcu */
+
+#endif /* __BACKPORT_RCULIST_H */