Fix Trac #2985: generating superclasses and recursive dictionaries
[ghc-hetmet.git] / rts / Sparks.c
index 38a3090..9e4492a 100644 (file)
@@ -44,6 +44,7 @@
 #include "RtsUtils.h"
 #include "ParTicky.h"
 #include "Trace.h"
+#include "Prelude.h"
 
 #include "SMP.h" // for cas
 
@@ -201,11 +202,15 @@ steal(SparkPool *deque)
   StgClosurePtr stolen;
   StgWord b,t; 
 
-  ASSERT_SPARK_POOL_INVARIANTS(deque); 
+// Can't do this on someone else's spark pool:
+// ASSERT_SPARK_POOL_INVARIANTS(deque); 
 
   b = deque->bottom;
   t = deque->top;
-  if (b - t <= 0 ) { 
+
+  // NB. b and t are unsigned; we need a signed value for the test
+  // below.
+  if ((long)b - (long)t <= 0 ) { 
     return NULL; /* already looks empty, abort */
   }
 
@@ -221,14 +226,17 @@ steal(SparkPool *deque)
       return NULL;
   }  /* else: OK, top has been incremented by the cas call */
 
-  ASSERT_SPARK_POOL_INVARIANTS(deque); 
+// Can't do this on someone else's spark pool:
+// ASSERT_SPARK_POOL_INVARIANTS(deque); 
+
   /* return stolen element */
   return stolen;
 }
 
 StgClosure *
-tryStealSpark (SparkPool *pool)
+tryStealSpark (Capability *cap)
 {
+  SparkPool *pool = cap->sparks;
   StgClosure *stolen;
 
   do { 
@@ -253,7 +261,7 @@ looksEmpty(SparkPool* deque)
   StgWord t = deque->top;
   StgWord b = deque->bottom;
   /* try to prefer false negatives by reading top first */
-  return (b - t <= 0);
+  return ((long)b - (long)t <= 0);
   /* => array is *never* completely filled, always 1 place free! */
 }
 
@@ -264,13 +272,13 @@ looksEmpty(SparkPool* deque)
  * -------------------------------------------------------------------------- */
 
 void
-createSparkThread (Capability *cap, StgClosure *p)
+createSparkThread (Capability *cap)
 {
     StgTSO *tso;
 
-    tso = createGenThread (cap, RtsFlags.GcFlags.initialStkSize, p);
+    tso = createIOThread (cap, RtsFlags.GcFlags.initialStkSize, 
+                          &base_GHCziConc_runSparks_closure);
     appendToRunQueue(cap,tso);
-    cap->sparks_converted++;
 }
 
 /* -----------------------------------------------------------------------------
@@ -298,7 +306,10 @@ pushBottom (SparkPool* deque, StgClosurePtr elem)
      This is why we do not just call empty(deque) here.
   */
   t = deque->topBound;
-  if ( b - t >= sz ) { /* nota bene: sz == deque->size - 1, thus ">=" */
+  if ( (StgInt)b - (StgInt)t >= (StgInt)sz ) { 
+    /* NB. 1. sz == deque->size - 1, thus ">="
+           2. signed comparison, it is possible that t > b
+    */
     /* could be full, check the real top value in this case */
     t = deque->top;
     deque->topBound = t;
@@ -387,6 +398,12 @@ pruneSparkQueue (evac_fn evac, void *user, Capability *cap)
     
     pool = cap->sparks;
     
+    // it is possible that top > bottom, indicating an empty pool.  We
+    // fix that here; this is only necessary because the loop below
+    // assumes it.
+    if (pool->top > pool->bottom)
+        pool->top = pool->bottom;
+
     // Take this opportunity to reset top/bottom modulo the size of
     // the array, to avoid overflow.  This is only possible because no
     // stealing is happening during GC.