diff options
author | Adam Gundry <adam@well-typed.com> | 2014-11-18 10:17:22 +0000 |
---|---|---|
committer | Adam Gundry <adam@well-typed.com> | 2014-11-18 10:17:22 +0000 |
commit | 7b24febb2afc92289846a1ff7593d9a4ae2b61d1 (patch) | |
tree | 218fb067524582677b40ced852d2c2808885c1df /rts/RaiseAsync.c | |
parent | c0f657fd2549719b2959dbf93fcd744c02427a5c (diff) | |
parent | b9096df6a9733e38e15361e79973ef5659fc5c22 (diff) | |
download | haskell-wip/tc-plugins-amg.tar.gz |
Merge remote-tracking branch 'origin/master' into wip/tc-plugins-amgwip/tc-plugins-amg
Diffstat (limited to 'rts/RaiseAsync.c')
-rw-r--r-- | rts/RaiseAsync.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/rts/RaiseAsync.c b/rts/RaiseAsync.c index 10585c89fa..3b206ffa7e 100644 --- a/rts/RaiseAsync.c +++ b/rts/RaiseAsync.c @@ -89,6 +89,60 @@ suspendComputation (Capability *cap, StgTSO *tso, StgUpdateFrame *stop_here) } /* ----------------------------------------------------------------------------- + throwToSelf + + Useful for throwing an async exception in a thread from the + runtime. It handles unlocking the throwto message returned by + throwTo(). + + Note [Throw to self when masked] + + When a StackOverflow occurs when the thread is masked, we want to + defer the exception to when the thread becomes unmasked/hits an + interruptible point. We already have a mechanism for doing this, + the blocked_exceptions list, but the use here is a bit unusual, + because an exception is normally only added to this list upon + an asynchronous 'throwTo' call (with all of the relevant + multithreaded nonsense). Morally, a stack overflow should be an + asynchronous exception sent by a thread to itself, and it should + have the same semantics. But there are a few key differences: + + - If you actually tried to send an asynchronous exception to + yourself using throwTo, the exception would actually immediately + be delivered. This is because throwTo itself is considered an + interruptible point, so the exception is always deliverable. Thus, + ordinarily, we never end up with a message to onesself in the + blocked_exceptions queue. + + - In the case of a StackOverflow, we don't actually care about the + wakeup semantics; when an exception is delivered, the thread that + originally threw the exception should be woken up, since throwTo + blocks until the exception is successfully thrown. Fortunately, + it is harmless to wakeup a thread that doesn't actually need waking + up, e.g. ourselves. + + - No synchronization is necessary, because we own the TSO and the + capability. You can observe this by tracing through the execution + of throwTo. We skip synchronizing the message and inter-capability + communication. + + We think this doesn't break any invariants, but do be careful! + -------------------------------------------------------------------------- */ + +void +throwToSelf (Capability *cap, StgTSO *tso, StgClosure *exception) +{ + MessageThrowTo *m; + + m = throwTo(cap, tso, tso, exception); + + if (m != NULL) { + // throwTo leaves it locked + unlockClosure((StgClosure*)m, &stg_MSG_THROWTO_info); + } +} + +/* ----------------------------------------------------------------------------- throwTo This function may be used to throw an exception from one thread to |