Why do remaining HECs busy-wait during unsafe-FFI calls?

Herbert Valerio Riedel hvr at gnu.org
Mon May 6 16:26:54 CEST 2013


Andreas Voellmy <andreas.voellmy at gmail.com> writes:

> When an unsafe call is made, the OS thread currently running on the HEC
> makes the call without releasing the HEC. If the main thread was on the run
> queue of the HEC making the foreign unsafe call when the foreign call was
> made, then no other HECs will pick up the main thread. Hence the two sleep
> calls in your program happen sequentially instead of concurrently.

Is this the bound-main-thread issue? That is, would wrapping the main
thread in 'runInUnboundThread' help here?

> I'm not completely sure what is causing the busy wait, but here is one
> guess: when a GC is triggered on one HEC, it signals to all the other HECs
> to stop the mutator and run the collection.  This waiting may be a busy
> wait, because the wait is typically brief.  If this is true, then since one
> thread is off in a unsafe foreign call, there is one HEC that refuses to
> start the GC and all the other HECs are busy-waiting for the signal.  The
> GC could be triggered by a period of inactivity.  Again, this is just a
> guess - you might try to verify this by turning off the periodic triggering
> of GC and checking whether the start GC barrier is a busy-wait.

that seems to be a rather good guess: I inhibited the GC by disabling
the idle-timer using "+RTS -N4 -I0" and with that the HEC
busy-waiting is gone;

So actually this isn't FFI-specific at all, as I could trigger the very
same effect by using a non-allocating/tight-loop evaluation such as the
following:

  do
    _ <- forkIO (evaluate (busyfun 0 0) >> putStrLnTime "busyfun finished")
  where
    busyfun :: Int -> Int -> Int
    busyfun !n !m = if m < 0 then n else busyfun (n+1) (m+1)


cheers,
  hvr



More information about the Glasgow-haskell-users mailing list