diff options
Diffstat (limited to 'includes')
-rw-r--r-- | includes/rts/Constants.h | 9 | ||||
-rw-r--r-- | includes/rts/SpinLock.h | 29 | ||||
-rw-r--r-- | includes/rts/storage/SMPClosureOps.h | 2 |
3 files changed, 27 insertions, 13 deletions
diff --git a/includes/rts/Constants.h b/includes/rts/Constants.h index 0aee60aa83..54a1ca71ca 100644 --- a/includes/rts/Constants.h +++ b/includes/rts/Constants.h @@ -296,4 +296,13 @@ #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 */ diff --git a/includes/rts/SpinLock.h b/includes/rts/SpinLock.h index 3d0b56cfcb..8b337de73f 100644 --- a/includes/rts/SpinLock.h +++ b/includes/rts/SpinLock.h @@ -36,7 +36,6 @@ typedef StgWord SpinLock; typedef lnat SpinLockCount; - #if defined(PROF_SPIN) // PROF_SPIN enables counting the number of times we spin on a lock @@ -45,13 +44,16 @@ typedef lnat SpinLockCount; 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 @@ -75,10 +77,15 @@ INLINE_HEADER void initSpinLock(SpinLock * p) 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 diff --git a/includes/rts/storage/SMPClosureOps.h b/includes/rts/storage/SMPClosureOps.h index d5f7c3f295..582ec0e959 100644 --- a/includes/rts/storage/SMPClosureOps.h +++ b/includes/rts/storage/SMPClosureOps.h @@ -28,8 +28,6 @@ EXTERN_INLINE void unlockClosure(StgClosure *p, const StgInfoTable *info); * 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) |