This helps on a hyperthreaded CPU by yielding to the other thread in a
spinlock loop.
r = cas((StgVolatilePtr)&(p->lock), 1, 0);
if (r == 0) {
p->spin++;
+ busy_wait_nop();
goto spin;
}
}
StgWord32 r = 0;
do {
r = cas((StgVolatilePtr)p, 1, 0);
+ busy_wait_nop();
} while(r == 0);
}
*/
EXTERN_INLINE StgWord atomic_dec(StgVolatilePtr p);
+/*
+ * Busy-wait nop: this is a hint to the CPU that we are currently in a
+ * busy-wait loop waiting for another CPU to change something. On a
+ * hypertreaded CPU it should yield to another thread, for example.
+ */
+EXTERN_INLINE void busy_wait_nop(void);
+
#endif // !IN_STG_CODE
/*
#endif
}
+EXTERN_INLINE void
+busy_wait_nop(void)
+{
+#if defined(i386_HOST_ARCH) || defined(x86_64_HOST_ARCH)
+ __asm__ __volatile__ ("rep; nop");
+ //
+#else
+ // nothing
+#endif
+}
+
#endif // !IN_STG_CODE
/*