summaryrefslogtreecommitdiff
path: root/rts/RaiseAsync.c
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2014-10-15 00:03:15 +0100
committerSimon Marlow <marlowsd@gmail.com>2014-11-12 15:11:10 +0000
commitd70b19bfb5ed79b22c2ac31e22f46782fc47a117 (patch)
treed7bc2ad5a6d50bf351dfd97779030dae63e5d7cf /rts/RaiseAsync.c
parentc774b28f76ee4c220f7c1c9fd81585e0e3af0e8a (diff)
downloadhaskell-d70b19bfb5ed79b22c2ac31e22f46782fc47a117.tar.gz
Per-thread allocation counters and limits
This reverts commit f0fcc41d755876a1b02d1c7c79f57515059f6417. New changes: now works on 32-bit platforms too. I added some basic support for 64-bit subtraction and comparison operations to the x86 NCG.
Diffstat (limited to 'rts/RaiseAsync.c')
-rw-r--r--rts/RaiseAsync.c54
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