From 1966db91b731024c508a52df3f9f8c10bf44fa1f Mon Sep 17 00:00:00 2001 From: Jim Huang Date: Fri, 23 Apr 2021 22:42:58 +0000 Subject: [PATCH] Implement appropriate atomic_yield for Armv7+ Spin-wait often involves active sleep (better known as "pause"). x86 has a direct assembly instruction named "PAUSE" which has two roles: one is to hint at the operating systme that it might be ready to be swapped out, and the other is to create a small delay. That delay is useful as backoff from attempting to capture spinlocks, which improves the behavior of the system and allows more efficient lock acquisition. However, the "yield" instruction is not a good fit because it is effectively a nop on most Arm cores and does not cause enough delay to help backoff. The "isb" instruction is a barrier that, especially inside a loop, creates a small delay without consuming ALU resources. --- include/mimalloc-atomic.h | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/include/mimalloc-atomic.h b/include/mimalloc-atomic.h index db885319..29de7532 100644 --- a/include/mimalloc-atomic.h +++ b/include/mimalloc-atomic.h @@ -293,19 +293,15 @@ static inline void mi_atomic_yield(void) { static inline void mi_atomic_yield(void) { __asm__ volatile ("pause" ::: "memory"); } -#elif defined(__aarch64__) +#elif defined(__aarch64__) || (defined(__arm__) && __ARM_ARCH >= 7) static inline void mi_atomic_yield(void) { - asm volatile("wfe"); -} -#elif (defined(__arm__) && __ARM_ARCH__ >= 7) -static inline void mi_atomic_yield(void) { - __asm__ volatile("yield" ::: "memory"); + asm volatile("isb" ::: "memory"); } #elif defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) static inline void mi_atomic_yield(void) { __asm__ __volatile__ ("or 27,27,27" ::: "memory"); } -#elif defined(__armel__) || defined(__ARMEL__) +#elif defined(__arm__) /* Arm cores prior to Armv7-A */ static inline void mi_atomic_yield(void) { asm volatile ("nop" ::: "memory"); }