/* -----------------------------------------------------------------------------
- * $Id: Exception.hc,v 1.8 2000/02/24 17:20:46 simonmar Exp $
+ * $Id: Exception.hc,v 1.13 2000/04/26 09:44:18 simonmar Exp $
*
* (c) The GHC Team, 1998-1999
*
#if defined(PAR)
# include "FetchMe.h"
#endif
+#if defined(PROFILING)
+# include "Profiling.h"
+#endif
/* -----------------------------------------------------------------------------
Exception Primitives
FE_
}
-
FN_(killThreadzh_fast)
{
FB_
/* This thread may have been relocated.
* (see Schedule.c:threadStackOverflow)
*/
- while (R1.t->whatNext == ThreadRelocated) {
+ while (R1.t->what_next == ThreadRelocated) {
R1.t = R1.t->link;
}
/* If the target thread is currently blocking async exceptions,
- * we'll have to block until it's ready to accept them.
+ * 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.
*/
- if (R1.t->blocked_exceptions != NULL) {
-
- /* ToDo (SMP): locking if destination thread is currently
- * running...
- */
- CurrentTSO->link = R1.t->blocked_exceptions;
- R1.t->blocked_exceptions = CurrentTSO;
-
- CurrentTSO->why_blocked = BlockedOnException;
- CurrentTSO->block_info.tso = R1.t;
+ if (R1.t->blocked_exceptions != NULL && !interruptible(R1.t) ) {
+
+ /* ToDo (SMP): locking if destination thread is currently
+ * running...
+ */
+ CurrentTSO->link = R1.t->blocked_exceptions;
+ R1.t->blocked_exceptions = CurrentTSO;
- BLOCK( R1_PTR | R2_PTR, killThreadzh_fast );
+ CurrentTSO->why_blocked = BlockedOnException;
+ CurrentTSO->block_info.tso = R1.t;
+
+ BLOCK( R1_PTR | R2_PTR, killThreadzh_fast );
}
/* Killed threads turn into zombies, which might be garbage
if (R1.t == CurrentTSO) {
SaveThreadState(); /* inline! */
STGCALL2(raiseAsync, R1.t, R2.cl);
- if (CurrentTSO->whatNext == ThreadKilled) {
- R1.w = ThreadYielding;
+ if (CurrentTSO->what_next == ThreadKilled) {
+ R1.w = ThreadFinished;
JMP_(StgReturn);
}
LoadThreadState();
- if (CurrentTSO->whatNext == ThreadEnterGHC) {
+ if (CurrentTSO->what_next == ThreadEnterGHC) {
R1.w = Sp[0];
Sp++;
JMP_(GET_ENTRY(R1.cl));
STGFUN(catch_entry)
{
FB_
- R2.cl = payloadCPtr(R1.cl,1); /* h */
- R1.cl = payloadCPtr(R1.cl,0); /* x */
+ R2.cl = R1.cl->payload[1]; /* h */
+ R1.cl = R1.cl->payload[0]; /* x */
JMP_(catchzh_fast);
FE_
}
StgUpdateFrame *p;
StgClosure *raise_closure;
FB_
- /* args : R1 = error */
+ /* args : R1 = exception */
#if defined(PROFILING)
break;
case STOP_FRAME:
- barf("raisezh_fast: STOP_FRAME");
-
+ /* We've stripped the entire stack, the thread is now dead. */
+ Sp = CurrentTSO->stack + CurrentTSO->stack_size - 1;
+ Sp[0] = R1.w; /* save the exception */
+ Su = (StgUpdateFrame *)(Sp+1);
+ CurrentTSO->what_next = ThreadKilled;
+ SaveThreadState(); /* inline! */
+ R1.w = ThreadFinished;
+ JMP_(StgReturn);
+
default:
barf("raisezh_fast: weird activation record");
}