]> xenbits.xensource.com Git - people/royger/xen-test-framework.git/commitdiff
Ordering primitives, suitable for a shared ring
authorAndrew Cooper <andrew.cooper3@citrix.com>
Sun, 22 Mar 2015 14:54:05 +0000 (15:54 +0100)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Mon, 28 Sep 2015 13:53:02 +0000 (14:53 +0100)
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
include/arch/x86/barrier.h [new file with mode: 0644]
include/xtf/atomic.h [new file with mode: 0644]
include/xtf/barrier.h [new file with mode: 0644]
include/xtf/compiler.h
include/xtf/lib.h

diff --git a/include/arch/x86/barrier.h b/include/arch/x86/barrier.h
new file mode 100644 (file)
index 0000000..4c439af
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef XTF_X86_BARRIER_H
+#define XTF_X86_BARRIER_H
+
+/*
+ * Memory barriers for x86 systems
+ *
+ * See Linux: Documentation/memory-barriers.txt for a very detailed
+ * description of the problems and their implications.
+ *
+ * Under Xen, we rely on the fact that only x86_64 cpus are supported, which
+ * guarantees that the {m,l,s}fence instructions are supported (SSE2 being a
+ * requirement of 64bit).
+ *
+ * x86 memory ordering requirements make the smp_???() variants easy.  From
+ * the point of view of program order, reads may not be reordered with respect
+ * to other reads, and writes may not be reordered with respect to other
+ * writes, causing smp_rmb() and smp_wmb() to degrade to simple compiler
+ * barriers.  smp_mb() however does need to be an mfence instruction, as reads
+ * are permitted to be reordered ahead of non-aliasing writes.
+ */
+
+#include <xtf/compiler.h>
+
+#define mb()      __asm__ __volatile__ ("mfence" ::: "memory")
+#define rmb()     __asm__ __volatile__ ("lfence" ::: "memory")
+#define wmb()     __asm__ __volatile__ ("sfence" ::: "memory")
+
+#define smp_mb()  mb()
+#define smp_rmb() barrier()
+#define smp_wmb() barrier()
+
+#endif /* XTF_X86_BARRIER_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/include/xtf/atomic.h b/include/xtf/atomic.h
new file mode 100644 (file)
index 0000000..3034165
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef XTF_ATOMIC_H
+#define XTF_ATOMIC_H
+
+#include <xtf/barrier.h>
+
+#define LOAD_ACQUIRE(p)                         \
+    ({ typeof(*p) _p = ACCESS_ONCE(*p);         \
+        smp_rmb();                              \
+        _p;                                     \
+    })
+
+#define STORE_RELEASE(p, v)                     \
+    ({ smp_wmb();                               \
+        ACCESS_ONCE(*p) = v;                    \
+    })
+
+#endif /* XTF_ATOMIC_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/include/xtf/barrier.h b/include/xtf/barrier.h
new file mode 100644 (file)
index 0000000..0db30d3
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef XTF_BARRIER_H
+#define XTF_BARRIER_H
+
+#if defined(__x86_64__) || defined (__i386__)
+# include <arch/x86/barrier.h>
+#else
+# error Bad architecture
+#endif
+
+#endif /* XTF_BARRIER_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
index a6dc0b72bfbd10d758ec0516db45196ae9c65705..b91744c455bd46cde234e75d9fcc390d3ebc1129 100644 (file)
@@ -6,6 +6,8 @@
 
 #define __printf(f, v)        __attribute__((format(__printf__, f, v)))
 
+#define barrier()             __asm__ __volatile__ ("" ::: "memory")
+
 #endif /* XTF_COMPILER_H */
 
 /*
index 819322b5207d46b59966b5e36b9fd0e81dcd94de..512e954cb701ddf1f6337f8195a40557f31691fb 100644 (file)
@@ -1,8 +1,12 @@
 #ifndef XTF_LIB_H
 #define XTF_LIB_H
 
+#include <xtf/types.h>
+
 #define ARRAY_SIZE(a)    (sizeof(a) / sizeof(*a))
 
+#define ACCESS_ONCE(x)   (*(volatile typeof(x) *)&(x))
+
 #endif /* XTF_LIB_H */
 
 /*