Add handling for | to the transitional alternative layout rule
[ghc-hetmet.git] / includes / rts / SpinLock.h
index ea992a3..8b337de 100644 (file)
@@ -1,6 +1,6 @@
 /* ----------------------------------------------------------------------------
  *
- * (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
@@ -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