aboutsummaryrefslogtreecommitdiff
path: root/platform/linux-generic/include/odp/api/plat
diff options
context:
space:
mode:
authorPetri Savolainen <petri.savolainen@nokia.com>2023-03-29 16:59:08 +0300
committerPetri Savolainen <petri.savolainen@nokia.com>2023-04-05 15:38:35 +0300
commit207209793df5a79cd6dc4fb2ee1b542719f30502 (patch)
tree9011dd9332cebd3766a61ef730051f80e117fc61 /platform/linux-generic/include/odp/api/plat
parentbcf004b831294ed0f042dc5a22908e8fbbe5a329 (diff)
linux-gen: atomic: optimize min/max operations on ARM
ARM ISA v8.1 introduced specific instructions for atomic minimum and maximum value updates (e.g. STUMIN and STUMAX). Utilize these instructions when available. Optimization is similar to previous optimization of atomic add operations to utilize STADD instruction. Signed-off-by: Petri Savolainen <petri.savolainen@nokia.com> Reviewed-by: Tuomas Taipale <tuomas.taipale@nokia.com>
Diffstat (limited to 'platform/linux-generic/include/odp/api/plat')
-rw-r--r--platform/linux-generic/include/odp/api/plat/atomic_inlines.h72
1 files changed, 34 insertions, 38 deletions
diff --git a/platform/linux-generic/include/odp/api/plat/atomic_inlines.h b/platform/linux-generic/include/odp/api/plat/atomic_inlines.h
index 5ce4bfc28..e47559102 100644
--- a/platform/linux-generic/include/odp/api/plat/atomic_inlines.h
+++ b/platform/linux-generic/include/odp/api/plat/atomic_inlines.h
@@ -149,28 +149,14 @@ _ODP_INLINE uint32_t odp_atomic_xchg_u32(odp_atomic_u32_t *atom,
return __atomic_exchange_n(&atom->v, new_val, __ATOMIC_RELAXED);
}
-_ODP_INLINE void odp_atomic_max_u32(odp_atomic_u32_t *atom, uint32_t new_max)
+_ODP_INLINE void odp_atomic_max_u32(odp_atomic_u32_t *atom, uint32_t val)
{
- 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;
- }
+ _odp_atomic_max_u32(atom, val);
}
-_ODP_INLINE void odp_atomic_min_u32(odp_atomic_u32_t *atom, uint32_t new_min)
+_ODP_INLINE void odp_atomic_min_u32(odp_atomic_u32_t *atom, uint32_t val)
{
- 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;
- }
+ _odp_atomic_min_u32(atom, val);
}
#ifdef ODP_ATOMIC_U64_LOCK
@@ -325,6 +311,30 @@ _ODP_INLINE int odp_atomic_cas_acq_rel_u64(odp_atomic_u64_t *atom,
return ret;
}
+_ODP_INLINE void odp_atomic_max_u64(odp_atomic_u64_t *atom, uint64_t new_val)
+{
+ uint64_t old_val;
+
+ old_val = odp_atomic_load_u64(atom);
+
+ while (new_val > old_val) {
+ if (odp_atomic_cas_u64(atom, &old_val, new_val))
+ break;
+ }
+}
+
+_ODP_INLINE void odp_atomic_min_u64(odp_atomic_u64_t *atom, uint64_t new_val)
+{
+ uint64_t old_val;
+
+ old_val = odp_atomic_load_u64(atom);
+
+ while (new_val < old_val) {
+ if (odp_atomic_cas_u64(atom, &old_val, new_val))
+ break;
+ }
+}
+
#else /* !ODP_ATOMIC_U64_LOCK */
_ODP_INLINE void odp_atomic_init_u64(odp_atomic_u64_t *atom, uint64_t val)
@@ -447,32 +457,18 @@ _ODP_INLINE int odp_atomic_cas_acq_rel_u64(odp_atomic_u64_t *atom,
__ATOMIC_RELAXED);
}
-#endif /* !ODP_ATOMIC_U64_LOCK */
-
-_ODP_INLINE void odp_atomic_max_u64(odp_atomic_u64_t *atom, uint64_t new_max)
+_ODP_INLINE void odp_atomic_max_u64(odp_atomic_u64_t *atom, uint64_t val)
{
- 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;
- }
+ _odp_atomic_max_u64(atom, val);
}
-_ODP_INLINE void odp_atomic_min_u64(odp_atomic_u64_t *atom, uint64_t new_min)
+_ODP_INLINE void odp_atomic_min_u64(odp_atomic_u64_t *atom, uint64_t val)
{
- 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;
- }
+ _odp_atomic_min_u64(atom, val);
}
+#endif /* !ODP_ATOMIC_U64_LOCK */
+
_ODP_INLINE uint32_t odp_atomic_load_acq_u32(odp_atomic_u32_t *atom)
{
return __atomic_load_n(&atom->v, __ATOMIC_ACQUIRE);