aboutsummaryrefslogtreecommitdiff
path: root/platform/linux-generic/arch/aarch64
diff options
context:
space:
mode:
authorMalvika Gupta <Malvika.Gupta@arm.com>2021-02-23 12:00:41 -0600
committerMatias Elo <matias.elo@nokia.com>2021-03-29 11:30:41 +0300
commitad9c14ffa4363598995bf11b65e07cb4192670a7 (patch)
treee940bc9d10d87b2b742af57ea086c4dd798487db /platform/linux-generic/arch/aarch64
parent30c6605eff3ae63111929bafc3056859da276607 (diff)
linux-gen: bitset: move aarch64 specific code to arch files
On arm64 systems, the build fails with the --disable-host-optimization compiler flag as it is unable to locate definitions of lockless APIs used in atomic bit operations since these declarations are present in arch/aarch64/odp_atomic.h files Consequently, the aarch64 specific code has been moved to the arch-specific file while the reminder code has been moved under the default linux-generic implementation. Signed-off-by: Malvika Gupta <Malvika.Gupta@arm.com> Reviewed-by: Govindarajan Mohandoss <govindarajan.mohandoss@arm.com> Reviewed-by: Matias Elo <matias.elo@nokia.com>
Diffstat (limited to 'platform/linux-generic/arch/aarch64')
-rw-r--r--platform/linux-generic/arch/aarch64/odp_atomic.h82
1 files changed, 82 insertions, 0 deletions
diff --git a/platform/linux-generic/arch/aarch64/odp_atomic.h b/platform/linux-generic/arch/aarch64/odp_atomic.h
index 6cf114f2e..c7a28fc2c 100644
--- a/platform/linux-generic/arch/aarch64/odp_atomic.h
+++ b/platform/linux-generic/arch/aarch64/odp_atomic.h
@@ -12,6 +12,8 @@
#error This file should not be included directly, please include odp_cpu.h
#endif
+#include <limits.h>
+
#ifdef CONFIG_DMBSTR
#define atomic_store_release(loc, val, ro) \
@@ -241,4 +243,84 @@ static inline int lockfree_check_u128(void)
return 1;
}
+/** Atomic bit set operations with memory ordering */
+#if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__ == 16
+typedef __int128 bitset_t;
+#define ATOM_BITSET_SIZE (CHAR_BIT * __SIZEOF_INT128__)
+
+#elif __GCC_ATOMIC_LLONG_LOCK_FREE == 2 && \
+ __SIZEOF_LONG_LONG__ != __SIZEOF_LONG__
+typedef unsigned long long bitset_t;
+#define ATOM_BITSET_SIZE (CHAR_BIT * __SIZEOF_LONG_LONG__)
+
+#elif __GCC_ATOMIC_LONG_LOCK_FREE == 2 && __SIZEOF_LONG__ != __SIZEOF_INT__
+typedef unsigned long bitset_t;
+#define ATOM_BITSET_SIZE (CHAR_BIT * __SIZEOF_LONG__)
+
+#elif __GCC_ATOMIC_INT_LOCK_FREE == 2
+typedef unsigned int bitset_t;
+#define ATOM_BITSET_SIZE (CHAR_BIT * __SIZEOF_INT__)
+
+#else
+/* Target does not support lock-free atomic operations */
+typedef unsigned int bitset_t;
+#define ATOM_BITSET_SIZE (CHAR_BIT * __SIZEOF_INT__)
+#endif
+
+#if ATOM_BITSET_SIZE <= 32
+
+static inline bitset_t bitset_mask(uint32_t bit)
+{
+ return 1UL << bit;
+}
+
+#elif ATOM_BITSET_SIZE <= 64
+
+static inline bitset_t bitset_mask(uint32_t bit)
+{
+ return 1ULL << bit;
+}
+
+#elif ATOM_BITSET_SIZE <= 128
+
+static inline bitset_t bitset_mask(uint32_t bit)
+{
+ if (bit < 64)
+ return 1ULL << bit;
+ else
+ return (unsigned __int128)(1ULL << (bit - 64)) << 64;
+}
+
+#else
+#error Unsupported size of bit sets (ATOM_BITSET_SIZE)
+#endif
+
+static inline bitset_t atom_bitset_load(bitset_t *bs, int mo)
+{
+ return __lockfree_load_16(bs, mo);
+}
+
+static inline void atom_bitset_set(bitset_t *bs, uint32_t bit, int mo)
+{
+ (void)__lockfree_fetch_or_16(bs, bitset_mask(bit), mo);
+}
+
+static inline void atom_bitset_clr(bitset_t *bs, uint32_t bit, int mo)
+{
+ (void)__lockfree_fetch_and_16(bs, ~bitset_mask(bit), mo);
+}
+
+static inline bitset_t atom_bitset_xchg(bitset_t *bs, bitset_t neu, int mo)
+{
+ return __lockfree_exchange_16(bs, neu, mo);
+}
+
+static inline bitset_t atom_bitset_cmpxchg(bitset_t *bs, bitset_t *old,
+ bitset_t neu, bool weak,
+ int mo_success, int mo_failure)
+{
+ return __lockfree_compare_exchange_16(bs, old, neu, weak, mo_success,
+ mo_failure);
+}
+
#endif /* PLATFORM_LINUXGENERIC_ARCH_ARM_ODP_ATOMIC_H */