Added atomic min and max operations. These can be used e.g.
to maintain high and low water marks of an another atomic counter.
These use relaxed memory order.

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

diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h
index 957d304..b79a50a 100644
--- a/include/odp/api/atomic.h
+++ b/include/odp/api/atomic.h
@@ -136,6 +136,28 @@ uint32_t odp_atomic_fetch_dec_u32(odp_atomic_u32_t *atom);
 void odp_atomic_dec_u32(odp_atomic_u32_t *atom);
 
 /**
+ * Update maximum value of atomic uint32 variable
+ *
+ * Compares value of atomic variable to the new maximum value. If the new value
+ * is greater than the current value, writes the new value into the variable.
+ *
+ * @param atom    Pointer to atomic variable
+ * @param new_max New maximum value to be written into the atomic variable
+ */
+void odp_atomic_max_u32(odp_atomic_u32_t *atom, uint32_t new_max);
+
+/**
+ * Update minimum value of atomic uint32 variable
+ *
+ * Compares value of atomic variable to the new minimum value. If the new value
+ * is less than the current value, writes the new value into the variable.
+ *
+ * @param atom    Pointer to atomic variable
+ * @param new_min New minimum value to be written into the atomic variable
+ */
+void odp_atomic_min_u32(odp_atomic_u32_t *atom, uint32_t new_min);
+
+/**
  * Compare and swap atomic uint32 variable
  *
  * Compares value of atomic variable to the value pointed by 'old_val'.
@@ -248,6 +270,28 @@ uint64_t odp_atomic_fetch_dec_u64(odp_atomic_u64_t *atom);
 void odp_atomic_dec_u64(odp_atomic_u64_t *atom);
 
 /**
+ * Update maximum value of atomic uint64 variable
+ *
+ * Compares value of atomic variable to the new maximum value. If the new value
+ * is greater than the current value, writes the new value into the variable.
+ *
+ * @param atom    Pointer to atomic variable
+ * @param new_max New maximum value to be written into the atomic variable
+ */
+void odp_atomic_max_u64(odp_atomic_u64_t *atom, uint64_t new_max);
+
+/**
+ * Update minimum value of atomic uint64 variable
+ *
+ * Compares value of atomic variable to the new minimum value. If the new value
+ * is less than the current value, writes the new value into the variable.
+ *
+ * @param atom    Pointer to atomic variable
+ * @param new_min New minimum value to be written into the atomic variable
+ */
+void odp_atomic_min_u64(odp_atomic_u64_t *atom, uint64_t new_min);
+
+/**
  * Compare and swap atomic uint64 variable
  *
  * Compares value of atomic variable to the value pointed by 'old_val'.
diff --git a/platform/linux-generic/include/odp/atomic.h 
b/platform/linux-generic/include/odp/atomic.h
index 5b13e02..b2bc5c4 100644
--- a/platform/linux-generic/include/odp/atomic.h
+++ b/platform/linux-generic/include/odp/atomic.h
@@ -94,6 +94,30 @@ static inline int odp_atomic_cas_u32(odp_atomic_u32_t *atom, 
uint32_t *old_val,
                                           __ATOMIC_RELAXED);
 }
 
+static inline void odp_atomic_max_u32(odp_atomic_u32_t *atom, uint32_t new_max)
+{
+       uint32_t old_val;
+
+       old_val = odp_atomic_load_u32(atom);
+
+       while (new_max > old_val) {
+               if (odp_atomic_cas_u32(atom, &old_val, new_max))
+                       break;
+       }
+}
+
+static inline void odp_atomic_min_u32(odp_atomic_u32_t *atom, uint32_t new_min)
+{
+       uint32_t old_val;
+
+       old_val = odp_atomic_load_u32(atom);
+
+       while (new_min < old_val) {
+               if (odp_atomic_cas_u32(atom, &old_val, new_min))
+                       break;
+       }
+}
+
 static inline void odp_atomic_init_u64(odp_atomic_u64_t *atom, uint64_t val)
 {
        atom->v = val;
@@ -210,6 +234,30 @@ static inline int odp_atomic_cas_u64(odp_atomic_u64_t 
*atom, uint64_t *old_val,
 #endif
 }
 
+static inline void odp_atomic_max_u64(odp_atomic_u64_t *atom, uint64_t new_max)
+{
+       uint64_t old_val;
+
+       old_val = odp_atomic_load_u64(atom);
+
+       while (new_max > old_val) {
+               if (odp_atomic_cas_u64(atom, &old_val, new_max))
+                       break;
+       }
+}
+
+static inline void odp_atomic_min_u64(odp_atomic_u64_t *atom, uint64_t new_min)
+{
+       uint64_t old_val;
+
+       old_val = odp_atomic_load_u64(atom);
+
+       while (new_min < old_val) {
+               if (odp_atomic_cas_u64(atom, &old_val, new_min))
+                       break;
+       }
+}
+
 /**
  * @}
  */
-- 
2.6.2

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

Reply via email to