Question about indirectees of BLACKHOLE closures
Rahul Muttineni
rahulmutt at gmail.com
Fri Mar 23 15:51:18 UTC 2018
Hi Omer,
As per my understanding, a BLACKHOLE can point to a THUNK when an exception
is thrown. An exception walks up the stack and overwrites the blackholes
pointed to by the update frames as it walks with an stg_raise closure. That
way, if any concurrent thread happens to evaluate a thunk that was walked,
it'll evaluate the thunk which will blow up as well thereby throwing the
exception on the other thread(s) too.
Definition of stg_raise:
https://github.com/ghc/ghc/blob/ba5797937e575ce6119de6c07703e90dda2557e8/rts/Exception.cmm#L424-L427
raiseExceptionHelper dealing with update frames:
https://github.com/ghc/ghc/blob/d9d463289fe20316cff12a8f0dbf414db678fa72/rts/Schedule.c#L2864-L2875
In general, yes, you can think that a BLACKHOLE will point to a non-THUNK
object assuming that everything went right.
Hope that helps,
Rahul
On Fri, Mar 23, 2018 at 5:48 PM, Ömer Sinan Ağacan <omeragacan at gmail.com>
wrote:
> Thanks Simon, that's really helpful.
>
> A few more questions:
>
> As far as I understand the difference between
>
> - BLACKHOLE pointing to a TSO
> - BLACKHOLE pointing to a BLOCKING_QUEUE
>
> is that in the former we don't yet have any threads blocked by the
> BLACKHOLE
> whereas in the latter we have and the blocking queue holds all those
> blocked
> threads. Did I get this right?
>
> Secondly, can a BLACKHOLE point to a THUNK? I'd expect no, because we
> BLACKHOLE
> a closure when we're done evaluating it (assuming no eager blackholing),
> and
> evaluation usually happens up to WHNF.
>
> Thanks,
>
> Ömer
>
> 2018-03-20 18:27 GMT+03:00 Simon Marlow <marlowsd at gmail.com>:
> > 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_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.
> >>
> >>
> >> 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
> >>
> >>
> >
> _______________________________________________
> ghc-devs mailing list
> ghc-devs at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
>
--
Rahul Muttineni
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-devs/attachments/20180323/11c7040c/attachment.html>
More information about the ghc-devs
mailing list