Question about indirectees of BLACKHOLE closures

Simon Marlow marlowsd at gmail.com
Tue Mar 20 15:27:36 UTC 2018


Added comments: https://phabricator.haskell.org/D4517

On 20 March 2018 at 14:58, Simon Marlow <marlowsd at gmail.com> wrote:

> Hi Omer,
>
> On 20 March 2018 at 13:05, Ömer Sinan Ağacan <omeragacan at gmail.com> 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
>> ghc-devs at haskell.org
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-devs/attachments/20180320/5a786f55/attachment.html>


More information about the ghc-devs mailing list