aboutsummaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
authorPetri Savolainen <petri.savolainen@nokia.com>2015-10-23 10:00:20 +0300
committerMaxim Uvarov <maxim.uvarov@linaro.org>2016-02-08 20:45:24 +0300
commit630b3fa076205c73fcc0843a216d34e0e05be234 (patch)
tree2e8a48d718a821dd8285a38249225f2f595f1f94 /platform
parent2145a338867f41b37acfb204807891d39002f2aa (diff)
api: atomic: added atomic min and max
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.savolainen@nokia.com> Reviewed-by: Mike Holmes <mike.holmes@linaro.org> Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
Diffstat (limited to 'platform')
-rw-r--r--platform/linux-generic/include/odp/atomic.h48
1 files changed, 48 insertions, 0 deletions
diff --git a/platform/linux-generic/include/odp/atomic.h b/platform/linux-generic/include/odp/atomic.h
index 7d67bf54b..d99117bc1 100644
--- a/platform/linux-generic/include/odp/atomic.h
+++ b/platform/linux-generic/include/odp/atomic.h
@@ -93,6 +93,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;
@@ -209,6 +233,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;
+ }
+}
+
/**
* @}
*/