- /* args: R1 = TSO to kill, R2 = Exception */
-
- W_ why_blocked;
-
- /* This thread may have been relocated.
- * (see Schedule.c:threadStackOverflow)
- */
- while:
- if (StgTSO_what_next(R1) == ThreadRelocated::I16) {
- R1 = StgTSO_link(R1);
- goto while;
- }
-
- /* Determine whether this thread is interruptible or not */
-
- /* If the target thread is currently blocking async exceptions,
- * we'll have to block until it's ready to accept them. The
- * exception is interruptible threads - ie. those that are blocked
- * on some resource.
- */
- why_blocked = TO_W_(StgTSO_why_blocked(R1));
- if (StgTSO_blocked_exceptions(R1) != NULL && !interruptible(why_blocked))
- {
- StgTSO_link(CurrentTSO) = StgTSO_blocked_exceptions(R1);
- StgTSO_blocked_exceptions(R1) = CurrentTSO;
-
- StgTSO_why_blocked(CurrentTSO) = BlockedOnException::I16;
- StgTSO_block_info(CurrentTSO) = R1;
-
- BLOCK( R1_PTR & R2_PTR, killThreadzh_fast );
- }
-
- /* Killed threads turn into zombies, which might be garbage
- * collected at a later date. That's why we don't have to
- * explicitly remove them from any queues they might be on.
- */
-
- /* We might have killed ourselves. In which case, better be *very*
- * careful. If the exception killed us, then return to the scheduler.
- * If the exception went to a catch frame, we'll just continue from
- * the handler.
- */
- if (R1 == CurrentTSO) {
+ /* args: R1 = TSO to kill, R2 = Exception */
+
+ W_ why_blocked;
+ W_ target;
+ W_ exception;
+
+ target = R1;
+ exception = R2;
+
+ STK_CHK_GEN( WDS(3), R1_PTR & R2_PTR, killThreadzh_fast);
+
+ /*
+ * We might have killed ourselves. In which case, better be *very*
+ * careful. If the exception killed us, then return to the scheduler.
+ * If the exception went to a catch frame, we'll just continue from
+ * the handler.
+ */
+ if (target == CurrentTSO) {