summaryrefslogtreecommitdiff
path: root/rts/sm
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2014-10-23 11:12:16 +0100
committerSimon Marlow <marlowsd@gmail.com>2014-10-23 11:12:16 +0100
commita11f71eff15ba2706cbb2ee29aaf7350909e0d2f (patch)
treeee6d16f4e4ca1baad4114e50a5b12e8f4aa656ce /rts/sm
parentaa641e514821514e76a07d03f3783b94f819f085 (diff)
downloadhaskell-a11f71eff15ba2706cbb2ee29aaf7350909e0d2f.tar.gz
Fix a rare parallel GC bug
When there's a conflict between two threads evacuating the same TSO, in some cases we would update the incall->tso pointer to point to the wrong copy of the TSO. This would get fixed during the next GC, but if the thread completed in the meantime, it would likely crash. We're seeing this about once per day on a heavily loaded machine (it varies a lot though).
Diffstat (limited to 'rts/sm')
-rw-r--r--rts/sm/Scav.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/rts/sm/Scav.c b/rts/sm/Scav.c
index 1abaefb317..97c65897f5 100644
--- a/rts/sm/Scav.c
+++ b/rts/sm/Scav.c
@@ -55,7 +55,12 @@ scavengeTSO (StgTSO *tso)
// update the pointer from the InCall.
if (tso->bound != NULL) {
- tso->bound->tso = tso;
+ // NB. We can't just set tso->bound->tso = tso, because this
+ // might be an invalid copy the TSO resulting from multiple
+ // threads evacuating the TSO simultaneously (see
+ // Evac.c:copy_tag()). Calling evacuate() on this pointer
+ // will ensure that we update it to point to the correct copy.
+ evacuate((StgClosure **)&tso->bound->tso);
}
saved_eager = gct->eager_promotion;