/* ----------------------------------------------------------------------------
*
- * (c) The GHC Team, 2006-2008
+ * (c) The GHC Team, 2006-2009
*
* Spin locks
*
* 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
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++;
- 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);
- } 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