diff options
author | GHC GitLab CI <ghc-ci@gitlab-haskell.org> | 2020-11-26 00:10:26 +0000 |
---|---|---|
committer | GHC GitLab CI <ghc-ci@gitlab-haskell.org> | 2020-12-07 15:12:10 +0000 |
commit | 38f2f62729ff7a47001bf5ef00c3b34ec5398999 (patch) | |
tree | 1d5d93aeeb77f14bbc53f7365283e4af8f2533cb | |
parent | ef241371de7c4546b3ad45d7d190965be735f998 (diff) | |
download | haskell-38f2f62729ff7a47001bf5ef00c3b34ec5398999.tar.gz |
rts/Messages: Add missing write barrier in THROWTO message update
After a THROWTO message has been handle the message closure is
overwritten by a NULL message. We must ensure that the original
closure's pointers continue to be visible to the nonmoving GC.
(cherry picked from commit 6c2faf158fd26fc06b03c9bd11b6d2cf8e8db572)
-rw-r--r-- | rts/Messages.c | 2 | ||||
-rw-r--r-- | rts/Messages.h | 10 | ||||
-rw-r--r-- | rts/RaiseAsync.c | 8 |
3 files changed, 14 insertions, 6 deletions
diff --git a/rts/Messages.c b/rts/Messages.c index 0bdeb05aa0..232b266045 100644 --- a/rts/Messages.c +++ b/rts/Messages.c @@ -100,7 +100,7 @@ loop: case THROWTO_SUCCESS: { // this message is done StgTSO *source = t->source; - doneWithMsgThrowTo(t); + doneWithMsgThrowTo(cap, t); tryWakeupThread(cap, source); break; } diff --git a/rts/Messages.h b/rts/Messages.h index 18371564c4..561eb449d2 100644 --- a/rts/Messages.h +++ b/rts/Messages.h @@ -23,8 +23,16 @@ void sendMessage (Capability *from_cap, Capability *to_cap, Message *msg); #include "SMPClosureOps.h" INLINE_HEADER void -doneWithMsgThrowTo (MessageThrowTo *m) +doneWithMsgThrowTo (Capability *cap, MessageThrowTo *m) { + // The message better be locked + ASSERT(m->header.info == &stg_WHITEHOLE_info); + IF_NONMOVING_WRITE_BARRIER_ENABLED { + updateRemembSetPushClosure(cap, (StgClosure *) m->link); + updateRemembSetPushClosure(cap, (StgClosure *) m->source); + updateRemembSetPushClosure(cap, (StgClosure *) m->target); + updateRemembSetPushClosure(cap, (StgClosure *) m->exception); + } OVERWRITING_CLOSURE((StgClosure*)m); unlockClosure((StgClosure*)m, &stg_MSG_NULL_info); LDV_RECORD_CREATE(m); diff --git a/rts/RaiseAsync.c b/rts/RaiseAsync.c index db56a2f68b..751ae5bce4 100644 --- a/rts/RaiseAsync.c +++ b/rts/RaiseAsync.c @@ -336,7 +336,7 @@ check_target: } // nobody else can wake up this TSO after we claim the message - doneWithMsgThrowTo(m); + doneWithMsgThrowTo(cap, m); raiseAsync(cap, target, msg->exception, false, NULL); return THROWTO_SUCCESS; @@ -577,7 +577,7 @@ maybePerformBlockedException (Capability *cap, StgTSO *tso) throwToSingleThreaded(cap, msg->target, msg->exception); source = msg->source; - doneWithMsgThrowTo(msg); + doneWithMsgThrowTo(cap, msg); tryWakeupThread(cap, source); return 1; } @@ -599,7 +599,7 @@ awakenBlockedExceptionQueue (Capability *cap, StgTSO *tso) i = lockClosure((StgClosure *)msg); if (i != &stg_MSG_NULL_info) { source = msg->source; - doneWithMsgThrowTo(msg); + doneWithMsgThrowTo(cap, msg); tryWakeupThread(cap, source); } else { unlockClosure((StgClosure *)msg,i); @@ -696,7 +696,7 @@ removeFromQueues(Capability *cap, StgTSO *tso) // ASSERT(m->header.info == &stg_WHITEHOLE_info); // unlock and revoke it at the same time - doneWithMsgThrowTo(m); + doneWithMsgThrowTo(cap, m); break; } |