diff options
-rw-r--r-- | rts/Messages.c | 1 | ||||
-rw-r--r-- | rts/StgMiscClosures.cmm | 1 | ||||
-rw-r--r-- | rts/sm/Evac.c | 13 |
3 files changed, 15 insertions, 0 deletions
diff --git a/rts/Messages.c b/rts/Messages.c index a9c794d823..2b13b6306c 100644 --- a/rts/Messages.c +++ b/rts/Messages.c @@ -203,6 +203,7 @@ loop: // just been replaced with an IND by another thread in // updateThunk(). In which case, if we read the indirectee // again we should get the value. + // See Note [BLACKHOLE pointing to IND] in sm/Evac.c goto loop; } diff --git a/rts/StgMiscClosures.cmm b/rts/StgMiscClosures.cmm index 595d3ce6c2..9fd5fb8b88 100644 --- a/rts/StgMiscClosures.cmm +++ b/rts/StgMiscClosures.cmm @@ -302,6 +302,7 @@ retry: // This could happen, if e.g. we got a BLOCKING_QUEUE that has // just been replaced with an IND by another thread in // wakeBlockingQueue(). + // See Note [BLACKHOLE pointing to IND] in sm/Evac.c goto retry; } diff --git a/rts/sm/Evac.c b/rts/sm/Evac.c index 27f280665e..06648c3de9 100644 --- a/rts/sm/Evac.c +++ b/rts/sm/Evac.c @@ -747,6 +747,19 @@ loop: copy(p,info,q,sizeofW(StgInd),gen_no); return; } + // Note [BLACKHOLE pointing to IND] + // + // BLOCKING_QUEUE can be overwritten by IND (see + // wakeBlockingQueue()). However, when this happens we must + // be updating the BLACKHOLE, so the BLACKHOLE's indirectee + // should now point to the value. + // + // The mutator might observe an inconsistent state, because + // the writes are happening in another thread, so it's + // possible for the mutator to follow an indirectee and find + // an IND. But this should never happen in the GC, because + // the mutators are all stopped and the writes have + // completed. ASSERT(i != &stg_IND_info); } q = r; |