diff --git a/ghc/includes/TSO.h b/ghc/includes/TSO.h index ce46e00c9a22f3e3d62d135e7a117b47afbbfd22..2b81f7613541ee772f067fdb2b771ca5dd9f1abd 100644 --- a/ghc/includes/TSO.h +++ b/ghc/includes/TSO.h @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $Id: TSO.h,v 1.10 2000/01/13 14:34:01 hwloidl Exp $ + * $Id: TSO.h,v 1.11 2000/01/22 18:00:03 simonmar Exp $ * * (c) The GHC Team, 1998-1999 * @@ -71,12 +71,16 @@ typedef enum { tso_state_stopped } StgTSOState; +/* + * The whatNext field of a TSO indicates how the thread is to be run. + */ typedef enum { - ThreadEnterGHC, - ThreadRunGHC, - ThreadEnterHugs, - ThreadKilled, - ThreadComplete + ThreadEnterGHC, /* enter top thunk on stack */ + ThreadRunGHC, /* return to address on top of stack */ + ThreadEnterHugs, /* enter top thunk on stack (w/ interpreter) */ + ThreadKilled, /* thread has died, don't run it */ + ThreadRelocated, /* thread has moved, link points to new locn */ + ThreadComplete /* thread has finished */ } StgTSOWhatNext; /* diff --git a/ghc/rts/Exception.hc b/ghc/rts/Exception.hc index d74ecec4160e9076e8fc005235b179a663289b8d..ce7ba7a3ef91440cd36fce3414884f4eae203b39 100644 --- a/ghc/rts/Exception.hc +++ b/ghc/rts/Exception.hc @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $Id: Exception.hc,v 1.4 2000/01/14 11:45:21 hwloidl Exp $ + * $Id: Exception.hc,v 1.5 2000/01/22 18:00:03 simonmar Exp $ * * (c) The GHC Team, 1998-1999 * @@ -51,8 +51,11 @@ FN_(blockAsyncExceptionszh_fast) if (CurrentTSO->blocked_exceptions == NULL) { CurrentTSO->blocked_exceptions = END_TSO_QUEUE; - Sp--; - Sp[0] = (W_)&unblockAsyncExceptionszh_ret_info; + /* avoid growing the stack unnecessarily */ + if (Sp[0] != (W_)&blockAsyncExceptionszh_ret_info) { + Sp--; + Sp[0] = (W_)&blockAsyncExceptionszh_ret_info; + } } Sp--; Sp[0] = ARG_TAG(0); @@ -101,8 +104,12 @@ FN_(unblockAsyncExceptionszh_fast) awakenBlockedQueue(CurrentTSO->blocked_exceptions); #endif CurrentTSO->blocked_exceptions = NULL; - Sp--; - Sp[0] = (W_)&blockAsyncExceptionszh_ret_info; + + /* avoid growing the stack unnecessarily */ + if (Sp[0] != (W_)&blockAsyncExceptionszh_ret_info) { + Sp--; + Sp[0] = (W_)&blockAsyncExceptionszh_ret_info; + } } Sp--; Sp[0] = ARG_TAG(0); @@ -127,6 +134,13 @@ FN_(killThreadzh_fast) FB_ /* args: R1.p = TSO to kill, R2.p = Exception */ + /* This thread may have been relocated. + * (see Schedule.c:threadStackOverflow) + */ + while (R1.t->whatNext == 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. */ diff --git a/ghc/rts/GC.c b/ghc/rts/GC.c index 02f76afacf82ae110c3a9346c127f8119f886287..acb122fad6d336e34a37be9808f77428816aab58 100644 --- a/ghc/rts/GC.c +++ b/ghc/rts/GC.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $Id: GC.c,v 1.71 2000/01/14 14:55:03 simonmar Exp $ + * $Id: GC.c,v 1.72 2000/01/22 18:00:03 simonmar Exp $ * * (c) The GHC Team 1998-1999 * @@ -933,7 +933,6 @@ isAlive(StgClosure *p) StgClosure * MarkRoot(StgClosure *root) { - //if (root != END_TSO_QUEUE) return evacuate(root); } @@ -1490,10 +1489,17 @@ loop: case TSO: { - StgTSO *tso = stgCast(StgTSO *,q); + StgTSO *tso = (StgTSO *)q; nat size = tso_sizeW(tso); int diff; + /* Deal with redirected TSOs (a TSO that's had its stack enlarged). + */ + if (tso->whatNext == ThreadRelocated) { + q = (StgClosure *)tso->link; + goto loop; + } + /* Large TSOs don't get moved, so no relocation is required. */ if (size >= LARGE_OBJECT_THRESHOLD/sizeof(W_)) { diff --git a/ghc/rts/Schedule.c b/ghc/rts/Schedule.c index 37eeda944af856173a1fb0bbd921adf982c76b58..88a66d833bf7573dd76c059f08bdfc2e10267cbf 100644 --- a/ghc/rts/Schedule.c +++ b/ghc/rts/Schedule.c @@ -1,5 +1,5 @@ /* --------------------------------------------------------------------------- - * $Id: Schedule.c,v 1.44 2000/01/14 13:39:59 simonmar Exp $ + * $Id: Schedule.c,v 1.45 2000/01/22 18:00:03 simonmar Exp $ * * (c) The GHC Team, 1998-1999 * @@ -697,13 +697,15 @@ schedule( void ) /* This TSO has moved, so update any pointers to it from the * main thread stack. It better not be on any other queues... - * (it shouldn't be) + * (it shouldn't be). */ for (m = main_threads; m != NULL; m = m->link) { if (m->tso == t) { m->tso = new_t; } } + ready_to_gc = rtsTrue; + context_switch = 1; PUSH_ON_RUN_QUEUE(new_t); } break; @@ -1583,9 +1585,10 @@ performGCWithRoots(void (*get_roots)(void)) /* ----------------------------------------------------------------------------- Stack overflow - If the thread has reached its maximum stack size, - then bomb out. Otherwise relocate the TSO into a larger chunk of - memory and adjust its stack size appropriately. + If the thread has reached its maximum stack size, then raise the + StackOverflow exception in the offending thread. Otherwise + relocate the TSO into a larger chunk of memory and adjust its stack + size appropriately. -------------------------------------------------------------------------- */ static StgTSO * @@ -1642,14 +1645,15 @@ threadStackOverflow(StgTSO *tso) /* and relocate the update frame list */ relocate_TSO(tso, dest); - /* Mark the old one as dead so we don't try to scavenge it during - * garbage collection (the TSO will likely be on a mutables list in - * some generation, but it'll get collected soon enough). It's - * important to set the sp and su values to just beyond the end of - * the stack, so we don't attempt to scavenge any part of the dead - * TSO's stack. + /* Mark the old TSO as relocated. We have to check for relocated + * TSOs in the garbage collector and any primops that deal with TSOs. + * + * It's important to set the sp and su values to just beyond the end + * of the stack, so we don't attempt to scavenge any part of the + * dead TSO's stack. */ - tso->whatNext = ThreadKilled; + tso->whatNext = ThreadRelocated; + tso->link = dest; tso->sp = (P_)&(tso->stack[tso->stack_size]); tso->su = (StgUpdateFrame *)tso->sp; tso->why_blocked = NotBlocked; @@ -1660,12 +1664,6 @@ threadStackOverflow(StgTSO *tso) IF_DEBUG(scheduler,printTSO(dest)); #endif -#if 0 - /* This will no longer work: KH */ - if (tso == MainTSO) { /* hack */ - MainTSO = dest; - } -#endif return dest; }