1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
|
Subject: Restricts cpu yield instructions a little.
Forwarded: https://github.com/microsoft/mimalloc/pull/350
From: Ryan Pavlik <ryan.pavlik@collabora.com>
Last-Update: 2021-02-11
Applied-Upstream: 3.0.0, https://github.com/solvespace/solvespace/commit/cdeb6c90fb753a2b0f6d033affedbcceab046758
adding clobber for ARM and preventing older 32 bits chips not supporting this instruction.
Backport of https://github.com/microsoft/mimalloc/commit/33a10b48605f8bb419487a03125815ad6ee00a70
Enhanced via https://github.com/mr-c/misc/wiki/pause-techniques-on-many-architectures
---
extlib/mimalloc/include/mimalloc-atomic.h | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
--- solvespace.orig/extlib/mimalloc/include/mimalloc-atomic.h
+++ solvespace/extlib/mimalloc/include/mimalloc-atomic.h
@@ -266,17 +266,37 @@
static inline void mi_atomic_yield(void) {
std::this_thread::yield();
}
-#elif (defined(__GNUC__) || defined(__clang__)) && \
- (defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__))
-#if defined(__x86_64__) || defined(__i386__)
+#elif defined(__SSE2__) // AMD and Intel
+ #include <emmintrin.h>
+ static inline void mi_atomic_yield(void) {
+ _mm_pause();
+ }
+#elif defined(__x86_64__) || defined(__i386__)
static inline void mi_atomic_yield(void) {
asm volatile ("pause" ::: "memory");
}
-#elif defined(__arm__) || defined(__aarch64__)
+#elif defined(__aarch64__)
+ 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");
+ }
+#elif defined(__armel__) || defined(__ARMEL__)
+ static inline void mi_atomic_yield(void) {
+ asm volatile ("nop" ::: "memory"); // default operation - does nothing => Might lead to passive spinning.
+ }
+#elif defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) // PowerPC
+ static inline void mi_atomic_yield(void) {
+ __asm__ __volatile__ ("or 27,27,27" ::: "memory");
+ }
+#elif defined(__sun)
+ // Fallback for other archs
+ #include <synch.h>
static inline void mi_atomic_yield(void) {
- asm volatile("yield");
+ smt_pause();
}
-#endif
#elif defined(__wasi__)
#include <sched.h>
static inline void mi_atomic_yield(void) {
|