From 971dc580812a096f3b37282dd8ffcac4b126390f Mon Sep 17 00:00:00 2001 From: Xuhai Chang Date: Sun, 12 Oct 2025 13:43:44 +0800 Subject: [PATCH] riscv: implement atomic_yield fastpath --- CMakeLists.txt | 10 ++++++++++ include/mimalloc/atomic.h | 13 ++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bb3682c48..f5ddd1109 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,6 +49,7 @@ option(MI_CHECK_FULL "Use full internal invariant checking in DEBUG mode option(MI_USE_LIBATOMIC "Explicitly link with -latomic (on older systems) (deprecated and detected automatically)" OFF) include(CheckLinkerFlag) # requires cmake 3.18 +include(CheckCCompilerFlag) include(CheckIncludeFiles) include(GNUInstallDirs) include("cmake/mimalloc-config-version.cmake") @@ -151,6 +152,8 @@ if(MI_NO_OPT_ARCH) set(MI_OPT_ARCH "OFF") elseif(MI_ARCH STREQUAL "arm64") set(MI_OPT_ARCH "ON") # enable armv8.1-a by default on arm64 unless MI_NO_OPT_ARCH is set +elseif(MI_ARCH STREQUAL "riscv64") + set(MI_OPT_ARCH "ON") # enable rv64gc_zihintpause by default on riscv64 unless MI_NO_OPT_ARCH is set endif() @@ -454,6 +457,13 @@ if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang|GNU|Intel" AND NOT CMAKE_SYSTEM set(MI_OPT_ARCH_FLAGS "-march=haswell;-mavx2") # fast bit scan (since 2013) elseif(MI_ARCH STREQUAL "arm64") set(MI_OPT_ARCH_FLAGS "-march=armv8.1-a") # fast atomics (since 2016) + elseif(MI_ARCH STREQUAL "riscv64") + check_c_compiler_flag("-march=rv64gc_zihintpause" MI_HAS_RISCV_PAUSE) # fast atomcs + if(MI_HAS_RISCV_PAUSE) + set(MI_OPT_ARCH_FLAGS "-march=rv64gc_zihintpause") # fast atomics + else() + set(MI_OPT_ARCH_FLAGS "-march=rv64gc") + endif() endif() endif() endif() diff --git a/include/mimalloc/atomic.h b/include/mimalloc/atomic.h index 592afb16e..149a46976 100644 --- a/include/mimalloc/atomic.h +++ b/include/mimalloc/atomic.h @@ -381,7 +381,8 @@ static inline void mi_atomic_yield(void) { #elif (defined(__GNUC__) || defined(__clang__)) && \ (defined(__x86_64__) || defined(__i386__) || \ defined(__aarch64__) || defined(__arm__) || \ - defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) || defined(__POWERPC__)) + defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) || defined(__POWERPC__) || \ + defined(__riscv)) #if defined(__x86_64__) || defined(__i386__) static inline void mi_atomic_yield(void) { __asm__ volatile ("pause" ::: "memory"); @@ -410,6 +411,16 @@ static inline void mi_atomic_yield(void) { __asm__ __volatile__ ("or 27,27,27" ::: "memory"); } #endif +#elif defined(__riscv) +#if defined(__riscv_zihintpause) +static inline void mi_atomic_yield(void) { + __asm__ volatile ("pause"); +} +#else +static inline void mi_atomic_yield(void) { + __asm__ volatile ("nop"); +} +#endif #endif #elif defined(__sun) // Fallback for other archs