aboutsummaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
authorPetri Savolainen <petri.savolainen@nokia.com>2016-01-20 11:19:24 +0200
committerMaxim Uvarov <maxim.uvarov@linaro.org>2016-02-08 20:45:24 +0300
commit87e75c7bf192d91400b7c7ab56c796d35d98f10c (patch)
treeeff5fc1cf02814a57c50e07a2ac93468e06e5ccc /platform
parent8a27a4a6c8287d54f79a75bf5acab4ee8e03572b (diff)
linux-generic: atomic: non-relaxed 64bit operations
Implemented 64 bit non-relaxed atomic operations. Additional ordering is not needed in case of using ATOMIC_OP since it includes both acquire and release ordering. Signed-off-by: Petri Savolainen <petri.savolainen@nokia.com> Reviewed-by: Ola Liljedahl <ola.liljedahl@linaro.org> Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
Diffstat (limited to 'platform')
-rw-r--r--platform/linux-generic/include/odp/atomic.h83
1 files changed, 83 insertions, 0 deletions
diff --git a/platform/linux-generic/include/odp/atomic.h b/platform/linux-generic/include/odp/atomic.h
index f1ba20ff5..e262f4851 100644
--- a/platform/linux-generic/include/odp/atomic.h
+++ b/platform/linux-generic/include/odp/atomic.h
@@ -324,6 +324,89 @@ static inline int odp_atomic_cas_acq_rel_u32(odp_atomic_u32_t *atom,
__ATOMIC_RELAXED);
}
+static inline uint64_t odp_atomic_load_acq_u64(odp_atomic_u64_t *atom)
+{
+#if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
+ return ATOMIC_OP(atom, (void)0);
+#else
+ return __atomic_load_n(&atom->v, __ATOMIC_ACQUIRE);
+#endif
+}
+
+static inline void odp_atomic_store_rel_u64(odp_atomic_u64_t *atom,
+ uint64_t val)
+{
+#if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
+ (void)ATOMIC_OP(atom, atom->v = val);
+#else
+ __atomic_store_n(&atom->v, val, __ATOMIC_RELEASE);
+#endif
+}
+
+static inline void odp_atomic_add_rel_u64(odp_atomic_u64_t *atom, uint64_t val)
+{
+#if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
+ (void)ATOMIC_OP(atom, atom->v += val);
+#else
+ (void)__atomic_fetch_add(&atom->v, val, __ATOMIC_RELEASE);
+#endif
+}
+
+static inline void odp_atomic_sub_rel_u64(odp_atomic_u64_t *atom, uint64_t val)
+{
+#if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
+ (void)ATOMIC_OP(atom, atom->v -= val);
+#else
+ (void)__atomic_fetch_sub(&atom->v, val, __ATOMIC_RELEASE);
+#endif
+}
+
+static inline int odp_atomic_cas_acq_u64(odp_atomic_u64_t *atom,
+ uint64_t *old_val, uint64_t new_val)
+{
+#if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
+ int ret;
+ *old_val = ATOMIC_OP(atom, ATOMIC_CAS_OP(&ret, *old_val, new_val));
+ return ret;
+#else
+ return __atomic_compare_exchange_n(&atom->v, old_val, new_val,
+ 0 /* strong */,
+ __ATOMIC_ACQUIRE,
+ __ATOMIC_RELAXED);
+#endif
+}
+
+static inline int odp_atomic_cas_rel_u64(odp_atomic_u64_t *atom,
+ uint64_t *old_val, uint64_t new_val)
+{
+#if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
+ int ret;
+ *old_val = ATOMIC_OP(atom, ATOMIC_CAS_OP(&ret, *old_val, new_val));
+ return ret;
+#else
+ return __atomic_compare_exchange_n(&atom->v, old_val, new_val,
+ 0 /* strong */,
+ __ATOMIC_RELEASE,
+ __ATOMIC_RELAXED);
+#endif
+}
+
+static inline int odp_atomic_cas_acq_rel_u64(odp_atomic_u64_t *atom,
+ uint64_t *old_val,
+ uint64_t new_val)
+{
+#if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
+ int ret;
+ *old_val = ATOMIC_OP(atom, ATOMIC_CAS_OP(&ret, *old_val, new_val));
+ return ret;
+#else
+ return __atomic_compare_exchange_n(&atom->v, old_val, new_val,
+ 0 /* strong */,
+ __ATOMIC_ACQ_REL,
+ __ATOMIC_RELAXED);
+#endif
+}
+
/**
* @}
*/