[Haskell-cafe] FFI and callbacks

Simon Marlow simonmar at microsoft.com
Mon Jul 25 05:43:22 EDT 2005

On 23 July 2005 03:38, Duncan Coutts wrote:

> The problem then as John noted is that the main loop of these toolkits
> block and so the other Haskell threads would not get a chance to
> schedule. So the challenge is to give the Haskell threads a chance to
> schedule.

[ good description of the multi-threaded GUI problem deleted ]

Thanks for describing the problem in detail, I understand it better now.
I think it comes down to this conflict:

 - you want to take advantage of the fact that GHC has lightweight
   "green" threads in order to do multithreading within a single OS
   thread, but

 - our "bound threads" design does not require the implementation
   to support lightweight threads, and hence doesn't let the
   programmer take advantage of them.

When we were thinking about bound threads, the idea was to accommodate
multiple implementations including the one-to-one and giant lock
approaches.  We consider(ed) GHC's mixture of lightweight and
heavyweight threads to be an optimisation.

However, the GUI library example is interesting, because if we could
take advantage of lightweight threads it seems we could have
multithreaded access to the GUI with better performance and no
requirement to make all GUI calls from a single thread.

But I'm not convinced.  There are advantages to using the single GUI
thread approach, and we don't have any measurements for whether the
overhead is too much.  Suppose you set up a channel containing requests
of type (IO a, MVar a), where the MVar takes the result.  You can build
a combinator

  withGUI :: IO a -> IO a

to perform a GUI operation (and this allows you to try multiple
approaches without changing the code).  Using withGUI you can send a
whole batch of GUI operations in one go, it doesn't have to be one
request per GUI call.  You could also build

  asyncGUI :: IO a -> IO ()

which fires off a GUI request that doesn't require a result, and
combines it with existing requests in a single batch if possible.
Ordering would be retained, of course.

The GUI thread will run multiple requests sequentially, it doesn't have
to context switch between each request.  And you get more parallelism,
because the other threads continue to run while the GUI thread is in the
main loop.


More information about the Haskell-Cafe mailing list