+/* -----------------------------------------------------------------------------
+ Invariants:
+
+ An active thread has the following properties:
+
+ tso->stack < tso->sp < tso->stack+tso->stack_size
+ tso->stack_size <= tso->max_stack_size
+
+ RESERVED_STACK_WORDS is large enough for any heap-check or
+ stack-check failure.
+
+ The size of the TSO struct plus the stack is either
+ (a) smaller than a block, or
+ (b) a multiple of BLOCK_SIZE
+
+ tso->why_blocked tso->block_info location
+ ----------------------------------------------------------------------
+ NotBlocked NULL runnable_queue, or running
+
+ BlockedOnBlackHole the BLACKHOLE_BQ the BLACKHOLE_BQ's queue
+
+ BlockedOnMVar the MVAR the MVAR's queue
+
+ BlockedOnException the TSO TSO->blocked_exception
+
+ 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