Added 32 bit acquire load/cas and release store/add/sub calls.
These are the minimum set of non-relaxed calls that are needed
for building lock-free algorithms. 64 bit versions can be added
later.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 include/odp/api/atomic.h                    | 80 ++++++++++++++++++++++++++++-
 platform/linux-generic/include/odp/atomic.h | 32 ++++++++++++
 2 files changed, 111 insertions(+), 1 deletion(-)

diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h
index b79a50a..316f13a 100644
--- a/include/odp/api/atomic.h
+++ b/include/odp/api/atomic.h
@@ -21,7 +21,7 @@ extern "C" {
 /**
  * @defgroup odp_atomic ODP ATOMIC
  * @details
- * <b> Atomic integers </b>
+ * <b> Atomic integers using relaxed memory ordering </b>
  *
  * Atomic integer types (odp_atomic_u32_t and odp_atomic_u64_t) can be used to
  * implement e.g. shared counters. If not otherwise documented, operations in
@@ -31,6 +31,18 @@ extern "C" {
  * before or after the operation), only atomicity of the operation itself is
  * guaranteed.
  *
+ * <b> Operations with other than relaxed memory ordering </b>
+ *
+ * <b> An operation with RELEASE </b> memory ordering 
(odp_atomic_xxx_rls_xxx())
+ * ensures that other threads loading the same atomic variable with ACQUIRE
+ * memory ordering see all stores (from the calling thread) that happened 
before
+ * this releasing store.
+ *
+ * <b> An operation with ACQUIRE </b> memory ordering 
(odp_atomic_xxx_acq_xxx())
+ * ensures that the calling thread sees all stores (done by the releasing
+ * thread) that happened before a RELEASE memory ordered store to the same
+ * atomic variable.
+ *
  * @{
  */
 
@@ -309,6 +321,72 @@ void odp_atomic_min_u64(odp_atomic_u64_t *atom, uint64_t 
new_min);
 int odp_atomic_cas_u64(odp_atomic_u64_t *atom, uint64_t *old_val,
                       uint64_t new_val);
 
+/*
+ * Operations with other than relaxed memory ordering
+ * --------------------------------------------------
+ */
+
+/**
+ * Load value of atomic uint32 variable using ACQUIRE memory ordering
+ *
+ * Otherwise identical to odp_atomic_load_u32() but ensures ACQUIRE memory
+ * ordering.
+ *
+ * @param atom    Pointer to atomic variable
+ *
+ * @return Value of the variable
+ */
+uint32_t odp_atomic_load_acq_u32(odp_atomic_u32_t *atom);
+
+/**
+ * Compare and swap atomic uint32 variable using ACQUIRE memory ordering
+ *
+ * Otherwise identical to odp_atomic_cas_u32() but ensures ACQUIRE memory
+ * ordering.
+ *
+ * @param         atom      Pointer to atomic variable
+ * @param[in,out] old_val   Pointer to the old value of the atomic variable.
+ *                          Operation updates this value on failure.
+ * @param         new_val   New value to be written into the atomic variable
+ *
+ * @return 0 on failure, !0 on success
+ */
+int odp_atomic_cas_acq_u32(odp_atomic_u32_t *atom, uint32_t *old_val,
+                          uint32_t new_val);
+
+/**
+ * Store value to atomic uint32 variable using RELEASE memory ordering
+ *
+ * Otherwise identical to odp_atomic_store_u32() but ensures RELEASE memory
+ * ordering.
+ *
+ * @param atom    Pointer to atomic variable
+ * @param val     Value to store in the variable
+ */
+void odp_atomic_store_rls_u32(odp_atomic_u32_t *atom, uint32_t val);
+
+/**
+ * Add to atomic uint32 variable using RELEASE memory ordering
+ *
+ * Otherwise identical to odp_atomic_add_u32() but ensures RELEASE memory
+ * ordering.
+ *
+ * @param atom    Pointer to atomic variable
+ * @param val     Value to be added to the variable
+ */
+void odp_atomic_add_rls_u32(odp_atomic_u32_t *atom, uint32_t val);
+
+/**
+ * Subtract from atomic uint32 variable using RELEASE memory ordering
+ *
+ * Otherwise identical to odp_atomic_sub_u32() but ensures RELEASE memory
+ * ordering.
+ *
+ * @param atom    Pointer to atomic variable
+ * @param val     Value to be subtracted from the variable
+ */
+void odp_atomic_sub_rls_u32(odp_atomic_u32_t *atom, uint32_t val);
+
 /**
  * @}
  */
diff --git a/platform/linux-generic/include/odp/atomic.h 
b/platform/linux-generic/include/odp/atomic.h
index b2bc5c4..005a0cd 100644
--- a/platform/linux-generic/include/odp/atomic.h
+++ b/platform/linux-generic/include/odp/atomic.h
@@ -258,6 +258,38 @@ static inline void odp_atomic_min_u64(odp_atomic_u64_t 
*atom, uint64_t new_min)
        }
 }
 
+static inline uint32_t odp_atomic_load_acq_u32(odp_atomic_u32_t *atom)
+{
+       return __atomic_load_n(&atom->v, __ATOMIC_ACQUIRE);
+}
+
+static inline int odp_atomic_cas_acq_u32(odp_atomic_u32_t *atom,
+                                        uint32_t *old_val, uint32_t new_val)
+{
+       return __atomic_compare_exchange_n(&atom->v, old_val, new_val,
+                                          0 /* strong */,
+                                          __ATOMIC_ACQUIRE,
+                                          __ATOMIC_RELAXED);
+}
+
+static inline void odp_atomic_store_rls_u32(odp_atomic_u32_t *atom,
+                                           uint32_t val)
+{
+       __atomic_store_n(&atom->v, val, __ATOMIC_RELEASE);
+}
+
+static inline void odp_atomic_add_rls_u32(odp_atomic_u32_t *atom,
+                                         uint32_t val)
+{
+       (void)__atomic_fetch_add(&atom->v, val, __ATOMIC_RELEASE);
+}
+
+static inline void odp_atomic_sub_rls_u32(odp_atomic_u32_t *atom,
+                                         uint32_t val)
+{
+       (void)__atomic_fetch_sub(&atom->v, val, __ATOMIC_RELEASE);
+}
+
 /**
  * @}
  */
-- 
2.6.2

_______________________________________________
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to