From be05af79fb8d9a6f88e8ad384675df9cfad23069 Mon Sep 17 00:00:00 2001 From: Huang Qi Date: Sat, 18 Nov 2023 08:59:58 +0800 Subject: [PATCH] Refine atomic operation flags in bh_atomic.h (#2780) --- core/shared/utils/bh_atomic.h | 104 +++++++++++++++++++++++----------- 1 file changed, 71 insertions(+), 33 deletions(-) diff --git a/core/shared/utils/bh_atomic.h b/core/shared/utils/bh_atomic.h index ac3417c30..5744a64c0 100644 --- a/core/shared/utils/bh_atomic.h +++ b/core/shared/utils/bh_atomic.h @@ -47,6 +47,19 @@ extern "C" { typedef uint32 bh_atomic_32_t; typedef uint16 bh_atomic_16_t; +/* The flag can be defined by the user if the platform + * supports atomic 32-bit operations. + * If left undefined, it will be automatically defined + * according to the platform. + */ +#ifdef WASM_UINT32_IS_ATOMIC +#define BH_ATOMIC_32_IS_ATOMIC WASM_UINT32_IS_ATOMIC +#endif /* WASM_UINT32_IS_ATOMIC */ + +#ifdef WASM_UINT16_IS_ATOMIC +#define BH_ATOMIC_16_IS_ATOMIC WASM_UINT16_IS_ATOMIC +#endif /* WASM_UINT16_IS_ATOMIC */ + #if defined(__GNUC_PREREQ) #if __GNUC_PREREQ(4, 7) #define CLANG_GCC_HAS_ATOMIC_BUILTIN @@ -58,7 +71,38 @@ typedef uint16 bh_atomic_16_t; #endif #if defined(CLANG_GCC_HAS_ATOMIC_BUILTIN) +#ifndef BH_ATOMIC_32_IS_ATOMIC #define BH_ATOMIC_32_IS_ATOMIC 1 +#endif +#ifndef BH_ATOMIC_16_IS_ATOMIC +#define BH_ATOMIC_16_IS_ATOMIC 1 +#endif +#else +#ifndef BH_ATOMIC_32_IS_ATOMIC +#define BH_ATOMIC_32_IS_ATOMIC 0 +#endif +#ifndef BH_ATOMIC_16_IS_ATOMIC +#define BH_ATOMIC_16_IS_ATOMIC 0 +#endif +#endif + +/* Force disable atomic 16-bit operations on bare-metal RISC-V + * because the 16-bit atomic operations is emulated by 32-bit + * atomic operations, which has linkage problem on current toolchain: + * in function `shared_memory_inc_reference': + * wasm_shared_memory.c:85:(.text.shared_memory_inc_reference+0x10): undefined + * reference to `__atomic_fetch_add_2' + */ +#ifndef WASM_UINT16_IS_ATOMIC +#if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) \ + && !defined(__OpenBSD__) && defined(__riscv) +#undef BH_ATOMIC_16_IS_ATOMIC +#define BH_ATOMIC_16_IS_ATOMIC 0 +#endif +#endif + +#if BH_ATOMIC_32_IS_ATOMIC != 0 + #define BH_ATOMIC_32_LOAD(v) __atomic_load_n(&(v), __ATOMIC_SEQ_CST) #define BH_ATOMIC_32_STORE(v, val) __atomic_store_n(&(v), val, __ATOMIC_SEQ_CST) #define BH_ATOMIC_32_FETCH_OR(v, val) \ @@ -70,18 +114,8 @@ typedef uint16 bh_atomic_16_t; #define BH_ATOMIC_32_FETCH_SUB(v, val) \ __atomic_fetch_sub(&(v), (val), __ATOMIC_SEQ_CST) -#define BH_ATOMIC_16_IS_ATOMIC 1 -#define BH_ATOMIC_16_LOAD(v) __atomic_load_n(&(v), __ATOMIC_SEQ_CST) -#define BH_ATOMIC_16_STORE(v, val) __atomic_store_n(&(v), val, __ATOMIC_SEQ_CST) -#define BH_ATOMIC_16_FETCH_OR(v, val) \ - __atomic_fetch_or(&(v), (val), __ATOMIC_SEQ_CST) -#define BH_ATOMIC_16_FETCH_AND(v, val) \ - __atomic_fetch_and(&(v), (val), __ATOMIC_SEQ_CST) -#define BH_ATOMIC_16_FETCH_ADD(v, val) \ - __atomic_fetch_add(&(v), (val), __ATOMIC_SEQ_CST) -#define BH_ATOMIC_16_FETCH_SUB(v, val) \ - __atomic_fetch_sub(&(v), (val), __ATOMIC_SEQ_CST) -#else /* else of defined(CLANG_GCC_HAS_ATOMIC_BUILTIN) */ +#else /* else of BH_ATOMIC_32_IS_ATOMIC != 0 */ + #define BH_ATOMIC_32_LOAD(v) (v) #define BH_ATOMIC_32_STORE(v, val) (v) = val #define BH_ATOMIC_32_FETCH_OR(v, val) nonatomic_32_fetch_or(&(v), val) @@ -89,13 +123,6 @@ typedef uint16 bh_atomic_16_t; #define BH_ATOMIC_32_FETCH_ADD(v, val) nonatomic_32_fetch_add(&(v), val) #define BH_ATOMIC_32_FETCH_SUB(v, val) nonatomic_32_fetch_sub(&(v), val) -#define BH_ATOMIC_16_LOAD(v) (v) -#define BH_ATOMIC_16_STORE(v) (v) = val -#define BH_ATOMIC_16_FETCH_OR(v, val) nonatomic_16_fetch_or(&(v), val) -#define BH_ATOMIC_16_FETCH_AND(v, val) nonatomic_16_fetch_and(&(v), val) -#define BH_ATOMIC_16_FETCH_ADD(v, val) nonatomic_16_fetch_add(&(v), val) -#define BH_ATOMIC_16_FETCH_SUB(v, val) nonatomic_16_fetch_sub(&(v), val) - static inline uint32 nonatomic_32_fetch_or(bh_atomic_32_t *p, uint32 val) { @@ -128,6 +155,31 @@ nonatomic_32_fetch_sub(bh_atomic_32_t *p, uint32 val) return old; } +#endif + +#if BH_ATOMIC_16_IS_ATOMIC != 0 + +#define BH_ATOMIC_16_IS_ATOMIC 1 +#define BH_ATOMIC_16_LOAD(v) __atomic_load_n(&(v), __ATOMIC_SEQ_CST) +#define BH_ATOMIC_16_STORE(v, val) __atomic_store_n(&(v), val, __ATOMIC_SEQ_CST) +#define BH_ATOMIC_16_FETCH_OR(v, val) \ + __atomic_fetch_or(&(v), (val), __ATOMIC_SEQ_CST) +#define BH_ATOMIC_16_FETCH_AND(v, val) \ + __atomic_fetch_and(&(v), (val), __ATOMIC_SEQ_CST) +#define BH_ATOMIC_16_FETCH_ADD(v, val) \ + __atomic_fetch_add(&(v), (val), __ATOMIC_SEQ_CST) +#define BH_ATOMIC_16_FETCH_SUB(v, val) \ + __atomic_fetch_sub(&(v), (val), __ATOMIC_SEQ_CST) + +#else /* else of BH_ATOMIC_16_IS_ATOMIC != 0 */ + +#define BH_ATOMIC_16_LOAD(v) (v) +#define BH_ATOMIC_16_STORE(v) (v) = val +#define BH_ATOMIC_16_FETCH_OR(v, val) nonatomic_16_fetch_or(&(v), val) +#define BH_ATOMIC_16_FETCH_AND(v, val) nonatomic_16_fetch_and(&(v), val) +#define BH_ATOMIC_16_FETCH_ADD(v, val) nonatomic_16_fetch_add(&(v), val) +#define BH_ATOMIC_16_FETCH_SUB(v, val) nonatomic_16_fetch_sub(&(v), val) + static inline uint16 nonatomic_16_fetch_or(bh_atomic_16_t *p, uint16 val) { @@ -160,20 +212,6 @@ nonatomic_16_fetch_sub(bh_atomic_16_t *p, uint16 val) return old; } -/* The flag can be defined by the user if the platform - supports atomic access to uint32 aligned memory. */ -#ifdef WASM_UINT32_IS_ATOMIC -#define BH_ATOMIC_32_IS_ATOMIC 1 -#else /* else of WASM_UINT32_IS_ATOMIC */ -#define BH_ATOMIC_32_IS_ATOMIC 0 -#endif /* WASM_UINT32_IS_ATOMIC */ - -#ifdef WASM_UINT16_IS_ATOMIC -#define BH_ATOMIC_16_IS_ATOMIC 1 -#else /* else of WASM_UINT16_IS_ATOMIC */ -#define BH_ATOMIC_16_IS_ATOMIC 0 -#endif /* WASM_UINT16_IS_ATOMIC */ - #endif #ifdef __cplusplus