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