[GHC] #15449: Nondeterministic Failure on aarch64 with -jn, n > 1

GHC ghc-devs at haskell.org
Sat Feb 9 21:43:09 UTC 2019


#15449: Nondeterministic Failure on aarch64 with -jn, n > 1
-------------------------------------+-------------------------------------
        Reporter:  tmobile           |                Owner:  tmobile
            Type:  bug               |               Status:  new
        Priority:  normal            |            Milestone:  8.10.1
       Component:  Compiler          |              Version:  8.4.3
      Resolution:                    |             Keywords:
Operating System:  Linux             |         Architecture:  aarch64
 Type of failure:  Compile-time      |            Test Case:
  crash or panic                     |
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by bgamari):

 Hmm, indeed let's think through this. There are two cases that
 `updateWithIndirection` needs to safely handle. In both case it is turning
 some sort of closure into an indirection:

  * updating a blackhole (e.g. as called from the `stg_upd_frame` entry
 code)
  * updating a thunk (e.g. from `Threads.c:updateThunk`)

 Note that the free variable fields of a thunk and the indirectee field of
 a thunk do not overlap (see `StgThunkHeader` for how this is so).
 Consequently it is safe to write to the indirectee field before writing to
 the info table pointer. In the event that we see this interleaving:

 {{{
 Thread A                                Thread B
 ---------------------------             ---------------------------
 X->indirectee = Y
                                         enter X
 X->info = stg_BLACKHOLE_info
 }}}
 we will, at worst, duplicate the evaluation of `X`. There is no chance to
 stumble into unsoundness here.

 The important thing, as mentioned in comment:22, is that the newly-created
 result is fully visible before the `updatee` field is written. This can be
 ensured by placing a barrier somewhere after the construction of the
 result but before the write to `updatee`.

 Consequently, I think my patch, wherein `updateWithIndirection` is
 {{{
 #define updateWithIndirection(p1, p2, and_then) \
     W_ bd;                                                      \
                                                                 \
     OVERWRITING_CLOSURE(p1);                                    \
     StgInd_indirectee(p1) = p2;                                 \
     prim_write_barrier;                                         \
     SET_INFO(p1, stg_BLACKHOLE_info);                           \
     .
     .
     .
 }}}
 ought to be correct.

-- 
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/15449#comment:24>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list