aboutsummaryrefslogtreecommitdiff
path: root/qemu-queue.h
diff options
context:
space:
mode:
authorHarsh Prateek Bora <harsh@linux.vnet.ibm.com>2011-10-25 12:10:40 +0530
committerAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>2011-10-31 12:34:18 +0530
commit5f7d05ecfda56b0b66ade19bc4d81eab46954149 (patch)
treec722dd31ec42afdebe39560b84232708c7dae312 /qemu-queue.h
parent9db221ae73a18e0bd2b1ee6c7dc1904ed06fb464 (diff)
qemu-queue: Introduce QLIST_INSERT_HEAD_RCU and dummy RCU wrappers.
SynthFS needs a QLIST_INSERT_HEAD_RCU to make sure list instructions are not re-ordered and therefore avoiding a crash. There may be parallel readers which should be allowed for lock-free access and this variant allows us to get rid of rwlocks used by readers. SynthFS is a special case where we dont really need full RCU capabilities as it doesnt allow list entry deletion but concurrent readers/writers and instruction re-ordering should not result in a crash. Also, once the real rcu is available, dummy rcu macro definitions will go away and the code will still work as expected. This patchwork is based on inputs from Paolo Bonzini. Signed-off-by: Harsh Prateek Bora <harsh@linux.vnet.ibm.com> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Diffstat (limited to 'qemu-queue.h')
-rw-r--r--qemu-queue.h13
1 files changed, 13 insertions, 0 deletions
diff --git a/qemu-queue.h b/qemu-queue.h
index 1d077458ce..22142305a6 100644
--- a/qemu-queue.h
+++ b/qemu-queue.h
@@ -76,6 +76,8 @@
* For details on the use of these macros, see the queue(3) manual page.
*/
+#include "qemu-barrier.h" /* for smp_wmb() */
+
/*
* List definitions.
*/
@@ -122,6 +124,17 @@ struct { \
(elm)->field.le_prev = &(head)->lh_first; \
} while (/*CONSTCOND*/0)
+#define QLIST_INSERT_HEAD_RCU(head, elm, field) do { \
+ (elm)->field.le_prev = &(head)->lh_first; \
+ (elm)->field.le_next = (head)->lh_first; \
+ smp_wmb(); /* fill elm before linking it */ \
+ if ((head)->lh_first != NULL) { \
+ (head)->lh_first->field.le_prev = &(elm)->field.le_next; \
+ } \
+ (head)->lh_first = (elm); \
+ smp_wmb(); \
+} while (/* CONSTCOND*/0)
+
#define QLIST_REMOVE(elm, field) do { \
if ((elm)->field.le_next != NULL) \
(elm)->field.le_next->field.le_prev = \