X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2FSparks.c;h=9e4492ac1925c66b4fe942d8a6480671200d4aac;hb=dd3d9333b2e2f6a0959bb4aebbad5bf23e968fb6;hp=e7273f3ed0167ff1bf7d16daaef2328759f35097;hpb=2b16fa4791b08b02df8461f3b79d0e44d72d0960;p=ghc-hetmet.git diff --git a/rts/Sparks.c b/rts/Sparks.c index e7273f3..9e4492a 100644 --- a/rts/Sparks.c +++ b/rts/Sparks.c @@ -202,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 */ } @@ -222,7 +226,9 @@ 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; } @@ -255,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! */ } @@ -300,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; @@ -389,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.