
Hello! I was wondering: is the Haskell default runtime (that which uses only one processor) scheduler able to interrupt a thread which is currently calling to a C function in order to enable another haskell thread to progress? I think it can't, because I have starvation problems when I have a thread which calls inside its loop to a C function which makes a little "sleep". BTW, what is the portable way to sleep a thread in Haskell ? Control.Concurrent.threadDelay is "GHC only". ----- Yves Parès Live long and prosper -- View this message in context: http://old.nabble.com/Threading-and-FFI-tp27611528p27611528.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

On Tue, Feb 16, 2010 at 09:00:08AM -0800, Yves Parès wrote:
I was wondering: is the Haskell default runtime (that which uses only one processor) scheduler able to interrupt a thread which is currently calling to a C function in order to enable another haskell thread to progress? I think it can't, because I have starvation problems when I have a thread which calls inside its loop to a C function which makes a little "sleep".
Did you try marking the call as safe? Cheers, -- Felipe.

Well I tried both 'unsafe' and 'safe', and actually I saw no difference... Even with 'safe', I see a huge difference between calling a C function which sleeps and another which doesn't. When there is a sleep, the other thread is really slower (it just prints numbers, and I look at which pace they're displayed). Felipe Lessa wrote:
On Tue, Feb 16, 2010 at 09:00:08AM -0800, Yves Parès wrote:
I was wondering: is the Haskell default runtime (that which uses only one processor) scheduler able to interrupt a thread which is currently calling to a C function in order to enable another haskell thread to progress? I think it can't, because I have starvation problems when I have a thread which calls inside its loop to a C function which makes a little "sleep".
Did you try marking the call as safe?
Cheers,
-- Felipe. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
----- Yves Parès Live long and prosper -- View this message in context: http://old.nabble.com/Threading-and-FFI-tp27611528p27612884.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

There is a minimal code which produces this issue: http://old.nabble.com/file/p27613138/func.c func.c http://old.nabble.com/file/p27613138/main.hs main.hs Yves Parès wrote:
Well I tried both 'unsafe' and 'safe', and actually I saw no difference... Even with 'safe', I see a huge difference between calling a C function which sleeps and another which doesn't. When there is a sleep, the other thread is really slower (it just prints numbers, and I look at which pace they're displayed).
----- Yves Parès Live long and prosper -- View this message in context: http://old.nabble.com/Threading-and-FFI-tp27611528p27613138.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

I've also discovered something interesting: when I link with the 'threaded' runtime, but let the program use only one core (with '+RTS -N1'), the problem disappears. How comes? The whole thing remains a mystery, because I think what I'm trying to do is quite common... Yves Parès wrote:
There is a minimal code which produces this issue: http://old.nabble.com/file/p27613138/func.c func.c http://old.nabble.com/file/p27613138/main.hs main.hs
Yves Parès wrote:
Well I tried both 'unsafe' and 'safe', and actually I saw no difference... Even with 'safe', I see a huge difference between calling a C function which sleeps and another which doesn't. When there is a sleep, the other thread is really slower (it just prints numbers, and I look at which pace they're displayed).
----- Yves Parès Live long and prosper -- View this message in context: http://old.nabble.com/Threading-and-FFI-tp27611528p27621580.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

Yves Parès wrote:
I've also discovered something interesting: when I link with the 'threaded' runtime, but let the program use only one core (with '+RTS -N1'), the problem disappears. How comes? The whole thing remains a mystery, because I think what I'm trying to do is quite common...
Yves Parès wrote:
There is a minimal code which produces this issue: http://old.nabble.com/file/p27613138/func.c func.c http://old.nabble.com/file/p27613138/main.hs main.hs
Yves Parès wrote:
Well I tried both 'unsafe' and 'safe', and actually I saw no difference... Even with 'safe', I see a huge difference between calling a C function which sleeps and another which doesn't. When there is a sleep, the other thread is really slower (it just prints numbers, and I look at which pace they're displayed).
This is to be expected. From the docs (http://www.haskell.org/ghc/docs/latest/html/libraries/base-4.2.0.0/Control-C...): "The downside of having lightweight threads is that only one can run at a time, so if one thread blocks in a foreign call, for example, the other threads cannot continue. The GHC runtime works around this by making use of full OS threads where necessary. When the program is built with the -threaded option (to link against the multithreaded version of the runtime), a thread making a safe foreign call will not block the other threads in the system; another OS thread will take over running Haskell threads until the original call returns. The runtime maintains a pool of these worker threads so that multiple Haskell threads can be involved in external calls simultaneously." IIRC, with -threaded, the RTS spawns a separate OS thread for 'safe' foreign calls _in addition_ to the OS threads used for Haskell code (the number of which you give with the +RTS -N<n> option). Cheers Ben

Okay! So under UNIX, haskell threaded runtime uses pthreads, if I well understood. To sum up, in order to achieve what I want, I have no other choice than compiling with '-threading' and importing as 'safe' the functions which can make a 'sleep'. Thanks! Ben Franksen wrote:
Yves Parès wrote:
I've also discovered something interesting: when I link with the 'threaded' runtime, but let the program use only one core (with '+RTS -N1'), the problem disappears. How comes? The whole thing remains a mystery, because I think what I'm trying to do is quite common...
Yves Parès wrote:
There is a minimal code which produces this issue: http://old.nabble.com/file/p27613138/func.c func.c http://old.nabble.com/file/p27613138/main.hs main.hs
Yves Parès wrote:
Well I tried both 'unsafe' and 'safe', and actually I saw no difference... Even with 'safe', I see a huge difference between calling a C function which sleeps and another which doesn't. When there is a sleep, the other thread is really slower (it just prints numbers, and I look at which pace they're displayed).
This is to be expected. From the docs (http://www.haskell.org/ghc/docs/latest/html/libraries/base-4.2.0.0/Control-C...):
"The downside of having lightweight threads is that only one can run at a time, so if one thread blocks in a foreign call, for example, the other threads cannot continue. The GHC runtime works around this by making use of full OS threads where necessary. When the program is built with the -threaded option (to link against the multithreaded version of the runtime), a thread making a safe foreign call will not block the other threads in the system; another OS thread will take over running Haskell threads until the original call returns. The runtime maintains a pool of these worker threads so that multiple Haskell threads can be involved in external calls simultaneously."
IIRC, with -threaded, the RTS spawns a separate OS thread for 'safe' foreign calls _in addition_ to the OS threads used for Haskell code (the number of which you give with the +RTS -N<n> option).
Cheers Ben
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
----- Yves Parès Live long and prosper -- View this message in context: http://old.nabble.com/Threading-and-FFI-tp27611528p27631980.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

Hello Yves, Thursday, February 18, 2010, 2:10:42 AM, you wrote:
Okay! So under UNIX, haskell threaded runtime uses pthreads, if I well understood.
not exactly. it still uses lightweight (green) threads, but starts additional OS threads as required to keep N haskell threads running. it's very smart
To sum up, in order to achieve what I want, I have no other choice than compiling with '-threading' and importing as 'safe' the functions which can make a 'sleep'.
Thanks!
Ben Franksen wrote:
Yves Pares wrote:
I've also discovered something interesting: when I link with the 'threaded' runtime, but let the program use only one core (with '+RTS -N1'), the problem disappears. How comes? The whole thing remains a mystery, because I think what I'm trying to do is quite common...
Yves Pares wrote:
There is a minimal code which produces this issue: http://old.nabble.com/file/p27613138/func.c func.c http://old.nabble.com/file/p27613138/main.hs main.hs
Yves Pares wrote:
Well I tried both 'unsafe' and 'safe', and actually I saw no difference... Even with 'safe', I see a huge difference between calling a C function which sleeps and another which doesn't. When there is a sleep, the other thread is really slower (it just prints numbers, and I look at which pace they're displayed).
This is to be expected. From the docs (http://www.haskell.org/ghc/docs/latest/html/libraries/base-4.2.0.0/Control-C...):
"The downside of having lightweight threads is that only one can run at a time, so if one thread blocks in a foreign call, for example, the other threads cannot continue. The GHC runtime works around this by making use of full OS threads where necessary. When the program is built with the -threaded option (to link against the multithreaded version of the runtime), a thread making a safe foreign call will not block the other threads in the system; another OS thread will take over running Haskell threads until the original call returns. The runtime maintains a pool of these worker threads so that multiple Haskell threads can be involved in external calls simultaneously."
IIRC, with -threaded, the RTS spawns a separate OS thread for 'safe' foreign calls _in addition_ to the OS threads used for Haskell code (the number of which you give with the +RTS -N<n> option).
Cheers Ben
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
----- Yves Pares
Live long and prosper
-- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

Thank you all. But there are two things that remain obscure: First, there is my situation: int the main thread, I call to some C functions binded through FFI. All of them are marked 'unsafe', except one, which is internally supposed to make pauses with 'usleep'. I then execute in another haskell thread (with forkIO) some pure haskell actions. I then compile with the threaded RTS, and let at run the default behaviour which is to use one core. Question 1) What happens to the "unsafe" C functions? I that simply that the threaded RTS is unable to prevent them from blocking haskell threads (which in my case is a problem only for the function which pauses, since other C calls are fast)? Or they could provoke a hazardous issue, so I have to mark all the C functions as "safe" (which will be much slower) because ? Question 2) In the Control.Concurrent documentation, I understood that forkIO creates unbound threads whereas forkOS creates bound threads, but what is not very clear is: when does GHC threaded runtime launches as bound instead of unbound if this one has been started with forkIO? When it detects the thread calls to a C function? When it detects it calls to a "safe" C function (*)? When it detects another thread calls to a (safe) C function (which is my case)? (*) according to documentation it would be this case. However as I said my C calls are done in the MAIN thread. The other thread just executes casual haskell operations, however it is not blocked, which makes me think that even if I launch it with forkIO, it is launched as an bound thread. Bulat Ziganshin-2 wrote:
Hello Yves,
Thursday, February 18, 2010, 2:10:42 AM, you wrote:
Okay! So under UNIX, haskell threaded runtime uses pthreads, if I well understood.
not exactly. it still uses lightweight (green) threads, but starts additional OS threads as required to keep N haskell threads running. it's very smart
To sum up, in order to achieve what I want, I have no other choice than compiling with '-threading' and importing as 'safe' the functions which can make a 'sleep'.
Thanks!
----- Yves Parès Live long and prosper -- View this message in context: http://old.nabble.com/Threading-and-FFI-tp27611528p27635260.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

Yves Parès wrote:
But there are two things that remain obscure: First, there is my situation: int the main thread, I call to some C functions binded through FFI. All of them are marked 'unsafe', except one, which is internally supposed to make pauses with 'usleep'. I then execute in another haskell thread (with forkIO) some pure haskell actions. I then compile with the threaded RTS, and let at run the default behaviour which is to use one core.
Question 1) What happens to the "unsafe" C functions? I that simply that the threaded RTS is unable to prevent them from blocking haskell threads (which in my case is a problem only for the function which pauses, since other C calls are fast)?
Yes. "unsafe" FFI calls are executed just as a Haskell function. Thta means the underlying OS thread that happens to run the Haskell thread which contains the unsafe FFI call will block and thus all other activity that is scheduled to be run by this OS thread. Note: With unbound threads (those created by forkIO) it might happen at any time that the RTS choses to reschedule your Haskell thread onto another OS thread.
Or they could provoke a hazardous issue, so I have to mark all the C functions as "safe" (which will be much slower) because ?
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".
Question 2) In the Control.Concurrent documentation, I understood that forkIO creates unbound threads whereas forkOS creates bound threads, but what is not very clear is: when does GHC threaded runtime launches as bound instead of unbound if this one has been started with forkIO?
Never. Bound thread are ONLY needed if you (that is, some foreign functions you use) rely on thread-local storage.
When it detects the thread calls to a C function? When it detects it calls to a "safe" C function (*)? When it detects another thread calls to a (safe) C function (which is my case)?
In no case will forkIO create a bounded thread. Period. Bound threads are created with forkOS. 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.
(*) according to documentation it would be this case. However as I said my C calls are done in the MAIN thread.
This doesn't make a difference. Main thread in Haskell is treated as any other thread (except with regard to program termination; imagine it has an invisible exit() call at the end).
The other thread just executes casual haskell operations, however it is not blocked, which makes me think that even if I launch it with forkIO, it is launched as an bound thread.
No. Bound thread means something different. It means that Haskell (green) thread is BOUND (fixed) to an OS thread. This is very bad for performance and only serves one purpose: to enable interoperation with broken C libraries (i.e. those which use thread local storage, a bad, bad, bad thing IMVHO). Cheers Ben

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 (^^).
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)
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. 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. Whenever my main thread reaches the call to my safe C function which 'sleeps', it launches it in another bound thread. Am I right or is it no that easy to foresee the behaviour of my program? ----- Yves Parès Live long and prosper -- View this message in context: http://old.nabble.com/Threading-and-FFI-tp27611528p27647126.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

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.
Yes.
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. Dean

Dean Herington wrote:
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.
That's alright. I'm used to putting all the related calls in the same thread as long as it is possible. It'd seem unlogical to me -- conceptually speaking -- to spread OpenGL calls between several threads. I understand better, now. Actually, I think I was getting worked up for nothing ^^. Just one last remark: when I moved all my OpenGL calls from the main thread to an unbound thread. I thought it'd not work -- because I assumed I would have to launch it in a bound thread -- and however it went right... ----- Yves Parès Live long and prosper -- View this message in context: http://old.nabble.com/Threading-and-FFI-tp27611528p27665592.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

Yves Parès wrote:
Just one last remark: when I moved all my OpenGL calls from the main thread to an unbound thread. I thought it'd not work -- because I assumed I would have to launch it in a bound thread -- and however it went right...
You were just lucky the RTS accidentally delegated all your OpenGL calls to the same OS thread. It might turn out bad next time you run the program, or on another machine, or after adding more threads. Been there... Cheers Ben

On 02/21/2010 09:51 PM, Ben Franksen wrote:
Yves Parès wrote:
Just one last remark: when I moved all my OpenGL calls from the main thread to an unbound thread. I thought it'd not work -- because I assumed I would have to launch it in a bound thread -- and however it went right...
You were just lucky the RTS accidentally delegated all your OpenGL calls to the same OS thread. It might turn out bad next time you run the program, or on another machine, or after adding more threads. Been there...
I've been hacking on a DirectX binding recently where just about all calls have thread affinity as well. The effect of running calls on the wrong thread there was (on my machine, running Seven) making the whole Windows GUI flicker. I wouldn't be surprised if it'd crash on other platforms. Remember, undefined behaviour is not always kind enough to fail hard.

Sorry I start spin-off of thread but all over the haskell code is idiom: throwErrorIfMinus1_ $ someCode args However this code is dependent on errno, which is thread dependent. Is GHC making sure that errno set from C call is propagated back into correct thread? Are there any requirements regarding safeness/unsafeness of such propagation (and if there are shouldn't they be added to various places where it is simply said that safe call simply does not call back into Haskell). Regards

On 20/02/2010 09:52, Maciej Piechotka wrote:
Sorry I start spin-off of thread but all over the haskell code is idiom:
throwErrorIfMinus1_ $ someCode args
However this code is dependent on errno, which is thread dependent. Is GHC making sure that errno set from C call is propagated back into correct thread?
Yes, it is.
Are there any requirements regarding safeness/unsafeness of such propagation
No there aren't. Cheers, Simon
participants (8)
-
Ben Franksen
-
Bulat Ziganshin
-
Dean Herington
-
Felipe Lessa
-
Lars Viklund
-
Maciej Piechotka
-
Simon Marlow
-
Yves Parès