Author: Michael R. Crusoe <crusoe@debian.org>
Description: Portable cpuRelax
Forwarded: https://github.com/COMBINE-lab/salmon/pull/547
--- salmon.orig/include/FastxParserThreadUtils.hpp
+++ salmon/include/FastxParserThreadUtils.hpp
@@ -6,6 +6,9 @@
 #include <pthread.h>
 #include <random>
 #include <thread>
+#if defined(__SSE2__)
+#include <xmmintrin.h> // _mm_pause
+#endif
 
 // Most of this code is taken directly from
 // https://github.com/geidav/spinlocks-bench/blob/master/os.hpp. However, things
@@ -18,7 +21,25 @@
 static const constexpr size_t MIN_BACKOFF_ITERS = 32;
 static const size_t MAX_BACKOFF_ITERS = 1024;
 
-ALWAYS_INLINE static void cpuRelax() { asm("pause"); }
+ALWAYS_INLINE static void cpuRelax() {
+#if defined(__SSE2__)  // AMD and Intel
+  _mm_pause();
+#elif defined(__i386__) || defined(__x86_64__)
+  asm volatile("pause");
+#elif defined(__aarch64__)
+  asm volatile("wfe");
+#elif defined(__armel__) || defined(__ARMEL__)
+  asm volatile ("nop" ::: "memory");
+#elif defined(__arm__) || defined(__aarch64__)
+  __asm__ __volatile__ ("yield" ::: "memory");
+#elif defined(__ia64__)  // IA64
+  __asm__ __volatile__ ("hint @pause");
+#elif defined(__powerpc__) || defined(__ppc__) || defined(__PPC__)
+   __asm__ __volatile__ ("or 27,27,27" ::: "memory");
+#else  // everything else.
+   asm volatile ("nop" ::: "memory");
+#endif
+}
 
 ALWAYS_INLINE void yieldSleep() {
   using namespace std::chrono;
