summaryrefslogtreecommitdiff
path: root/rts/RaiseAsync.c
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2009-12-18 16:32:00 +0000
committerSimon Marlow <marlowsd@gmail.com>2009-12-18 16:32:00 +0000
commit53bf23e5b0ad68264604c9c9da63d15de16da223 (patch)
tree35112f4e4bd167faea6b54d90bfb325cdfba5a77 /rts/RaiseAsync.c
parent5308c0423b613e0d6a22996e2052731f0a371475 (diff)
downloadhaskell-53bf23e5b0ad68264604c9c9da63d15de16da223.tar.gz
Allow throwTo() to be called without a source thread
Returns false if the exception could not be thrown becuase the tartget thread was running. Not used yet, but might come in handy later.
Diffstat (limited to 'rts/RaiseAsync.c')
-rw-r--r--rts/RaiseAsync.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/rts/RaiseAsync.c b/rts/RaiseAsync.c
index c8a38565af..15e6f8f314 100644
--- a/rts/RaiseAsync.c
+++ b/rts/RaiseAsync.c
@@ -143,7 +143,7 @@ suspendComputation(Capability *cap, StgTSO *tso, StgUpdateFrame *stop_here)
nat
throwTo (Capability *cap, // the Capability we hold
- StgTSO *source, // the TSO sending the exception
+ StgTSO *source, // the TSO sending the exception (or NULL)
StgTSO *target, // the TSO receiving the exception
StgClosure *exception, // the exception closure
/*[out]*/ void **out USED_IF_THREADS)
@@ -159,8 +159,13 @@ throwTo (Capability *cap, // the Capability we hold
// ASSERT(get_itbl(target)->type == TSO);
}
- debugTrace(DEBUG_sched, "throwTo: from thread %lu to thread %lu",
- (unsigned long)source->id, (unsigned long)target->id);
+ if (source != NULL) {
+ debugTrace(DEBUG_sched, "throwTo: from thread %lu to thread %lu",
+ (unsigned long)source->id, (unsigned long)target->id);
+ } else {
+ debugTrace(DEBUG_sched, "throwTo: from RTS to thread %lu",
+ (unsigned long)target->id);
+ }
#ifdef DEBUG
traceThreadStatus(DEBUG_sched, target);
@@ -486,14 +491,16 @@ check_target:
static void
blockedThrowTo (Capability *cap, StgTSO *source, StgTSO *target)
{
- debugTrace(DEBUG_sched, "throwTo: blocking on thread %lu", (unsigned long)target->id);
- setTSOLink(cap, source, target->blocked_exceptions);
- target->blocked_exceptions = source;
- dirty_TSO(cap,target); // we modified the blocked_exceptions queue
-
- source->block_info.tso = target;
- write_barrier(); // throwTo_exception *must* be visible if BlockedOnException is.
- source->why_blocked = BlockedOnException;
+ if (source != NULL) {
+ debugTrace(DEBUG_sched, "throwTo: blocking on thread %lu", (unsigned long)target->id);
+ setTSOLink(cap, source, target->blocked_exceptions);
+ target->blocked_exceptions = source;
+ dirty_TSO(cap,target); // we modified the blocked_exceptions queue
+
+ source->block_info.tso = target;
+ write_barrier(); // throwTo_exception *must* be visible if BlockedOnException is.
+ source->why_blocked = BlockedOnException;
+ }
}