Added comments: https://phabricator.haskell.org/D4517
On 20 March 2018 at 14:58, Simon Marlow <[email protected]> wrote: > Hi Omer, > > On 20 March 2018 at 13:05, Ömer Sinan Ağacan <[email protected]> wrote: > >> Hi, >> >> I've been looking at BLACKHOLE closures and how the indirectee field is >> used >> and I have a few questions: >> >> Looking at evacuate for BLACKHOLE closures: >> >> case BLACKHOLE: >> { >> StgClosure *r; >> const StgInfoTable *i; >> r = ((StgInd*)q)->indirectee; >> if (GET_CLOSURE_TAG(r) == 0) { >> i = r->header.info; >> if (IS_FORWARDING_PTR(i)) { >> r = (StgClosure *)UN_FORWARDING_PTR(i); >> i = r->header.info; >> } >> if (i == &stg_TSO_info >> || i == &stg_WHITEHOLE_info >> || i == &stg_BLOCKING_QUEUE_CLEAN_info >> || i == &stg_BLOCKING_QUEUE_DIRTY_info) { >> copy(p,info,q,sizeofW(StgInd),gen_no); >> return; >> } >> ASSERT(i != &stg_IND_info); >> } >> q = r; >> *p = r; >> goto loop; >> } >> >> It seems like indirectee can be a TSO, WHITEHOLE, BLOCKING_QUEUE_CLEAN, >> BLOCKING_QUEUE_DIRTY, and it can't be IND. I'm wondering what does it >> mean for >> a BLACKHOLE to point to a >> >> - TSO >> - WHITEHOLE >> - BLOCKING_QUEUE_CLEAN >> - BLOCKING_QUEUE_DIRTY >> > > That sounds right to me. > > >> Is this documented somewhere or otherwise could someone give a few >> pointers on >> where to look in the code? >> > > Unfortunately I don't think we have good documentation for this, but you > should look at the comments around messageBlackHole in Messages.c. > > >> Secondly, I also looked at the BLACKHOLE entry code, and it seems like it >> has a >> different assumption about what can indirectee field point to: >> >> INFO_TABLE(stg_BLACKHOLE,1,0,BLACKHOLE,"BLACKHOLE","BLACKHOLE") >> (P_ node) >> { >> W_ r, info, owner, bd; >> P_ p, bq, msg; >> >> TICK_ENT_DYN_IND(); /* tick */ >> >> retry: >> p = StgInd_indirectee(node); >> if (GETTAG(p) != 0) { >> return (p); >> } >> >> info = StgHeader_info(p); >> if (info == stg_IND_info) { >> // This could happen, if e.g. we got a BLOCKING_QUEUE that has >> // just been replaced with an IND by another thread in >> // wakeBlockingQueue(). >> goto retry; >> } >> >> if (info == stg_TSO_info || >> info == stg_BLOCKING_QUEUE_CLEAN_info || >> info == stg_BLOCKING_QUEUE_DIRTY_info) >> { >> ("ptr" msg) = ccall allocate(MyCapability() "ptr", >> BYTES_TO_WDS(SIZEOF_MessageBl >> ackHole)); >> >> SET_HDR(msg, stg_MSG_BLACKHOLE_info, CCS_SYSTEM); >> MessageBlackHole_tso(msg) = CurrentTSO; >> MessageBlackHole_bh(msg) = node; >> >> (r) = ccall messageBlackHole(MyCapability() "ptr", msg >> "ptr"); >> >> if (r == 0) { >> goto retry; >> } else { >> StgTSO_why_blocked(CurrentTSO) = BlockedOnBlackHole::I16; >> StgTSO_block_info(CurrentTSO) = msg; >> jump stg_block_blackhole(node); >> } >> } >> else >> { >> ENTER(p); >> } >> } >> >> The difference is, when the tag of indirectee is 0, evacuate assumes that >> indirectee can't point to an IND, but BLACKHOLE entry code thinks it's >> possible >> and there's even a comment about why. (I don't understand the comment >> yet) I'm >> wondering if this code is correct, and why. Again any pointers would be >> appreciated. >> > > Taking a quick look at the code, my guess is that: > - a BLOCKING_QUEUE gets overwritten by an IND in wakeBlockingQueue() > - but when this happens, the indirectee of the BLACKHOLE will also be > overwritten to point to the value > > At runtime a thread might see an intermediate state because these > mutations are happening in another thread, so we might follow the > indirectee and see the IND. But this state can't be observed by the GC, > because all mutator threads have stopped at a safe point. > > Cheers > Simon > > > >> Thanks, >> >> Ömer >> _______________________________________________ >> ghc-devs mailing list >> [email protected] >> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs >> > >
_______________________________________________ ghc-devs mailing list [email protected] http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
