|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |