Re[Haskell-cafe] [2]: Threading and FFI

Dean Herington heringtonlacey at
Sat Feb 20 03:43:24 EST 2010

At 2:53 PM -0800 2/18/10, Yves Parès wrote:
>Ben Franksen wrote:
>>You can leave them "unsafe" if you are sure that
>>1) they do not call (back) any function in your program
>>2) they do not block (or not long enough that it bothers you)
>>Otherwise they are no less safe that the "safe" calls. If (1) is not
>>fulfilled bad things might (that is, probably will) happen. Thus, if you
>>are not sure, chose "safe".
>Okay. Since I know which functions call back to haskell code and which make
>pauses, I know what need to be safe and what can be let safely unsafe (^^).

Think of it as "which foreign functions need to 
be called *safe*ly (because they may call back or 
block) and which can be called *unsafe*ly 
(because they don't).

>>  Bound thread are ONLY needed if you (that is, some foreign functions
>>  you use) rely on thread-local storage.
>Yes, but since the main thread (if I understood well) is bound, if I call to
>C functions which rely on thread-local storage (like OpenGL functions,
>according to GHC Control.Concurrent doc) in this thread I should have no
>problem, shouldn't I?
>And if I choose to call these functions from outside the main thread it'll
>have to be from a thread launched with forkOS? (The C functions I call in my
>real code actually use OpenGL internally)

Careful.  If you're calling foreign functions 
that rely on thread-local storage, you must call 
them using the same OS thread (to provide them 
with the correct thread state), which means using 
the same, *bound*, Haskell thread.  It wouldn't 
work to call them from both the main Haskell 
thread and another Haskell thread, even if the 
latter were a bound thread, as there would be two 
copies of thread-local storage at play.

>>  If runtime is threaded and FFI call is marked safe and Haskell thread is
>>  unbound, then calls to such a function will be executed from SOME extra OS
>>  thread that is managed completely behind the scenes.
>Okay, that's what I didn't understand! Only the call to my safe function
>will be done in an external bound thread, not the whole thread in which the
>call is done.

Note that "bound"edness is a property of a 
Haskell thread, not an OS thread.  The phrase 
"external bound thread" is not sensible.

>So, to sum up, my program will run this way (not necessarily in this order):
>My main is launched in a bound thread.


>My casual haskell I/O operations (read and print from and to the terminal)
>are launched in an unbound thread.

This phrasing also seems a bit confused.  You may 
perform Haskell I/O operations in any Haskell 
thread, and they will be carried out in some OS 
thread (which one doesn't matter).

>Whenever my main thread reaches the call to my safe C function which
>'sleeps', it launches it in another bound thread.

No.  Because the main thread is a bound thread, 
it carries out all of its foreign calls using the 
same OS thread.

>Am I right or is it no that easy to foresee the behaviour of my program?

The existence of both Haskell and OS threads can 
be confusing.  The key is that, to make a foreign 
call, a Haskell thread needs an OS thread as a 
vehicle.  Normally (that is, when any OS thread 
will do) the Haskell thread may (and should, for 
better performance) be unbound.  When the 
OS-defined per-thread state is important, the 
Haskell thread must be bound so that it always 
uses the same OS thread (but it's up to you to 
use the same Haskell thread!).

Hope this helps.

More information about the Haskell-Cafe mailing list