X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=rts%2FRaiseAsync.c;h=d562e33680c278c3eb44899db498409d3e2c88aa;hp=4a405e7b4909f23511e822873c50e3184670fe26;hb=9d03becc597e5b1ab6c8466209a1263bf8ba6f29;hpb=ab0e778ccfde61aed4c22679b24d175fc6cc9bf3 diff --git a/rts/RaiseAsync.c b/rts/RaiseAsync.c index 4a405e7..d562e33 100644 --- a/rts/RaiseAsync.c +++ b/rts/RaiseAsync.c @@ -12,12 +12,12 @@ #include "Trace.h" #include "RaiseAsync.h" #include "SMP.h" -#include "Storage.h" #include "Schedule.h" #include "LdvProfile.h" #include "Updates.h" #include "STM.h" #include "Sanity.h" +#include "Profiling.h" #if defined(mingw32_HOST_OS) #include "win32/IOManager.h" #endif @@ -283,7 +283,13 @@ check_target: // ASSUMPTION: tso->block_info must always point to a // closure. In the threaded RTS it does. - if (get_itbl(mvar)->type != MVAR) goto retry; + switch (get_itbl(mvar)->type) { + case MVAR_CLEAN: + case MVAR_DIRTY: + break; + default: + goto retry; + } info = lockClosure((StgClosure *)mvar); @@ -497,9 +503,11 @@ throwToReleaseTarget (void *tso) queue, but not perform any throwTo() immediately. This might be more appropriate when the target thread is the one actually running (see Exception.cmm). + + Returns: non-zero if an exception was raised, zero otherwise. -------------------------------------------------------------------------- */ -void +int maybePerformBlockedException (Capability *cap, StgTSO *tso) { StgTSO *source; @@ -515,7 +523,7 @@ maybePerformBlockedException (Capability *cap, StgTSO *tso) // locked it. if (tso->blocked_exceptions == END_TSO_QUEUE) { unlockTSO(tso); - return; + return 0; } // We unblock just the first thread on the queue, and perform @@ -525,7 +533,9 @@ maybePerformBlockedException (Capability *cap, StgTSO *tso) tso->blocked_exceptions = unblockOne_(cap, source, rtsFalse/*no migrate*/); unlockTSO(tso); + return 1; } + return 0; } void @@ -705,7 +715,7 @@ removeFromQueues(Capability *cap, StgTSO *tso) } default: - barf("removeFromQueues"); + barf("removeFromQueues: %d", tso->why_blocked); } done: @@ -778,7 +788,7 @@ removeFromQueues(Capability *cap, StgTSO *tso) #endif default: - barf("removeFromQueues"); + barf("removeFromQueues: %d", tso->why_blocked); } done: @@ -843,6 +853,18 @@ raiseAsync(Capability *cap, StgTSO *tso, StgClosure *exception, debugTrace(DEBUG_sched, "raising exception in thread %ld.", (long)tso->id); +#if defined(PROFILING) + /* + * Debugging tool: on raising an exception, show where we are. + * See also Exception.cmm:raisezh_fast. + * This wasn't done for asynchronous exceptions originally; see #1450 + */ + if (RtsFlags.ProfFlags.showCCSOnException) + { + fprintCCS_stderr(tso->prof.CCCS); + } +#endif + // mark it dirty; we're about to change its stack. dirtyTSO(tso); @@ -939,10 +961,12 @@ raiseAsync(Capability *cap, StgTSO *tso, StgClosure *exception, } case STOP_FRAME: + { // We've stripped the entire stack, the thread is now dead. tso->what_next = ThreadKilled; tso->sp = frame + sizeofW(StgStopFrame); return; + } case CATCH_FRAME: // If we find a CATCH_FRAME, and we've got an exception to raise, @@ -1014,15 +1038,17 @@ raiseAsync(Capability *cap, StgTSO *tso, StgClosure *exception, // whether the transaction is valid or not because its // possible validity cannot have caused the exception // and will not be visible after the abort. - debugTrace(DEBUG_stm, - "found atomically block delivering async exception"); + { StgTRecHeader *trec = tso -> trec; StgTRecHeader *outer = stmGetEnclosingTRec(trec); + debugTrace(DEBUG_stm, + "found atomically block delivering async exception"); stmAbortTransaction(cap, trec); stmFreeAbortedTRec(cap, trec); tso -> trec = outer; break; + }; default: break;