+ BlockedOnRead NULL blocked_queue
+ BlockedOnWrite NULL blocked_queue
+ BlockedOnDelay NULL blocked_queue
+ BlockedOnGA closure TSO blocks on BQ of that closure
+ BlockedOnGA_NoSend closure TSO blocks on BQ of that closure
+
+ tso->link == END_TSO_QUEUE, if the thread is currently running.
+
+ A zombie thread has the following properties:
+
+ tso->what_next == ThreadComplete or ThreadKilled
+ tso->link == (could be on some queue somewhere)
+ tso->su == tso->stack + tso->stack_size
+ tso->sp == tso->stack + tso->stack_size - 1 (i.e. top stack word)
+ tso->sp[0] == return value of thread, if what_next == ThreadComplete,
+ exception , if what_next == ThreadKilled
+
+ (tso->sp is left pointing at the top word on the stack so that
+ the return value or exception will be retained by a GC).
+
+ tso->blocked_exceptions is either:
+
+ NULL if async exceptions are unblocked.
+
+ END_TSO_QUEUE if async exceptions are blocked, but no threads
+ are currently waiting to deliver.
+
+ (StgTSO *)tso if threads are currently awaiting delivery of
+ exceptions to this thread.
+
+ The 2 cases BlockedOnGA and BlockedOnGA_NoSend are needed in a GUM
+ setup only. They mark a TSO that has entered a FETCH_ME or
+ FETCH_ME_BQ closure, respectively; only the first TSO hitting the
+ closure will send a Fetch message.
+ Currently we have no separate code for blocking on an RBH; we use the
+ BlockedOnBlackHole case for that. -- HWL
+
+ ---------------------------------------------------------------------------- */