X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2Fsm%2FMarkWeak.c;h=455b58628947116ce4f1cf60fc8552e4c8e33f27;hb=53a442f10d80cd85b33620a023c4a8749a7c0b20;hp=0042dbdeabbb79e4bb1e8956f314cbf92b082b89;hpb=ab0e778ccfde61aed4c22679b24d175fc6cc9bf3;p=ghc-hetmet.git diff --git a/rts/sm/MarkWeak.c b/rts/sm/MarkWeak.c index 0042dbd..455b586 100644 --- a/rts/sm/MarkWeak.c +++ b/rts/sm/MarkWeak.c @@ -4,6 +4,11 @@ * * Weak pointers and weak-like things in the GC * + * Documentation on the architecture of the Garbage Collector can be + * found in the online commentary: + * + * http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Storage/GC + * * ---------------------------------------------------------------------------*/ #include "Rts.h" @@ -279,17 +284,26 @@ traverseBlackholeQueue (void) { StgTSO *prev, *t, *tmp; rtsBool flag; + nat type; flag = rtsFalse; prev = NULL; for (t = blackhole_queue; t != END_TSO_QUEUE; prev=t, t = t->link) { + // if the thread is not yet alive... if (! (tmp = (StgTSO *)isAlive((StgClosure*)t))) { - if (isAlive(t->block_info.closure)) { - t = (StgTSO *)evacuate((StgClosure *)t); - if (prev) prev->link = t; - flag = rtsTrue; - } + // if the closure it is blocked on is either (a) a + // reachable BLAKCHOLE or (b) not a BLACKHOLE, then we + // make the thread alive. + if (!isAlive(t->block_info.closure)) { + type = get_itbl(t->block_info.closure)->type; + if (type == BLACKHOLE || type == CAF_BLACKHOLE) { + continue; + } + } + t = (StgTSO *)evacuate((StgClosure *)t); + if (prev) prev->link = t; + flag = rtsTrue; } } return flag;