[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v2 2/3] xen/atomic: Implement atomic_{inc, dec}_bounded()



These will increment/decremented an atomic_t, while ensuring that the atomic_t
doesn't hit a specific bound.

This involves introducing atomic_cmpxchg() for x86, which previously only
existed on ARM.

Suggested-by: Don Slutz <dslutz@xxxxxxxxxxx>
Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CC: Keir Fraser <keir@xxxxxxx>
CC: Jan Beulich <JBeulich@xxxxxxxx>
---
 xen/common/Makefile          |    1 +
 xen/common/atomic.c          |   35 +++++++++++++++++++++++++++++++++++
 xen/include/asm-x86/atomic.h |    5 +++++
 xen/include/xen/atomic.h     |   20 ++++++++++++++++++++
 4 files changed, 61 insertions(+)
 create mode 100644 xen/common/atomic.c

diff --git a/xen/common/Makefile b/xen/common/Makefile
index 3683ae3..7c1ee1d 100644
--- a/xen/common/Makefile
+++ b/xen/common/Makefile
@@ -1,3 +1,4 @@
+obj-y += atomic.o
 obj-y += bitmap.o
 obj-y += core_parking.o
 obj-y += cpu.o
diff --git a/xen/common/atomic.c b/xen/common/atomic.c
new file mode 100644
index 0000000..64408e3
--- /dev/null
+++ b/xen/common/atomic.c
@@ -0,0 +1,35 @@
+#include <xen/atomic.h>
+
+bool_t atomic_inc_bounded(atomic_t *v, int bound)
+{
+    int old, new, prev = atomic_read(v);
+
+    do
+    {
+        old = prev;
+        new = old + 1;
+        if ( new >= bound )
+            return 0;
+
+        prev = atomic_cmpxchg(v, old, new);
+    } while ( prev != old );
+
+    return 1;
+}
+
+bool_t atomic_dec_bounded(atomic_t *v, int bound)
+{
+    int old, new, prev = atomic_read(v);
+
+    do
+    {
+        old = prev;
+        new = old - 1;
+        if ( new <= bound )
+            return 0;
+
+        prev = atomic_cmpxchg(v, old, new);
+    } while ( prev != old );
+
+    return 1;
+}
diff --git a/xen/include/asm-x86/atomic.h b/xen/include/asm-x86/atomic.h
index 8972463..43a250b 100644
--- a/xen/include/asm-x86/atomic.h
+++ b/xen/include/asm-x86/atomic.h
@@ -255,4 +255,9 @@ static inline atomic_t atomic_compareandswap(
     return rc;
 }
 
+static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
+{
+    return __cmpxchg(&ptr->counter, old, new, sizeof(ptr->counter));
+}
+
 #endif /* __ARCH_X86_ATOMIC__ */
diff --git a/xen/include/xen/atomic.h b/xen/include/xen/atomic.h
index 141f9e9..d1a6b57 100644
--- a/xen/include/xen/atomic.h
+++ b/xen/include/xen/atomic.h
@@ -3,4 +3,24 @@
 
 #include <asm/atomic.h>
 
+/**
+ * atomic_inc_bounded - increment @v if it wouldn't exceed @bound
+ * @v:     pointer of type atomic_t
+ * @bound: boundary to compare against
+ *
+ * returns true if @v was incremented, or false if incrementing @v would hit
+ * @bound.
+ */
+bool_t atomic_inc_bounded(atomic_t *v, int bound);
+
+/**
+ * atomic_dec_bounded - decrement @v if it wouldn't exceed @bound
+ * @v:     pointer of type atomic_t
+ * @bound: boundary to compare against
+ *
+ * returns true if @v was decremented, or false if decrementing @v would hit
+ * @bound.
+ */
+bool_t atomic_dec_bounded(atomic_t *v, int bound);
+
 #endif /* __XEN_ATOMIC_H__ */
-- 
1.7.10.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.