summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2005-12-12 09:37:11 +0100
committerLinus Torvalds <torvalds@g5.osdl.org>2005-12-12 17:57:43 +0100
commitb88cb42428f14fabdaf947150c00d65891820635 (patch)
tree21546720b90d1263f2e61760eb515c00f350ee12 /include
parent[PATCH] Add timestamp field to process events (diff)
downloadlinux-b88cb42428f14fabdaf947150c00d65891820635.tar.xz
linux-b88cb42428f14fabdaf947150c00d65891820635.zip
[PATCH] add hlist_replace_rcu()
Add list_replace_rcu: replace old entry by new one. Signed-off-by: Paul E. McKenney <paulmck@us.ibm.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include')
-rw-r--r--include/linux/list.h26
1 files changed, 25 insertions, 1 deletions
diff --git a/include/linux/list.h b/include/linux/list.h
index fbfca73355a3..8e3388284530 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -202,12 +202,15 @@ static inline void list_del_rcu(struct list_head *entry)
*
* The old entry will be replaced with the new entry atomically.
*/
-static inline void list_replace_rcu(struct list_head *old, struct list_head *new){
+static inline void list_replace_rcu(struct list_head *old,
+ struct list_head *new)
+{
new->next = old->next;
new->prev = old->prev;
smp_wmb();
new->next->prev = new;
new->prev->next = new;
+ old->prev = LIST_POISON2;
}
/**
@@ -578,6 +581,27 @@ static inline void hlist_del_init(struct hlist_node *n)
}
}
+/*
+ * hlist_replace_rcu - replace old entry by new one
+ * @old : the element to be replaced
+ * @new : the new element to insert
+ *
+ * The old entry will be replaced with the new entry atomically.
+ */
+static inline void hlist_replace_rcu(struct hlist_node *old,
+ struct hlist_node *new)
+{
+ struct hlist_node *next = old->next;
+
+ new->next = next;
+ new->pprev = old->pprev;
+ smp_wmb();
+ if (next)
+ new->next->pprev = &new->next;
+ *new->pprev = new;
+ old->pprev = LIST_POISON2;
+}
+
static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
{
struct hlist_node *first = h->first;