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

Is this documented somewhere or otherwise could someone give a few pointers on
where to look in the code?

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_MessageBlackHole));

            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.

Thanks,

Ömer
_______________________________________________
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

Reply via email to