} SparkPool;
-/* INVARIANTS, in this order: bottom/top consistent, reasonable size,
- topBound consistent, space pointer, space accessible to us */
+/* INVARIANTS, in this order: reasonable size,
+ topBound consistent, space pointer, space accessible to us.
+
+ NB. This is safe to use only (a) on a spark pool owned by the
+ current thread, or (b) when there's only one thread running, or no
+ stealing going on (e.g. during GC).
+*/
#define ASSERT_SPARK_POOL_INVARIANTS(p) \
- ASSERT((p)->bottom >= (p)->top); \
ASSERT((p)->size > 0); \
- ASSERT((p)->size > (p)->bottom - (p)->top); \
ASSERT((p)->topBound <= (p)->top); \
ASSERT((p)->elements != NULL); \
ASSERT(*((p)->elements) || 1); \
ASSERT(*((p)->elements - 1 + ((p)->size)) || 1);
+// No: it is possible that top > bottom when using reclaimSpark()
+// ASSERT((p)->bottom >= (p)->top);
+// ASSERT((p)->size > (p)->bottom - (p)->top);
+
// Initialisation
void initSparkPools (void);
// if the pool is almost empty).
rtsBool looksEmpty(SparkPool* deque);
-StgClosure * tryStealSpark (SparkPool *pool);
+StgClosure * tryStealSpark (Capability *cap);
void freeSparkPool (SparkPool *pool);
-void createSparkThread (Capability *cap, StgClosure *p);
+void createSparkThread (Capability *cap);
void traverseSparkQueue(evac_fn evac, void *user, Capability *cap);
void pruneSparkQueue (evac_fn evac, void *user, Capability *cap);
INLINE_HEADER void
discardSparks (SparkPool *pool)
{
- pool->top = pool->topBound = pool->bottom = 0;
+ pool->top = pool->bottom;
+// pool->topBound = pool->top;
}
#endif