+/* Spark pools: used to store pending sparks
+ * (THREADED_RTS & PARALLEL_HASKELL only)
+ * Implementation uses a DeQue to enable concurrent read accesses at
+ * the top end.
+ */
+typedef struct SparkPool_ {
+ /* Size of elements array. Used for modulo calculation: we round up
+ to powers of 2 and use the dyadic log (modulo == bitwise &) */
+ StgWord size;
+ StgWord moduloSize; /* bitmask for modulo */
+
+ /* top, index where multiple readers steal() (protected by a cas) */
+ volatile StgWord top;
+
+ /* bottom, index of next free place where one writer can push
+ elements. This happens unsynchronised. */
+ volatile StgWord bottom;
+ /* both position indices are continuously incremented, and used as
+ an index modulo the current array size. */
+
+ /* lower bound on the current top value. This is an internal
+ optimisation to avoid unnecessarily accessing the top field
+ inside pushBottom */
+ volatile StgWord topBound;
+
+ /* The elements array */
+ StgClosurePtr* elements;
+ /* Please note: the dataspace cannot follow the admin fields
+ immediately, as it should be possible to enlarge it without
+ disposing the old one automatically (as realloc would)! */
+
+} SparkPool;
+
+
+/* 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).
+*/