X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=includes%2Frts%2FSpinLock.h;h=8b337de73fd19ef89db5ab8793fff1ed73af26e5;hb=ad3b79d22b32760f25bf10069bd2957462be959d;hp=ea992a3457153edee9fc132f10fe5ebe058ff66a;hpb=a2a67cd520b9841114d69a87a423dabcb3b4368e;p=ghc-hetmet.git diff --git a/includes/rts/SpinLock.h b/includes/rts/SpinLock.h index ea992a3..8b337de 100644 --- a/includes/rts/SpinLock.h +++ b/includes/rts/SpinLock.h @@ -1,6 +1,6 @@ /* ---------------------------------------------------------------------------- * - * (c) The GHC Team, 2006-2008 + * (c) The GHC Team, 2006-2009 * * Spin locks * @@ -12,6 +12,11 @@ * TODO: measure whether we really need these, or whether Mutexes * would do (and be a bit safer if a CPU becomes loaded). * + * Do not #include this file directly: #include "Rts.h" instead. + * + * To understand the structure of the RTS headers, see the wiki: + * http://hackage.haskell.org/trac/ghc/wiki/Commentary/SourceTree/Includes + * * -------------------------------------------------------------------------- */ #ifndef RTS_SPINLOCK_H @@ -31,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 @@ -40,12 +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++; - 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 @@ -69,9 +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); - } 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