Add rcu_assign_pointer
authorMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Mon, 9 Feb 2009 05:29:58 +0000 (00:29 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Mon, 9 Feb 2009 05:29:58 +0000 (00:29 -0500)
rcu_assign_pointer has a memory barrier which lets the writer make sure the data
has been properly written to memory before setting the pointer.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Makefile
urcu.c
urcu.h

index 8c343ccd5c039244af33b173d38c8e9cdc119ed6..8224567af8438f096c1529ef976958849e0bb8dd 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -33,6 +33,10 @@ urcu-asm.S: urcu-asm.c urcu.h
 urcu-asm.o: urcu-asm.c urcu.h
        $(CC) ${CFLAGS} -c -o $@ $(SRC_DEP)
 
+#in progress...
+urcutorture.o: urcutorture.c urcu.o urcu.h rcutorture.h
+       $(CC) ${CFLAGS} $(LDFLAGS) -o $@ $(SRC_DEP)
+
 .PHONY: clean
 
 clean:
diff --git a/urcu.c b/urcu.c
index 31cdf6fc08b61c14e0a8f47d93154c0d54599ccc..23a985b9f9f4cdaf992c227322720e38bc139d85 100644 (file)
--- a/urcu.c
+++ b/urcu.c
@@ -174,7 +174,7 @@ void *urcu_publish_content(void **ptr, void *new)
         */
        oldptr = *ptr;
        debug_yield_write();
-       *ptr = new;
+       rcu_assign_pointer(*ptr, new);
 
        debug_yield_write();
        switch_qparity();
diff --git a/urcu.h b/urcu.h
index 01a4c6857d7e6fd31668dec57615be03e94ccc91..27695d495aeeb6388b121a099183949cbbdbac06 100644 (file)
--- a/urcu.h
+++ b/urcu.h
@@ -169,7 +169,29 @@ static inline void rcu_read_unlock(void)
        debug_yield_read();
 }
 
+/**
+ * rcu_assign_pointer - assign (publicize) a pointer to a newly
+ * initialized structure that will be dereferenced by RCU read-side
+ * critical sections.  Returns the value assigned.
+ *
+ * Inserts memory barriers on architectures that require them
+ * (pretty much all of them other than x86), and also prevents
+ * the compiler from reordering the code that initializes the
+ * structure after the pointer assignment.  More importantly, this
+ * call documents which pointers will be dereferenced by RCU read-side
+ * code.
+ */
+
+#define rcu_assign_pointer(p, v) \
+       ({ \
+               if (!__builtin_constant_p(v) || \
+                   ((v) != NULL)) \
+                       wmb(); \
+               (p) = (v); \
+       })
+
 extern void *urcu_publish_content(void **ptr, void *new);
+extern void synchronize_rcu(void);
 
 /*
  * Reader thread registration.
This page took 0.027097 seconds and 4 git commands to generate.