diff options
author | Simon Marlow <marlowsd@gmail.com> | 2009-12-18 16:32:00 +0000 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2009-12-18 16:32:00 +0000 |
commit | 53bf23e5b0ad68264604c9c9da63d15de16da223 (patch) | |
tree | 35112f4e4bd167faea6b54d90bfb325cdfba5a77 /rts/RaiseAsync.c | |
parent | 5308c0423b613e0d6a22996e2052731f0a371475 (diff) | |
download | haskell-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.c | 29 |
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; + } } |