#error RESERVED_STACK_WORDS may be wrong!
#endif
+/*
+ * The number of times we spin in a spin lock before yielding (see
+ * #3758). To tune this value, use the benchmark in #3758: run the
+ * server with -N2 and the client both on a dual-core. Also make sure
+ * that the chosen value doesn't slow down any of the parallel
+ * benchmarks in nofib/parallel.
+ */
+#define SPIN_COUNT 1000
+
#endif /* RTS_CONSTANTS_H */
typedef lnat SpinLockCount;
-
#if defined(PROF_SPIN)
// PROF_SPIN enables counting the number of times we spin on a lock
INLINE_HEADER void ACQUIRE_SPIN_LOCK(SpinLock * p)
{
StgWord32 r = 0;
-spin:
- r = cas((StgVolatilePtr)&(p->lock), 1, 0);
- if (r == 0) {
- p->spin++;
- busy_wait_nop();
- goto spin;
- }
+ nat i;
+ do {
+ for (i = 0; i < SPIN_COUNT; i++) {
+ r = cas((StgVolatilePtr)&(p->lock), 1, 0);
+ if (r != 0) return;
+ p->spin++;
+ busy_wait_nop();
+ }
+ yieldThread();
+ } while (1);
}
// release spin lock
INLINE_HEADER void ACQUIRE_SPIN_LOCK(SpinLock * p)
{
StgWord32 r = 0;
+ nat i;
do {
- r = cas((StgVolatilePtr)p, 1, 0);
- busy_wait_nop();
- } while(r == 0);
+ for (i = 0; i < SPIN_COUNT; i++) {
+ r = cas((StgVolatilePtr)p, 1, 0);
+ if (r != 0) return;
+ busy_wait_nop();
+ }
+ yieldThread();
+ } while (1);
}
// release spin lock
* This is used primarily in the implementation of MVars.
* -------------------------------------------------------------------------- */
-#define SPIN_COUNT 4000
-
// We want a callable copy of lockClosure() so that we can refer to it
// from .cmm files compiled using the native codegen.
EXTERN_INLINE StgInfoTable *lockClosure(StgClosure *p)