/* -----------------------------------------------------------------------------
- * $Id: Exception.hc,v 1.7 2000/02/04 11:15:04 simonmar Exp $
+ * $Id: Exception.hc,v 1.14 2000/05/25 09:16:56 simonmar Exp $
*
* (c) The GHC Team, 1998-1999
*
#if defined(PAR)
# include "FetchMe.h"
#endif
+#if defined(PROFILING)
+# include "Profiling.h"
+#endif
/* -----------------------------------------------------------------------------
Exception Primitives
awakenBlockedQueue(CurrentTSO->blocked_exceptions);
#endif
CurrentTSO->blocked_exceptions = NULL;
+#ifdef REG_R1
Sp++;
JMP_(ENTRY_CODE(Sp[0]));
+#else
+ Sp[1] = Sp[0];
+ Sp++;
+ JMP_(ENTRY_CODE(Sp[1]));
+#endif
FE_
}
FB_
ASSERT(CurrentTSO->blocked_exceptions == NULL);
CurrentTSO->blocked_exceptions = END_TSO_QUEUE;
+#ifdef REG_R1
Sp++;
JMP_(ENTRY_CODE(Sp[0]));
+#else
+ Sp[1] = Sp[0];
+ Sp++;
+ JMP_(ENTRY_CODE(Sp[1]));
+#endif
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_
}
* It is used in raisezh_fast to update thunks on the update list
* -------------------------------------------------------------------------- */
-INFO_TABLE(raise_info,raise_entry,1,0,FUN,,EF_,0,0);
+INFO_TABLE(raise_info,raise_entry,1,0,THUNK,,EF_,0,0);
STGFUN(raise_entry)
{
FB_
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");
}