Add futex_(inc|dec|set) atomic operations
Add futex_t specific atomic operations and update
performance/harness.h to use them.
(Fix merge conflict from set_wait branch re. the futex_set_wait()
wrapper in futextest.h).
Signed-off-by: Darren Hart <dvhltc@us.ibm.com>
diff --git a/include/atomic.h b/include/atomic.h
index 8c27939..d61cfd2 100644
--- a/include/atomic.h
+++ b/include/atomic.h
@@ -43,36 +43,36 @@
* @oldval: The expected value of the futex
* @newval: The new value to try and assign the futex
*
- * Implement cmpxchg using gcc atomic builtins.
+ * Return the old value of addr->val.
*/
-static inline void
+static inline int
atomic_cmpxchg(atomic_t *addr, int oldval, int newval)
{
- __sync_val_compare_and_swap(&addr->val, oldval, newval);
+ return __sync_val_compare_and_swap(&addr->val, oldval, newval);
}
/**
* atomic_inc() - Atomic incrememnt
* @addr: Address of the variable to increment
*
- * Return the new value of *addr;
+ * Return the new value of addr->val.
*/
-static inline void
+static inline int
atomic_inc(atomic_t *addr)
{
- __sync_add_and_fetch(&addr->val, 1);
+ return __sync_add_and_fetch(&addr->val, 1);
}
/**
* atomic_dec() - Atomic decrement
* @addr: Address of the variable to decrement
*
- * Return the new value of *addr;
+ * Return the new value of addr-val.
*/
-static inline void
+static inline int
atomic_dec(atomic_t *addr)
{
- __sync_sub_and_fetch(&addr->val, 1);
+ return __sync_sub_and_fetch(&addr->val, 1);
}
/**
@@ -80,10 +80,11 @@
* @addr: Address of the variable to set
* @newval: New value for the atomic_t
*
- * Return the new value of *addr;
+ * Return the new value of addr->val.
*/
-static inline void
+static inline int
atomic_set(atomic_t *addr, int newval)
{
addr->val = newval;
+ return newval;
}
diff --git a/include/futextest.h b/include/futextest.h
index d469f9c..48d18fd 100644
--- a/include/futextest.h
+++ b/include/futextest.h
@@ -212,7 +212,7 @@
}
/**
- * futex_cmpxchg() - Atomic compare and exchange
+ * futex_cmpxchg() - atomic compare and exchange
* @uaddr: The address of the futex to be modified
* @oldval: The expected value of the futex
* @newval: The new value to try and assign the futex
@@ -225,3 +225,34 @@
{
return __sync_val_compare_and_swap(uaddr, oldval, newval);
}
+
+/**
+ * futex_dec() - atomic decrement of the futex value
+ * @uaddr: The address of the futex to be modified
+ */
+static inline void
+futex_dec(futex_t *uaddr)
+{
+ __sync_sub_and_fetch(uaddr, 1);
+}
+
+/**
+ * futex_inc() - atomic increment of the futex value
+ * @uaddr: the address of the futex to be modified
+ */
+static inline void
+futex_inc(futex_t *uaddr)
+{
+ __sync_add_and_fetch(uaddr, 1);
+}
+
+/**
+ * futex_set() - atomic decrement of the futex value
+ * @uaddr: the address of the futex to be modified
+ * @newval: New value for the atomic_t
+ */
+static inline void
+futex_set(futex_t *uaddr, u_int32_t newval)
+{
+ *uaddr = newval;
+}
diff --git a/performance/harness.h b/performance/harness.h
index 9d74d17..849209d 100644
--- a/performance/harness.h
+++ b/performance/harness.h
@@ -19,11 +19,6 @@
futex_t futex;
};
-static inline void decrement(futex_t *ptr)
-{
- __sync_fetch_and_add(ptr, -1);
-}
-
/* Called by main thread to initialize barrier */
static void barrier_init(struct thread_barrier *barrier, int threads)
{
@@ -34,7 +29,7 @@
/* Called by worker threads to synchronize with main thread */
static void barrier_sync(struct thread_barrier *barrier)
{
- decrement(&barrier->threads);
+ futex_dec(&barrier->threads);
if (barrier->threads == 0)
futex_wake(&barrier->threads, 1, FUTEX_PRIVATE_FLAG);
while (barrier->unblock == 0)