Re: [Haskell-cafe] How to ensure code executes in the context of a specific OS thread?

On Jul 5, 2011 1:04 PM, "Jason Dagit"
On Tue, Jul 5, 2011 at 12:33 PM, Ian Lynagh
wrote: On Tue, Jul 05, 2011 at 08:11:21PM +0100, Simon Marlow wrote:
In GHCi it's a different matter, because the main thread is running GHCi itself, and all the expressions/statements typed at the prompt are run in forkIO'd threads (a new one for each statement, in fact). If you want a way to run command-line operations in the main thread, please submit a feature request. I'm not sure it can be done, but I'll look into it.
We already have a way: -fno-ghci-sandbox
I've removed all my explicit attempts to forkIO/forkOS and passed the command line flag you mention. I just tried this but it doesn't change the behavior in my example.
I tried it again and discovered that due to an argument parsing bug in cabal-dev that the flag was not passed correctly. I explicitly passed it and verified that it works. Thanks for the workaround. By the way, I did look at the user guide for options like this and didn't see it. Which part of the manual is it in? Can I still make a feature request for a function to make code run on the original thread? My reasoning is that the code which needs to run on the main thread may appear in a library in which case the developer has no control over how ghc is invoked. The alternative appears to be context specific workarounds. I think that a general solution, if possible, will make gui libraries easier to develop for Ghc. I'm hooping it's as simple as exposing a pthreads call. Thanks, Jason

On 06/07/2011 07:37, Jason Dagit wrote:
On Jul 5, 2011 1:04 PM, "Jason Dagit"
mailto:dagitj@gmail.com> wrote: On Tue, Jul 5, 2011 at 12:33 PM, Ian Lynagh
mailto:igloo@earth.li> wrote:
On Tue, Jul 05, 2011 at 08:11:21PM +0100, Simon Marlow wrote:
In GHCi it's a different matter, because the main thread is running GHCi itself, and all the expressions/statements typed at the prompt are run in forkIO'd threads (a new one for each statement, in fact). If you want a way to run command-line operations in the main thread, please submit a feature request. I'm not sure it can be done, but I'll look into it.
We already have a way: -fno-ghci-sandbox
I've removed all my explicit attempts to forkIO/forkOS and passed the command line flag you mention. I just tried this but it doesn't change the behavior in my example.
I tried it again and discovered that due to an argument parsing bug in cabal-dev that the flag was not passed correctly. I explicitly passed it and verified that it works. Thanks for the workaround. By the way, I did look at the user guide for options like this and didn't see it. Which part of the manual is it in?
Can I still make a feature request for a function to make code run on the original thread? My reasoning is that the code which needs to run on the main thread may appear in a library in which case the developer has no control over how ghc is invoked.
I'm not sure how that would work. The programmer is in control of what the main thread does, not GHC. So in order to implement some mechanism to run code on the main thread, we would need some cooperation from the main thread itself. For example, in gtk2hs the main thread runs an event handler loop which occasionally checks a queue for requests from other threads (at least, I think that's how it works). Cheers, Simon
The alternative appears to be context specific workarounds. I think that a general solution, if possible, will make gui libraries easier to develop for Ghc. I'm hooping it's as simple as exposing a pthreads call.

On Wed, Jul 6, 2011 at 2:23 AM, Simon Marlow
On 06/07/2011 07:37, Jason Dagit wrote:
On Jul 5, 2011 1:04 PM, "Jason Dagit"
mailto:dagitj@gmail.com> wrote: > > On Tue, Jul 5, 2011 at 12:33 PM, Ian Lynagh mailto:igloo@earth.li> wrote: > > On Tue, Jul 05, 2011 at 08:11:21PM +0100, Simon Marlow wrote: > >> > >> In GHCi it's a different matter, because the main thread is running > >> GHCi itself, and all the expressions/statements typed at the prompt > >> are run in forkIO'd threads (a new one for each statement, in fact). > >> If you want a way to run command-line operations in the main thread, > >> please submit a feature request. I'm not sure it can be done, but > >> I'll look into it. > > > > We already have a way: -fno-ghci-sandbox > > I've removed all my explicit attempts to forkIO/forkOS and passed the > command line flag you mention. I just tried this but it doesn't > change the behavior in my example. I tried it again and discovered that due to an argument parsing bug in cabal-dev that the flag was not passed correctly. I explicitly passed it and verified that it works. Thanks for the workaround. By the way, I did look at the user guide for options like this and didn't see it. Which part of the manual is it in?
Can I still make a feature request for a function to make code run on the original thread? My reasoning is that the code which needs to run on the main thread may appear in a library in which case the developer has no control over how ghc is invoked.
I'm not sure how that would work. The programmer is in control of what the main thread does, not GHC. So in order to implement some mechanism to run code on the main thread, we would need some cooperation from the main thread itself. For example, in gtk2hs the main thread runs an event handler loop which occasionally checks a queue for requests from other threads (at least, I think that's how it works).
What I'm wrestling with is the following. Say I make a GUI library. As author of the GUI library I discover issues like this where the library code needs to execute on the "main" thread. Users of the library expect the typical Haskell environment where you can't tell the difference between threads, and you fork at will. How can I make sure my library works from GHC (with arbitrary user threads) and from GHCI? As John Lato points out in his email lots of people bump into this without realizing it and don't understand what the problem is. We can try our best to educate everyone, but I have this sense that we could also do a better job of providing primitives to make it so that code will run on the main thread regardless of how people invoke the library. In my specific case (Cocoa on OSX), it is possible for me to use some Cocoa functions to force things to run on the main thread. From what I've read Cocoa uses pthreads to implement this. I was hoping we could expose something from the RTS code in Control.Concurrent so that it's part of an "official" Haskell API that library writers can assume. Judging by this SO question, it's easier to implement this in Haskell on top of pthreads than to implement it in C (here I'm assuming GHC's RTS uses pthreads, but I've never checked): http://stackoverflow.com/questions/6130823/pthreads-perform-function-on-main... In fact, the it sounds like what Gtk2hs is doing with the postGUI functions. Jason

On 06/07/2011 15:42, Jason Dagit wrote:
On Wed, Jul 6, 2011 at 2:23 AM, Simon Marlow
wrote: On 06/07/2011 07:37, Jason Dagit wrote:
On Jul 5, 2011 1:04 PM, "Jason Dagit"
mailto:dagitj@gmail.com> wrote: On Tue, Jul 5, 2011 at 12:33 PM, Ian Lynagh
mailto:igloo@earth.li> wrote:
On Tue, Jul 05, 2011 at 08:11:21PM +0100, Simon Marlow wrote:
In GHCi it's a different matter, because the main thread is running GHCi itself, and all the expressions/statements typed at the prompt are run in forkIO'd threads (a new one for each statement, in fact). If you want a way to run command-line operations in the main thread, please submit a feature request. I'm not sure it can be done, but I'll look into it.
We already have a way: -fno-ghci-sandbox
I've removed all my explicit attempts to forkIO/forkOS and passed the command line flag you mention. I just tried this but it doesn't change the behavior in my example.
I tried it again and discovered that due to an argument parsing bug in cabal-dev that the flag was not passed correctly. I explicitly passed it and verified that it works. Thanks for the workaround. By the way, I did look at the user guide for options like this and didn't see it. Which part of the manual is it in?
Can I still make a feature request for a function to make code run on the original thread? My reasoning is that the code which needs to run on the main thread may appear in a library in which case the developer has no control over how ghc is invoked.
I'm not sure how that would work. The programmer is in control of what the main thread does, not GHC. So in order to implement some mechanism to run code on the main thread, we would need some cooperation from the main thread itself. For example, in gtk2hs the main thread runs an event handler loop which occasionally checks a queue for requests from other threads (at least, I think that's how it works).
What I'm wrestling with is the following. Say I make a GUI library. As author of the GUI library I discover issues like this where the library code needs to execute on the "main" thread. Users of the library expect the typical Haskell environment where you can't tell the difference between threads, and you fork at will. How can I make sure my library works from GHC (with arbitrary user threads) and from GHCI?
As John Lato points out in his email lots of people bump into this without realizing it and don't understand what the problem is. We can try our best to educate everyone, but I have this sense that we could also do a better job of providing primitives to make it so that code will run on the main thread regardless of how people invoke the library.
In my specific case (Cocoa on OSX), it is possible for me to use some Cocoa functions to force things to run on the main thread. From what I've read Cocoa uses pthreads to implement this. I was hoping we could expose something from the RTS code in Control.Concurrent so that it's part of an "official" Haskell API that library writers can assume.
Judging by this SO question, it's easier to implement this in Haskell on top of pthreads than to implement it in C (here I'm assuming GHC's RTS uses pthreads, but I've never checked): http://stackoverflow.com/questions/6130823/pthreads-perform-function-on-main...
In fact, the it sounds like what Gtk2hs is doing with the postGUI functions.
Right, but usually the way this is implemented is with some cooperation from the main thread. That SO answer explains it - the main thread runs some kind of loop that periodically checks for requests from other threads and services them. I expect that's how it works on Cocoa. So you can't just do this from a library - the main thread has to be in on the game. I suppose you might wonder whether the GHC RTS could implement runInMainThread by preempting the main thread and running some different code on it. In theory that's possible, but whether it's a good idea or not is a different matter! I think it amounts to the same thing as the gtk2hs folks have been asking for - multiple Haskell threads bound to the same OS thread. runInMainThread then becomes the same as forking a temporary new thread bound to the main OS thread, or temporarily binding the current thread to the main OS thread. If the main OS thread is off making a foreign call (e.g. in the GUI library's main loop) then it can't run any other Haskell threads anyway, and then I have to figure out what to do with all these Haskell threads waiting for their bound OS thread to come back from the foreign call. My guess is that all this would be pretty complex to implement. Still, I'm all for making things easier somehow. At the least, we should have good diagnostics when you're using GHCi and this goes wrong. Although I'm not sure how to do that, I think it's really something the gtk2hs or Cocoa binding needs to implement. Do you have a way to check whether you're on the main thread or not? Cheers, Simon

On Wed, Jul 6, 2011 at 8:09 AM, Simon Marlow
On 06/07/2011 15:42, Jason Dagit wrote:
On Wed, Jul 6, 2011 at 2:23 AM, Simon Marlow
wrote: On 06/07/2011 07:37, Jason Dagit wrote:
On Jul 5, 2011 1:04 PM, "Jason Dagit"
mailto:dagitj@gmail.com> wrote: > > On Tue, Jul 5, 2011 at 12:33 PM, Ian Lynagh mailto:igloo@earth.li> wrote: > > On Tue, Jul 05, 2011 at 08:11:21PM +0100, Simon Marlow wrote: > >> > >> In GHCi it's a different matter, because the main thread is running > >> GHCi itself, and all the expressions/statements typed at the prompt > >> are run in forkIO'd threads (a new one for each statement, in fact). > >> If you want a way to run command-line operations in the main thread, > >> please submit a feature request. I'm not sure it can be done, but > >> I'll look into it. > > > > We already have a way: -fno-ghci-sandbox > > I've removed all my explicit attempts to forkIO/forkOS and passed the > command line flag you mention. I just tried this but it doesn't > change the behavior in my example. I tried it again and discovered that due to an argument parsing bug in cabal-dev that the flag was not passed correctly. I explicitly passed it and verified that it works. Thanks for the workaround. By the way, I did look at the user guide for options like this and didn't see it. Which part of the manual is it in?
Can I still make a feature request for a function to make code run on the original thread? My reasoning is that the code which needs to run on the main thread may appear in a library in which case the developer has no control over how ghc is invoked.
I'm not sure how that would work. The programmer is in control of what the main thread does, not GHC. So in order to implement some mechanism to run code on the main thread, we would need some cooperation from the main thread itself. For example, in gtk2hs the main thread runs an event handler loop which occasionally checks a queue for requests from other threads (at least, I think that's how it works).
What I'm wrestling with is the following. Say I make a GUI library. As author of the GUI library I discover issues like this where the library code needs to execute on the "main" thread. Users of the library expect the typical Haskell environment where you can't tell the difference between threads, and you fork at will. How can I make sure my library works from GHC (with arbitrary user threads) and from GHCI?
As John Lato points out in his email lots of people bump into this without realizing it and don't understand what the problem is. We can try our best to educate everyone, but I have this sense that we could also do a better job of providing primitives to make it so that code will run on the main thread regardless of how people invoke the library.
In my specific case (Cocoa on OSX), it is possible for me to use some Cocoa functions to force things to run on the main thread. From what I've read Cocoa uses pthreads to implement this. I was hoping we could expose something from the RTS code in Control.Concurrent so that it's part of an "official" Haskell API that library writers can assume.
Judging by this SO question, it's easier to implement this in Haskell on top of pthreads than to implement it in C (here I'm assuming GHC's RTS uses pthreads, but I've never checked):
http://stackoverflow.com/questions/6130823/pthreads-perform-function-on-main...
In fact, the it sounds like what Gtk2hs is doing with the postGUI functions.
Right, but usually the way this is implemented is with some cooperation from the main thread. That SO answer explains it - the main thread runs some kind of loop that periodically checks for requests from other threads and services them. I expect that's how it works on Cocoa. So you can't just do this from a library - the main thread has to be in on the game.
Yes. From my perspective (that of a library writer) that's what makes this tricky in GHCi. I need GHCi's cooperation. From GHCi's perspective it's tricky too.
I suppose you might wonder whether the GHC RTS could implement runInMainThread by preempting the main thread and running some different code on it.
Yes, that's roughly what I was wondering about.
In theory that's possible, but whether it's a good idea or not is a different matter! I think it amounts to the same thing as the gtk2hs folks have been asking for - multiple Haskell threads bound to the same OS thread.
I'm starting to realize that I don't understand the GHC threading model very well :) I thought that was already possible. I may be mixing GHC's thread model up with other language implementations, but I thought that it had a pool of OS threads and that Haskell threads ran on them as needed. I think what you're saying is that the RTS has bound threads and it has thread pooling, but what it doesn't have is "bound thread pooling" (that is, the combination of being bound and pooled).
runInMainThread then becomes the same as forking a temporary new thread bound to the main OS thread, or temporarily binding the current thread to the main OS thread. If the main OS thread is off making a foreign call (e.g. in the GUI library's main loop) then it can't run any other Haskell threads anyway, and then I have to figure out what to do with all these Haskell threads waiting for their bound OS thread to come back from the foreign call. My guess is that all this would be pretty complex to implement.
Yes it does sound complex. I'd really like help as much as possible. I know very little about GHC internals but perhaps I could take a look at some of the RTS code. Is there some background reading I could do? Perhaps a specific reference to a paper or wiki page?
Still, I'm all for making things easier somehow. At the least, we should have good diagnostics when you're using GHCi and this goes wrong. Although I'm not sure how to do that, I think it's really something the gtk2hs or Cocoa binding needs to implement. Do you have a way to check whether you're on the main thread or not?
pthread_main_np is the only way I've stumbled across: https://www.mirbsd.org/htman/i386/man3/pthread_main_np.htm Jason

On 06/07/2011 16:24, Jason Dagit wrote:
On Wed, Jul 6, 2011 at 8:09 AM, Simon Marlow
wrote: On 06/07/2011 15:42, Jason Dagit wrote:
On Wed, Jul 6, 2011 at 2:23 AM, Simon Marlow
wrote: On 06/07/2011 07:37, Jason Dagit wrote:
On Jul 5, 2011 1:04 PM, "Jason Dagit"
mailto:dagitj@gmail.com> wrote: On Tue, Jul 5, 2011 at 12:33 PM, Ian Lynagh
> On Tue, Jul 05, 2011 at 08:11:21PM +0100, Simon Marlow wrote: >> >> In GHCi it's a different matter, because the main thread is running >> GHCi itself, and all the expressions/statements typed at the
>> are run in forkIO'd threads (a new one for each statement, in fact). >> If you want a way to run command-line operations in the main
>> please submit a feature request. I'm not sure it can be done, but >> I'll look into it. > > We already have a way: -fno-ghci-sandbox
I've removed all my explicit attempts to forkIO/forkOS and passed
mailto:igloo@earth.li> wrote: prompt thread, the
command line flag you mention. I just tried this but it doesn't change the behavior in my example.
I tried it again and discovered that due to an argument parsing bug in cabal-dev that the flag was not passed correctly. I explicitly passed it and verified that it works. Thanks for the workaround. By the way, I did look at the user guide for options like this and didn't see it. Which part of the manual is it in?
Can I still make a feature request for a function to make code run on the original thread? My reasoning is that the code which needs to run on the main thread may appear in a library in which case the developer has no control over how ghc is invoked.
I'm not sure how that would work. The programmer is in control of what the main thread does, not GHC. So in order to implement some mechanism to run code on the main thread, we would need some cooperation from the main thread itself. For example, in gtk2hs the main thread runs an event handler loop which occasionally checks a queue for requests from other threads (at least, I think that's how it works).
What I'm wrestling with is the following. Say I make a GUI library. As author of the GUI library I discover issues like this where the library code needs to execute on the "main" thread. Users of the library expect the typical Haskell environment where you can't tell the difference between threads, and you fork at will. How can I make sure my library works from GHC (with arbitrary user threads) and from GHCI?
As John Lato points out in his email lots of people bump into this without realizing it and don't understand what the problem is. We can try our best to educate everyone, but I have this sense that we could also do a better job of providing primitives to make it so that code will run on the main thread regardless of how people invoke the library.
In my specific case (Cocoa on OSX), it is possible for me to use some Cocoa functions to force things to run on the main thread. From what I've read Cocoa uses pthreads to implement this. I was hoping we could expose something from the RTS code in Control.Concurrent so that it's part of an "official" Haskell API that library writers can assume.
Judging by this SO question, it's easier to implement this in Haskell on top of pthreads than to implement it in C (here I'm assuming GHC's RTS uses pthreads, but I've never checked):
http://stackoverflow.com/questions/6130823/pthreads-perform-function-on-main...
In fact, the it sounds like what Gtk2hs is doing with the postGUI functions.
Right, but usually the way this is implemented is with some cooperation from the main thread. That SO answer explains it - the main thread runs some kind of loop that periodically checks for requests from other threads and services them. I expect that's how it works on Cocoa. So you can't just do this from a library - the main thread has to be in on the game.
Yes. From my perspective (that of a library writer) that's what makes this tricky in GHCi. I need GHCi's cooperation. From GHCi's perspective it's tricky too.
I suppose you might wonder whether the GHC RTS could implement runInMainThread by preempting the main thread and running some different code on it.
Yes, that's roughly what I was wondering about.
In theory that's possible, but whether it's a good idea or not is a different matter! I think it amounts to the same thing as the gtk2hs folks have been asking for - multiple Haskell threads bound to the same OS thread.
I'm starting to realize that I don't understand the GHC threading model very well :) I thought that was already possible. I may be mixing GHC's thread model up with other language implementations, but I thought that it had a pool of OS threads and that Haskell threads ran on them as needed. I think what you're saying is that the RTS has bound threads and it has thread pooling, but what it doesn't have is "bound thread pooling" (that is, the combination of being bound and pooled).
runInMainThread then becomes the same as forking a temporary new thread bound to the main OS thread, or temporarily binding the current thread to the main OS thread. If the main OS thread is off making a foreign call (e.g. in the GUI library's main loop) then it can't run any other Haskell threads anyway, and then I have to figure out what to do with all these Haskell threads waiting for their bound OS thread to come back from the foreign call. My guess is that all this would be pretty complex to implement.
Yes it does sound complex. I'd really like help as much as possible. I know very little about GHC internals but perhaps I could take a look at some of the RTS code. Is there some background reading I could do? Perhaps a specific reference to a paper or wiki page?
This is the paper that explains the design: http://community.haskell.org/~simonmar/papers/conc-ffi.pdf And there's some documentation on the implementation here: http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Scheduler though I think the latter is very incomplete. I'd really like to flesh it out sometime. Cheers, Simon

On Wed, Jul 6, 2011 at 8:51 AM, Simon Marlow
On 06/07/2011 16:24, Jason Dagit wrote:
On Wed, Jul 6, 2011 at 8:09 AM, Simon Marlow
wrote: On 06/07/2011 15:42, Jason Dagit wrote:
On Wed, Jul 6, 2011 at 2:23 AM, Simon Marlow
wrote: On 06/07/2011 07:37, Jason Dagit wrote:
On Jul 5, 2011 1:04 PM, "Jason Dagit"
mailto:dagitj@gmail.com> wrote: > > On Tue, Jul 5, 2011 at 12:33 PM, Ian Lynagh mailto:igloo@earth.li> wrote: > > On Tue, Jul 05, 2011 at 08:11:21PM +0100, Simon Marlow wrote: > >> > >> In GHCi it's a different matter, because the main thread is running > >> GHCi itself, and all the expressions/statements typed at the prompt > >> are run in forkIO'd threads (a new one for each statement, in fact). > >> If you want a way to run command-line operations in the main thread, > >> please submit a feature request. I'm not sure it can be done, but > >> I'll look into it. > > > > We already have a way: -fno-ghci-sandbox > > I've removed all my explicit attempts to forkIO/forkOS and passed the > command line flag you mention. I just tried this but it doesn't > change the behavior in my example. I tried it again and discovered that due to an argument parsing bug in cabal-dev that the flag was not passed correctly. I explicitly passed it and verified that it works. Thanks for the workaround. By the way, I did look at the user guide for options like this and didn't see it. Which part of the manual is it in?
Can I still make a feature request for a function to make code run on the original thread? My reasoning is that the code which needs to run on the main thread may appear in a library in which case the developer has no control over how ghc is invoked.
I'm not sure how that would work. The programmer is in control of what the main thread does, not GHC. So in order to implement some mechanism to run code on the main thread, we would need some cooperation from the main thread itself. For example, in gtk2hs the main thread runs an event handler loop which occasionally checks a queue for requests from other threads (at least, I think that's how it works).
What I'm wrestling with is the following. Say I make a GUI library. As author of the GUI library I discover issues like this where the library code needs to execute on the "main" thread. Users of the library expect the typical Haskell environment where you can't tell the difference between threads, and you fork at will. How can I make sure my library works from GHC (with arbitrary user threads) and from GHCI?
As John Lato points out in his email lots of people bump into this without realizing it and don't understand what the problem is. We can try our best to educate everyone, but I have this sense that we could also do a better job of providing primitives to make it so that code will run on the main thread regardless of how people invoke the library.
In my specific case (Cocoa on OSX), it is possible for me to use some Cocoa functions to force things to run on the main thread. From what I've read Cocoa uses pthreads to implement this. I was hoping we could expose something from the RTS code in Control.Concurrent so that it's part of an "official" Haskell API that library writers can assume.
Judging by this SO question, it's easier to implement this in Haskell on top of pthreads than to implement it in C (here I'm assuming GHC's RTS uses pthreads, but I've never checked):
http://stackoverflow.com/questions/6130823/pthreads-perform-function-on-main...
In fact, the it sounds like what Gtk2hs is doing with the postGUI functions.
Right, but usually the way this is implemented is with some cooperation from the main thread. That SO answer explains it - the main thread runs some kind of loop that periodically checks for requests from other threads and services them. I expect that's how it works on Cocoa. So you can't just do this from a library - the main thread has to be in on the game.
Yes. From my perspective (that of a library writer) that's what makes this tricky in GHCi. I need GHCi's cooperation. From GHCi's perspective it's tricky too.
I suppose you might wonder whether the GHC RTS could implement runInMainThread by preempting the main thread and running some different code on it.
Yes, that's roughly what I was wondering about.
In theory that's possible, but whether it's a good idea or not is a different matter! I think it amounts to the same thing as the gtk2hs folks have been asking for - multiple Haskell threads bound to the same OS thread.
I'm starting to realize that I don't understand the GHC threading model very well :) I thought that was already possible. I may be mixing GHC's thread model up with other language implementations, but I thought that it had a pool of OS threads and that Haskell threads ran on them as needed. I think what you're saying is that the RTS has bound threads and it has thread pooling, but what it doesn't have is "bound thread pooling" (that is, the combination of being bound and pooled).
runInMainThread then becomes the same as forking a temporary new thread bound to the main OS thread, or temporarily binding the current thread to the main OS thread. If the main OS thread is off making a foreign call (e.g. in the GUI library's main loop) then it can't run any other Haskell threads anyway, and then I have to figure out what to do with all these Haskell threads waiting for their bound OS thread to come back from the foreign call. My guess is that all this would be pretty complex to implement.
Yes it does sound complex. I'd really like help as much as possible. I know very little about GHC internals but perhaps I could take a look at some of the RTS code. Is there some background reading I could do? Perhaps a specific reference to a paper or wiki page?
This is the paper that explains the design:
http://community.haskell.org/~simonmar/papers/conc-ffi.pdf
And there's some documentation on the implementation here:
http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Scheduler
though I think the latter is very incomplete. I'd really like to flesh it out sometime.
These documents look like a great start. Thanks! Jason

On Wed, Jul 6, 2011 at 5:24 PM, Jason Dagit
On Wed, Jul 6, 2011 at 8:09 AM, Simon Marlow
wrote: On 06/07/2011 15:42, Jason Dagit wrote:
On Wed, Jul 6, 2011 at 2:23 AM, Simon Marlow
wrote: On 06/07/2011 07:37, Jason Dagit wrote:
On Jul 5, 2011 1:04 PM, "Jason Dagit"
mailto:dagitj@gmail.com> wrote: > > On Tue, Jul 5, 2011 at 12:33 PM, Ian Lynagh mailto:igloo@earth.li> wrote: > > On Tue, Jul 05, 2011 at 08:11:21PM +0100, Simon Marlow wrote: > >> > >> In GHCi it's a different matter, because the main thread is running > >> GHCi itself, and all the expressions/statements typed at the prompt > >> are run in forkIO'd threads (a new one for each statement, in fact). > >> If you want a way to run command-line operations in the main thread, > >> please submit a feature request. I'm not sure it can be done, but > >> I'll look into it. > > > > We already have a way: -fno-ghci-sandbox > > I've removed all my explicit attempts to forkIO/forkOS and passed the > command line flag you mention. I just tried this but it doesn't > change the behavior in my example. I tried it again and discovered that due to an argument parsing bug in cabal-dev that the flag was not passed correctly. I explicitly passed it and verified that it works. Thanks for the workaround. By the way, I did look at the user guide for options like this and didn't see it. Which part of the manual is it in?
Can I still make a feature request for a function to make code run on the original thread? My reasoning is that the code which needs to run on the main thread may appear in a library in which case the developer has no control over how ghc is invoked.
I'm not sure how that would work. The programmer is in control of what the main thread does, not GHC. So in order to implement some mechanism to run code on the main thread, we would need some cooperation from the main thread itself. For example, in gtk2hs the main thread runs an event handler loop which occasionally checks a queue for requests from other threads (at least, I think that's how it works).
What I'm wrestling with is the following. Say I make a GUI library. As author of the GUI library I discover issues like this where the library code needs to execute on the "main" thread. Users of the library expect the typical Haskell environment where you can't tell the difference between threads, and you fork at will. How can I make sure my library works from GHC (with arbitrary user threads) and from GHCI?
As John Lato points out in his email lots of people bump into this without realizing it and don't understand what the problem is. We can try our best to educate everyone, but I have this sense that we could also do a better job of providing primitives to make it so that code will run on the main thread regardless of how people invoke the library.
In my specific case (Cocoa on OSX), it is possible for me to use some Cocoa functions to force things to run on the main thread. From what I've read Cocoa uses pthreads to implement this. I was hoping we could expose something from the RTS code in Control.Concurrent so that it's part of an "official" Haskell API that library writers can assume.
Judging by this SO question, it's easier to implement this in Haskell on top of pthreads than to implement it in C (here I'm assuming GHC's RTS uses pthreads, but I've never checked):
http://stackoverflow.com/questions/6130823/pthreads-perform-function-on-main...
In fact, the it sounds like what Gtk2hs is doing with the postGUI functions.
Right, but usually the way this is implemented is with some cooperation from the main thread. That SO answer explains it - the main thread runs some kind of loop that periodically checks for requests from other threads and services them. I expect that's how it works on Cocoa. So you can't just do this from a library - the main thread has to be in on the game.
Yes. From my perspective (that of a library writer) that's what makes this tricky in GHCi. I need GHCi's cooperation. From GHCi's perspective it's tricky too.
I suppose you might wonder whether the GHC RTS could implement runInMainThread by preempting the main thread and running some different code on it.
Yes, that's roughly what I was wondering about.
There's more than one reason why a (GUI) library might require functions to be called only from the main thread. One is if the library uses thread-local storage, in which case the code needs to run in the right thread to see the right data. I've heard that OpenGL is like this. Another (more common, as far as I know) reason is if (parts of) the library aren't thread safe, and can't handle more than one thread at a time simultaneously calling its functions and mutating its members. I'm not sure if there are other reasons. In the second (thread safety) case, if you preempt the main thread in the middle of whatever it was doing to use it to call some function from the library, the effect would, I think, be the same as if the OS had preempted it to execute some other thread which then called the function, and you would be violating the library's one-thread-at-a-time expectation in pretty much the same exact way. So I don't think you would gain anything useful by doing this. The main thread needs to be interrupted at 'safe points', which is what the event loop lets you do, but the event loop is part of the GUI library, and not part of the GHC runtime, so GHC doesn't know about it and can't tell it what to do - only the library bindings can. Stated another way: I suspect most GUI libraries don't really actually care that you only execute GUI code from the main OS thread, as much as they care that only one (thread-unsafe) GUI function is being called at any given time. If you only ever call GUI code from the same (main) OS thread, that fulfills this requirement, because an OS thread is only capable of running one library function at a time; alternately, if you only ever call GUI code from the same Haskell thread, that also fulfills this requirement, because one Haskell thread is also only capable of running one library function at a time, even if its execution might jump between different OS threads along the way. (If you were writing code in the library's native language, and as part of your own code for processing an event in the main thread, stopped the main thread, used a different thread to execute some GUI functions, and then returned control to the main thread, I suspect that would also be safe, though there tends not to be any reason to want to do this.) Basically: In the context of GHC/Haskell, I think you need to separate the concept of "thread of execution", which is what the GUI libraries care about, from the concept of "OS threads", which nearly all of the time correspond to the threads of execution, but in this case, don't. (Or rather, do, but in a very different way from the usual.) These are impressions I've gained from the reading the docs (such as the paper Simon just linked) and thinking about it. If anyone more knowledgeable sees that I'm mistaken, please correct me.
In theory that's possible, but whether it's a good idea or not is a different matter! I think it amounts to the same thing as the gtk2hs folks have been asking for - multiple Haskell threads bound to the same OS thread.
I'm starting to realize that I don't understand the GHC threading model very well :) I thought that was already possible. I may be mixing GHC's thread model up with other language implementations, but I thought that it had a pool of OS threads and that Haskell threads ran on them as needed. I think what you're saying is that the RTS has bound threads and it has thread pooling, but what it doesn't have is "bound thread pooling" (that is, the combination of being bound and pooled).
runInMainThread then becomes the same as forking a temporary new thread bound to the main OS thread, or temporarily binding the current thread to the main OS thread. If the main OS thread is off making a foreign call (e.g. in the GUI library's main loop) then it can't run any other Haskell threads anyway, and then I have to figure out what to do with all these Haskell threads waiting for their bound OS thread to come back from the foreign call. My guess is that all this would be pretty complex to implement.
Yes it does sound complex. I'd really like help as much as possible. I know very little about GHC internals but perhaps I could take a look at some of the RTS code. Is there some background reading I could do? Perhaps a specific reference to a paper or wiki page?
Still, I'm all for making things easier somehow. At the least, we should have good diagnostics when you're using GHCi and this goes wrong. Although I'm not sure how to do that, I think it's really something the gtk2hs or Cocoa binding needs to implement. Do you have a way to check whether you're on the main thread or not?
pthread_main_np is the only way I've stumbled across: https://www.mirbsd.org/htman/i386/man3/pthread_main_np.htm
Jason
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Work is punishment for failing to procrastinate effectively.

2011/7/6 Gábor Lehel
On Wed, Jul 6, 2011 at 5:24 PM, Jason Dagit
wrote: On Wed, Jul 6, 2011 at 8:09 AM, Simon Marlow
wrote: On 06/07/2011 15:42, Jason Dagit wrote:
On Wed, Jul 6, 2011 at 2:23 AM, Simon Marlow
wrote: On 06/07/2011 07:37, Jason Dagit wrote:
On Jul 5, 2011 1:04 PM, "Jason Dagit"
mailto:dagitj@gmail.com> wrote: > > On Tue, Jul 5, 2011 at 12:33 PM, Ian Lynagh mailto:igloo@earth.li> wrote: > > On Tue, Jul 05, 2011 at 08:11:21PM +0100, Simon Marlow wrote: > >> > >> In GHCi it's a different matter, because the main thread is running > >> GHCi itself, and all the expressions/statements typed at the prompt > >> are run in forkIO'd threads (a new one for each statement, in fact). > >> If you want a way to run command-line operations in the main thread, > >> please submit a feature request. I'm not sure it can be done, but > >> I'll look into it. > > > > We already have a way: -fno-ghci-sandbox > > I've removed all my explicit attempts to forkIO/forkOS and passed the > command line flag you mention. I just tried this but it doesn't > change the behavior in my example. I tried it again and discovered that due to an argument parsing bug in cabal-dev that the flag was not passed correctly. I explicitly passed it and verified that it works. Thanks for the workaround. By the way, I did look at the user guide for options like this and didn't see it. Which part of the manual is it in?
Can I still make a feature request for a function to make code run on the original thread? My reasoning is that the code which needs to run on the main thread may appear in a library in which case the developer has no control over how ghc is invoked.
I'm not sure how that would work. The programmer is in control of what the main thread does, not GHC. So in order to implement some mechanism to run code on the main thread, we would need some cooperation from the main thread itself. For example, in gtk2hs the main thread runs an event handler loop which occasionally checks a queue for requests from other threads (at least, I think that's how it works).
What I'm wrestling with is the following. Say I make a GUI library. As author of the GUI library I discover issues like this where the library code needs to execute on the "main" thread. Users of the library expect the typical Haskell environment where you can't tell the difference between threads, and you fork at will. How can I make sure my library works from GHC (with arbitrary user threads) and from GHCI?
As John Lato points out in his email lots of people bump into this without realizing it and don't understand what the problem is. We can try our best to educate everyone, but I have this sense that we could also do a better job of providing primitives to make it so that code will run on the main thread regardless of how people invoke the library.
In my specific case (Cocoa on OSX), it is possible for me to use some Cocoa functions to force things to run on the main thread. From what I've read Cocoa uses pthreads to implement this. I was hoping we could expose something from the RTS code in Control.Concurrent so that it's part of an "official" Haskell API that library writers can assume.
Judging by this SO question, it's easier to implement this in Haskell on top of pthreads than to implement it in C (here I'm assuming GHC's RTS uses pthreads, but I've never checked):
http://stackoverflow.com/questions/6130823/pthreads-perform-function-on-main...
In fact, the it sounds like what Gtk2hs is doing with the postGUI functions.
Right, but usually the way this is implemented is with some cooperation from the main thread. That SO answer explains it - the main thread runs some kind of loop that periodically checks for requests from other threads and services them. I expect that's how it works on Cocoa. So you can't just do this from a library - the main thread has to be in on the game.
Yes. From my perspective (that of a library writer) that's what makes this tricky in GHCi. I need GHCi's cooperation. From GHCi's perspective it's tricky too.
I suppose you might wonder whether the GHC RTS could implement runInMainThread by preempting the main thread and running some different code on it.
Yes, that's roughly what I was wondering about.
There's more than one reason why a (GUI) library might require functions to be called only from the main thread. One is if the library uses thread-local storage, in which case the code needs to run in the right thread to see the right data. I've heard that OpenGL is like this. Another (more common, as far as I know) reason is if (parts of) the library aren't thread safe, and can't handle more than one thread at a time simultaneously calling its functions and mutating its members. I'm not sure if there are other reasons.
In the second (thread safety) case, if you preempt the main thread in the middle of whatever it was doing to use it to call some function from the library, the effect would, I think, be the same as if the OS had preempted it to execute some other thread which then called the function, and you would be violating the library's one-thread-at-a-time expectation in pretty much the same exact way. So I don't think you would gain anything useful by doing this. The main thread needs to be interrupted at 'safe points', which is what the event loop lets you do, but the event loop is part of the GUI library, and not part of the GHC runtime, so GHC doesn't know about it and can't tell it what to do - only the library bindings can.
Stated another way: I suspect most GUI libraries don't really actually care that you only execute GUI code from the main OS thread, as much as they care that only one (thread-unsafe) GUI function is being called at any given time. If you only ever call GUI code from the same (main) OS thread, that fulfills this requirement, because an OS thread is only capable of running one library function at a time; alternately, if you only ever call GUI code from the same Haskell thread, that also fulfills this requirement, because one Haskell thread is also only capable of running one library function at a time, even if its execution might jump between different OS threads along the way. (If you were writing code in the library's native language, and as part of your own code for processing an event in the main thread, stopped the main thread, used a different thread to execute some GUI functions, and then returned control to the main thread, I suspect that would also be safe, though there tends not to be any reason to want to do this.)
Basically: In the context of GHC/Haskell, I think you need to separate the concept of "thread of execution", which is what the GUI libraries care about, from the concept of "OS threads", which nearly all of the time correspond to the threads of execution, but in this case, don't. (Or rather, do, but in a very different way from the usual.)
Clarifying: The OS threads and the Haskell threads both correspond to threads of execution, and the two sets overlap with each other in time in complicated ways, but the property "only runs one function at a time, and runs it to completion before running a different function" in this case belongs to the Haskell threads. ("Function" here used in the C sense.) I'm not sure, at the moment, whether it *also* applies to the OS threads. Thinking about this makes my brain hurt.
These are impressions I've gained from the reading the docs (such as the paper Simon just linked) and thinking about it. If anyone more knowledgeable sees that I'm mistaken, please correct me.
In theory that's possible, but whether it's a good idea or not is a different matter! I think it amounts to the same thing as the gtk2hs folks have been asking for - multiple Haskell threads bound to the same OS thread.
I'm starting to realize that I don't understand the GHC threading model very well :) I thought that was already possible. I may be mixing GHC's thread model up with other language implementations, but I thought that it had a pool of OS threads and that Haskell threads ran on them as needed. I think what you're saying is that the RTS has bound threads and it has thread pooling, but what it doesn't have is "bound thread pooling" (that is, the combination of being bound and pooled).
runInMainThread then becomes the same as forking a temporary new thread bound to the main OS thread, or temporarily binding the current thread to the main OS thread. If the main OS thread is off making a foreign call (e.g. in the GUI library's main loop) then it can't run any other Haskell threads anyway, and then I have to figure out what to do with all these Haskell threads waiting for their bound OS thread to come back from the foreign call. My guess is that all this would be pretty complex to implement.
Yes it does sound complex. I'd really like help as much as possible. I know very little about GHC internals but perhaps I could take a look at some of the RTS code. Is there some background reading I could do? Perhaps a specific reference to a paper or wiki page?
Still, I'm all for making things easier somehow. At the least, we should have good diagnostics when you're using GHCi and this goes wrong. Although I'm not sure how to do that, I think it's really something the gtk2hs or Cocoa binding needs to implement. Do you have a way to check whether you're on the main thread or not?
pthread_main_np is the only way I've stumbled across: https://www.mirbsd.org/htman/i386/man3/pthread_main_np.htm
Jason
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Work is punishment for failing to procrastinate effectively.
-- Work is punishment for failing to procrastinate effectively.

2011/7/6 Gábor Lehel
2011/7/6 Gábor Lehel
: On Wed, Jul 6, 2011 at 5:24 PM, Jason Dagit
wrote: On Wed, Jul 6, 2011 at 8:09 AM, Simon Marlow
wrote: On 06/07/2011 15:42, Jason Dagit wrote:
On Wed, Jul 6, 2011 at 2:23 AM, Simon Marlow
wrote: On 06/07/2011 07:37, Jason Dagit wrote: > > On Jul 5, 2011 1:04 PM, "Jason Dagit"
mailto:dagitj@gmail.com> wrote: > > > > On Tue, Jul 5, 2011 at 12:33 PM, Ian Lynagh mailto:igloo@earth.li> wrote: > > > On Tue, Jul 05, 2011 at 08:11:21PM +0100, Simon Marlow wrote: > > >> > > >> In GHCi it's a different matter, because the main thread is > running > > >> GHCi itself, and all the expressions/statements typed at the > prompt > > >> are run in forkIO'd threads (a new one for each statement, in > fact). > > >> If you want a way to run command-line operations in the main > thread, > > >> please submit a feature request. I'm not sure it can be done, > but > > >> I'll look into it. > > > > > > We already have a way: -fno-ghci-sandbox > > > > I've removed all my explicit attempts to forkIO/forkOS and passed > the > > command line flag you mention. I just tried this but it doesn't > > change the behavior in my example. > > I tried it again and discovered that due to an argument parsing bug in > cabal-dev that the flag was not passed correctly. I explicitly passed it > and verified that it works. Thanks for the workaround. By the way, I did > look at the user guide for options like this and didn't see it. Which > part of the manual is it in? > > Can I still make a feature request for a function to make code run on > the original thread? My reasoning is that the code which needs to run on > the main thread may appear in a library in which case the developer has > no control over how ghc is invoked. I'm not sure how that would work. The programmer is in control of what the main thread does, not GHC. So in order to implement some mechanism to run code on the main thread, we would need some cooperation from the main thread itself. For example, in gtk2hs the main thread runs an event handler loop which occasionally checks a queue for requests from other threads (at least, I think that's how it works).
What I'm wrestling with is the following. Say I make a GUI library. As author of the GUI library I discover issues like this where the library code needs to execute on the "main" thread. Users of the library expect the typical Haskell environment where you can't tell the difference between threads, and you fork at will. How can I make sure my library works from GHC (with arbitrary user threads) and from GHCI?
As John Lato points out in his email lots of people bump into this without realizing it and don't understand what the problem is. We can try our best to educate everyone, but I have this sense that we could also do a better job of providing primitives to make it so that code will run on the main thread regardless of how people invoke the library.
In my specific case (Cocoa on OSX), it is possible for me to use some Cocoa functions to force things to run on the main thread. From what I've read Cocoa uses pthreads to implement this. I was hoping we could expose something from the RTS code in Control.Concurrent so that it's part of an "official" Haskell API that library writers can assume.
Judging by this SO question, it's easier to implement this in Haskell on top of pthreads than to implement it in C (here I'm assuming GHC's RTS uses pthreads, but I've never checked):
http://stackoverflow.com/questions/6130823/pthreads-perform-function-on-main...
In fact, the it sounds like what Gtk2hs is doing with the postGUI functions.
Right, but usually the way this is implemented is with some cooperation from the main thread. That SO answer explains it - the main thread runs some kind of loop that periodically checks for requests from other threads and services them. I expect that's how it works on Cocoa. So you can't just do this from a library - the main thread has to be in on the game.
Yes. From my perspective (that of a library writer) that's what makes this tricky in GHCi. I need GHCi's cooperation. From GHCi's perspective it's tricky too.
I suppose you might wonder whether the GHC RTS could implement runInMainThread by preempting the main thread and running some different code on it.
Yes, that's roughly what I was wondering about.
There's more than one reason why a (GUI) library might require functions to be called only from the main thread. One is if the library uses thread-local storage, in which case the code needs to run in the right thread to see the right data. I've heard that OpenGL is like this. Another (more common, as far as I know) reason is if (parts of) the library aren't thread safe, and can't handle more than one thread at a time simultaneously calling its functions and mutating its members. I'm not sure if there are other reasons.
In the second (thread safety) case, if you preempt the main thread in the middle of whatever it was doing to use it to call some function from the library, the effect would, I think, be the same as if the OS had preempted it to execute some other thread which then called the function, and you would be violating the library's one-thread-at-a-time expectation in pretty much the same exact way. So I don't think you would gain anything useful by doing this. The main thread needs to be interrupted at 'safe points', which is what the event loop lets you do, but the event loop is part of the GUI library, and not part of the GHC runtime, so GHC doesn't know about it and can't tell it what to do - only the library bindings can.
Stated another way: I suspect most GUI libraries don't really actually care that you only execute GUI code from the main OS thread, as much as they care that only one (thread-unsafe) GUI function is being called at any given time. If you only ever call GUI code from the same (main) OS thread, that fulfills this requirement, because an OS thread is only capable of running one library function at a time; alternately, if you only ever call GUI code from the same Haskell thread, that also fulfills this requirement, because one Haskell thread is also only capable of running one library function at a time, even if its execution might jump between different OS threads along the way. (If you were writing code in the library's native language, and as part of your own code for processing an event in the main thread, stopped the main thread, used a different thread to execute some GUI functions, and then returned control to the main thread, I suspect that would also be safe, though there tends not to be any reason to want to do this.)
Basically: In the context of GHC/Haskell, I think you need to separate the concept of "thread of execution", which is what the GUI libraries care about, from the concept of "OS threads", which nearly all of the time correspond to the threads of execution, but in this case, don't. (Or rather, do, but in a very different way from the usual.)
Clarifying: The OS threads and the Haskell threads both correspond to threads of execution, and the two sets overlap with each other in time in complicated ways, but the property "only runs one function at a time, and runs it to completion before running a different function" in this case belongs to the Haskell threads. ("Function" here used in the C sense.) I'm not sure, at the moment, whether it *also* applies to the OS threads. Thinking about this makes my brain hurt.
So: I believe it does also apply to OS threads regarding C functions (GHC doesn't preempt OS threads during FFI calls), but doesn't apply to them regarding Haskell functions (in which case it preempts with impunity). But a single, logical thread of execution as written in the program ("the thing that gets executed next is the thing that comes next in the source code, and not something totally unrelated") can be traced along the execution of a Haskell thread, not an OS thread. (Apologies if my terminology is sloppy and hard to follow, I'm not 100% sure of the proper mapping of words to concepts and may be using them in wrong ways.)
These are impressions I've gained from the reading the docs (such as the paper Simon just linked) and thinking about it. If anyone more knowledgeable sees that I'm mistaken, please correct me.
In theory that's possible, but whether it's a good idea or not is a different matter! I think it amounts to the same thing as the gtk2hs folks have been asking for - multiple Haskell threads bound to the same OS thread.
I'm starting to realize that I don't understand the GHC threading model very well :) I thought that was already possible. I may be mixing GHC's thread model up with other language implementations, but I thought that it had a pool of OS threads and that Haskell threads ran on them as needed. I think what you're saying is that the RTS has bound threads and it has thread pooling, but what it doesn't have is "bound thread pooling" (that is, the combination of being bound and pooled).
runInMainThread then becomes the same as forking a temporary new thread bound to the main OS thread, or temporarily binding the current thread to the main OS thread. If the main OS thread is off making a foreign call (e.g. in the GUI library's main loop) then it can't run any other Haskell threads anyway, and then I have to figure out what to do with all these Haskell threads waiting for their bound OS thread to come back from the foreign call. My guess is that all this would be pretty complex to implement.
Yes it does sound complex. I'd really like help as much as possible. I know very little about GHC internals but perhaps I could take a look at some of the RTS code. Is there some background reading I could do? Perhaps a specific reference to a paper or wiki page?
Still, I'm all for making things easier somehow. At the least, we should have good diagnostics when you're using GHCi and this goes wrong. Although I'm not sure how to do that, I think it's really something the gtk2hs or Cocoa binding needs to implement. Do you have a way to check whether you're on the main thread or not?
pthread_main_np is the only way I've stumbled across: https://www.mirbsd.org/htman/i386/man3/pthread_main_np.htm
Jason
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Work is punishment for failing to procrastinate effectively.
-- Work is punishment for failing to procrastinate effectively.
-- Work is punishment for failing to procrastinate effectively.

Quoth =?ISO-8859-1?Q?G=E1bor_Lehel?=
Stated another way: I suspect most GUI libraries don't really actually care that you only execute GUI code from the main OS thread, as much as they care that only one (thread-unsafe) GUI function is being called at any given time. If you only ever call GUI code from the same (main) OS thread, that fulfills this requirement, because an OS thread is only capable of running one library function at a time; alternately, if you only ever call GUI code from the same Haskell thread, that also fulfills this requirement, because one Haskell thread is also only capable of running one library function at a time,
I thought in the present case, the program now works when compiled, but fails when run in GHCi, and we believe that the only difference here is that GHCi took the main thread and put the program, and hence the GUI, in some other thread? I.e., your requirement is indeed met, per the second alternative, but the program still fails, because this library really does need to execute in the initial "main" program thread. Donn

2011/7/6 Donn Cave
Quoth =?ISO-8859-1?Q?G=E1bor_Lehel?=
, ... Stated another way: I suspect most GUI libraries don't really actually care that you only execute GUI code from the main OS thread, as much as they care that only one (thread-unsafe) GUI function is being called at any given time. If you only ever call GUI code from the same (main) OS thread, that fulfills this requirement, because an OS thread is only capable of running one library function at a time; alternately, if you only ever call GUI code from the same Haskell thread, that also fulfills this requirement, because one Haskell thread is also only capable of running one library function at a time,
I thought in the present case, the program now works when compiled, but fails when run in GHCi, and we believe that the only difference here is that GHCi took the main thread and put the program, and hence the GUI, in some other thread?
I.e., your requirement is indeed met, per the second alternative, but the program still fails, because this library really does need to execute in the initial "main" program thread.
Hmm. That does seem like a pretty strong "disproof". I wonder if my hypothesis is wrong in general, or if this particular library does in fact have other requirements (thread-local storage or such) (and in this case whether my other assumption was wrong and this is actually the usual case), or if there's something else we're missing.
Donn
-- Work is punishment for failing to procrastinate effectively.

2011/7/6 Gábor Lehel
Hmm. That does seem like a pretty strong "disproof". I wonder if my hypothesis is wrong in general, or if this particular library does in fact have other requirements (thread-local storage or such) (and in this case whether my other assumption was wrong and this is actually the usual case), or if there's something else we're missing.
I don't know about the general case, but OS X does treat the main thread specially here; the (native, not X11) framework sets up the connection to Core Graphics in the main thread before invoking the main program, so you can't make whatever it is (thread local storage seems likely) happen in a different thread. -- brandon s allbery allbery.b@gmail.com wandering unix systems administrator (available) (412) 475-9364 vm/sms

Quoth Brandon Allbery
I don't know about the general case, but OS X does treat the main thread specially here; the (native, not X11) framework sets up the connection to Core Graphics in the main thread before invoking the main program, so you can't make whatever it is (thread local storage seems likely) happen in a different thread.
For one general case, C++ static constructors run prior to main(), so any thread dependency introduced by a static C++ object would target the initial program thread. Donn

On 06/07/11 17:19, Gábor Lehel wrote:
On Wed, Jul 6, 2011 at 5:24 PM, Jason Dagit
wrote: On Wed, Jul 6, 2011 at 8:09 AM, Simon Marlow
wrote: On 06/07/2011 15:42, Jason Dagit wrote:
On Wed, Jul 6, 2011 at 2:23 AM, Simon Marlow
wrote: On 06/07/2011 07:37, Jason Dagit wrote:
On Jul 5, 2011 1:04 PM, "Jason Dagit"
mailto:dagitj@gmail.com> wrote: > > On Tue, Jul 5, 2011 at 12:33 PM, Ian Lynagh mailto:igloo@earth.li> wrote: > > On Tue, Jul 05, 2011 at 08:11:21PM +0100, Simon Marlow wrote: > >> > >> In GHCi it's a different matter, because the main thread is running > >> GHCi itself, and all the expressions/statements typed at the prompt > >> are run in forkIO'd threads (a new one for each statement, in fact). > >> If you want a way to run command-line operations in the main thread, > >> please submit a feature request. I'm not sure it can be done, but > >> I'll look into it. > > > > We already have a way: -fno-ghci-sandbox > > I've removed all my explicit attempts to forkIO/forkOS and passed the > command line flag you mention. I just tried this but it doesn't > change the behavior in my example. I tried it again and discovered that due to an argument parsing bug in cabal-dev that the flag was not passed correctly. I explicitly passed it and verified that it works. Thanks for the workaround. By the way, I did look at the user guide for options like this and didn't see it. Which part of the manual is it in?
Can I still make a feature request for a function to make code run on the original thread? My reasoning is that the code which needs to run on the main thread may appear in a library in which case the developer has no control over how ghc is invoked.
I'm not sure how that would work. The programmer is in control of what the main thread does, not GHC. So in order to implement some mechanism to run code on the main thread, we would need some cooperation from the main thread itself. For example, in gtk2hs the main thread runs an event handler loop which occasionally checks a queue for requests from other threads (at least, I think that's how it works).
What I'm wrestling with is the following. Say I make a GUI library. As author of the GUI library I discover issues like this where the library code needs to execute on the "main" thread. Users of the library expect the typical Haskell environment where you can't tell the difference between threads, and you fork at will. How can I make sure my library works from GHC (with arbitrary user threads) and from GHCI?
As John Lato points out in his email lots of people bump into this without realizing it and don't understand what the problem is. We can try our best to educate everyone, but I have this sense that we could also do a better job of providing primitives to make it so that code will run on the main thread regardless of how people invoke the library.
In my specific case (Cocoa on OSX), it is possible for me to use some Cocoa functions to force things to run on the main thread. From what I've read Cocoa uses pthreads to implement this. I was hoping we could expose something from the RTS code in Control.Concurrent so that it's part of an "official" Haskell API that library writers can assume.
Judging by this SO question, it's easier to implement this in Haskell on top of pthreads than to implement it in C (here I'm assuming GHC's RTS uses pthreads, but I've never checked):
http://stackoverflow.com/questions/6130823/pthreads-perform-function-on-main...
In fact, the it sounds like what Gtk2hs is doing with the postGUI functions.
Right, but usually the way this is implemented is with some cooperation from the main thread. That SO answer explains it - the main thread runs some kind of loop that periodically checks for requests from other threads and services them. I expect that's how it works on Cocoa. So you can't just do this from a library - the main thread has to be in on the game.
Yes. From my perspective (that of a library writer) that's what makes this tricky in GHCi. I need GHCi's cooperation. From GHCi's perspective it's tricky too.
I suppose you might wonder whether the GHC RTS could implement runInMainThread by preempting the main thread and running some different code on it.
Yes, that's roughly what I was wondering about.
There's more than one reason why a (GUI) library might require functions to be called only from the main thread. One is if the library uses thread-local storage, in which case the code needs to run in the right thread to see the right data. I've heard that OpenGL is like this. Another (more common, as far as I know) reason is if (parts of) the library aren't thread safe, and can't handle more than one thread at a time simultaneously calling its functions and mutating its members. I'm not sure if there are other reasons.
Yes, this we know (see the Concurrency/FFI paper I linked earlier).
In the second (thread safety) case, if you preempt the main thread in the middle of whatever it was doing to use it to call some function from the library, the effect would, I think, be the same as if the OS had preempted it to execute some other thread which then called the function, and you would be violating the library's one-thread-at-a-time expectation in pretty much the same exact way. So I don't think you would gain anything useful by doing this. The main thread needs to be interrupted at 'safe points', which is what the event loop lets you do, but the event loop is part of the GUI library, and not part of the GHC runtime, so GHC doesn't know about it and can't tell it what to do - only the library bindings can.
I think you misunderstand what I meant by preemption. I was talking about preempting the Haskell thread, not the OS thread. Haskell threads are preempted by other Haskell threads all the time.
Stated another way: I suspect most GUI libraries don't really actually care that you only execute GUI code from the main OS thread, as much as they care that only one (thread-unsafe) GUI function is being called at any given time.
No, this is not true. Some GUI libraries really have to be called from one specific thread (e.g. Win32). Cheers, Simon
If you only ever call GUI code from the same (main) OS thread, that fulfills this requirement, because an OS thread is only capable of running one library function at a time; alternately, if you only ever call GUI code from the same Haskell thread, that also fulfills this requirement, because one Haskell thread is also only capable of running one library function at a time, even if its execution might jump between different OS threads along the way. (If you were writing code in the library's native language, and as part of your own code for processing an event in the main thread, stopped the main thread, used a different thread to execute some GUI functions, and then returned control to the main thread, I suspect that would also be safe, though there tends not to be any reason to want to do this.)
Basically: In the context of GHC/Haskell, I think you need to separate the concept of "thread of execution", which is what the GUI libraries care about, from the concept of "OS threads", which nearly all of the time correspond to the threads of execution, but in this case, don't. (Or rather, do, but in a very different way from the usual.)
These are impressions I've gained from the reading the docs (such as the paper Simon just linked) and thinking about it. If anyone more knowledgeable sees that I'm mistaken, please correct me.
In theory that's possible, but whether it's a good idea or not is a different matter! I think it amounts to the same thing as the gtk2hs folks have been asking for - multiple Haskell threads bound to the same OS thread.
I'm starting to realize that I don't understand the GHC threading model very well :) I thought that was already possible. I may be mixing GHC's thread model up with other language implementations, but I thought that it had a pool of OS threads and that Haskell threads ran on them as needed. I think what you're saying is that the RTS has bound threads and it has thread pooling, but what it doesn't have is "bound thread pooling" (that is, the combination of being bound and pooled).
runInMainThread then becomes the same as forking a temporary new thread bound to the main OS thread, or temporarily binding the current thread to the main OS thread. If the main OS thread is off making a foreign call (e.g. in the GUI library's main loop) then it can't run any other Haskell threads anyway, and then I have to figure out what to do with all these Haskell threads waiting for their bound OS thread to come back from the foreign call. My guess is that all this would be pretty complex to implement.
Yes it does sound complex. I'd really like help as much as possible. I know very little about GHC internals but perhaps I could take a look at some of the RTS code. Is there some background reading I could do? Perhaps a specific reference to a paper or wiki page?
Still, I'm all for making things easier somehow. At the least, we should have good diagnostics when you're using GHCi and this goes wrong. Although I'm not sure how to do that, I think it's really something the gtk2hs or Cocoa binding needs to implement. Do you have a way to check whether you're on the main thread or not?
pthread_main_np is the only way I've stumbled across: https://www.mirbsd.org/htman/i386/man3/pthread_main_np.htm
Jason
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Quoth Jason Dagit
Yes. From my perspective (that of a library writer) that's what makes this tricky in GHCi. I need GHCi's cooperation. From GHCi's perspective it's tricky too.
It seems to me that ideally, GHCi would do its thing in a child thread, like the extra runtime threads, and let the program execute in the main thread, as in a compiled program. I mean, ideal from the point of view of supporting the general case of library functions that care what the main thread is doing. I'm not saying that's possible - have no idea - but just that where you're dealing with a possibly unconscious and probably poorly documented expectation like that, it's better to not break it in the first place, than to have to try to patch it up at run time. I have been wondering while reading this thread if my Haiku API functions are subject to this restriction - there is an application object that normally runs in main() - but while that would be easy to verify empirically, it wouldn't really tell me what I need to know. A subsequent OS release could easily introduce some thread sensitivity, and I guess if my Haskell programs must run from a child thread under certain circumstances, even if I could make them work I would have to consider that success temporary and provisional. Donn

On Wed, Jul 6, 2011 at 8:09 AM, Simon Marlow
On 06/07/2011 15:42, Jason Dagit wrote:
How can I make sure my library works from GHC (with arbitrary
user threads) and from GHCI?
Right, but usually the way this is implemented is with some cooperation from
the main thread. [...] So you can't just do this from a library - the main thread has to be in on the game. I suppose you might wonder whether the GHC RTS could implement runInMainThread by preempting the main thread and running some different code on it. [...]
I think the real issue is that GHC has a different behavior than GHCi, and I think this causes a lot of difficulties for people working on GUI and other FFI integration. Perhaps it would be possible to reverse the default roles of threads in GHCi: the main thread run user commands, and a second bound thread will process user interrupts and such.

On 06/07/11 17:14, David Barbour wrote:
On Wed, Jul 6, 2011 at 8:09 AM, Simon Marlow
mailto:marlowsd@gmail.com> wrote: On 06/07/2011 15:42, Jason Dagit wrote:
How can I make sure my library works from GHC (with arbitrary
user threads) and from GHCI?
Right, but usually the way this is implemented is with some cooperation from the main thread. [...] So you can't just do this from a library - the main thread has to be in on the game. I suppose you might wonder whether the GHC RTS could implement runInMainThread by preempting the main thread and running some different code on it. [...]
I think the real issue is that GHC has a different behavior than GHCi, and I think this causes a lot of difficulties for people working on GUI and other FFI integration.
Perhaps it would be possible to reverse the default roles of threads in GHCi: the main thread run user commands, and a second bound thread will process user interrupts and such.
Well, GHCi has no main, so it doesn't seem surprising (to me) that it's different. However, if -fno-ghci-sandbox doesn't have any drawbacks we could just make it the default. I don't actually remember why we run each statement in a new thread, I think it just seemed like a prudent thing to do. Cheers, Simon

On Wed, Jul 6, 2011 at 12:52 PM, Simon Marlow
I think the real issue is that GHC has a different behavior than GHCi,
and I think this causes a lot of difficulties for people working on GUI and other FFI integration.
Well, GHCi has no main, so it doesn't seem surprising (to me) that it's
different.
If we start GHCi then run the function called 'main', we should ideally get the same behavior as building with GHC then executing the process. Variations make exploratory programming with GHCi very difficult, especially with concurrent haskell.
However, if -fno-ghci-sandbox doesn't have any drawbacks we could just make it the default.
That sounds good, too. I think it worth looking up what the drawbacks will be. It might be an acceptable trade even if there are minor drawbacks. I would imagine the main benefit of the sandbox is ability to interrupt a task - i.e. job control from the GHCi shell. Regards, Dave

On 06/07/2011 21:11, David Barbour wrote:
On Wed, Jul 6, 2011 at 12:52 PM, Simon Marlow
mailto:marlowsd@gmail.com> wrote: I think the real issue is that GHC has a different behavior than GHCi, and I think this causes a lot of difficulties for people working on GUI and other FFI integration.
Well, GHCi has no main, so it doesn't seem surprising (to me) that it's different.
If we start GHCi then run the function called 'main', we should ideally get the same behavior as building with GHC then executing the process. Variations make exploratory programming with GHCi very difficult, especially with concurrent haskell.
That's a fair point.
However, if -fno-ghci-sandbox doesn't have any drawbacks we could just make it the default.
That sounds good, too. I think it worth looking up what the drawbacks will be. It might be an acceptable trade even if there are minor drawbacks. I would imagine the main benefit of the sandbox is ability to interrupt a task - i.e. job control from the GHCi shell.
Interruption is not affected, as far as I'm aware. Cheers, Simon

On Wed, Jul 6, 2011 at 12:52 PM, Simon Marlow
On 06/07/11 17:14, David Barbour wrote:
On Wed, Jul 6, 2011 at 8:09 AM, Simon Marlow
mailto:marlowsd@gmail.com> wrote: On 06/07/2011 15:42, Jason Dagit wrote:
How can I make sure my library works from GHC (with arbitrary
user threads) and from GHCI?
Right, but usually the way this is implemented is with some cooperation from the main thread. [...] So you can't just do this from a library - the main thread has to be in on the game. I suppose you might wonder whether the GHC RTS could implement runInMainThread by preempting the main thread and running some different code on it. [...]
I think the real issue is that GHC has a different behavior than GHCi, and I think this causes a lot of difficulties for people working on GUI and other FFI integration.
Perhaps it would be possible to reverse the default roles of threads in GHCi: the main thread run user commands, and a second bound thread will process user interrupts and such.
Well, GHCi has no main, so it doesn't seem surprising (to me) that it's different.
However, if -fno-ghci-sandbox doesn't have any drawbacks we could just make it the default. I don't actually remember why we run each statement in a new thread, I think it just seemed like a prudent thing to do.
+1 for this change. I'm not sure how we would know if there are drawbacks. Jason

On 06/07/2011 21:19, Jason Dagit wrote:
On Wed, Jul 6, 2011 at 12:52 PM, Simon Marlow
wrote: On 06/07/11 17:14, David Barbour wrote:
On Wed, Jul 6, 2011 at 8:09 AM, Simon Marlow
mailto:marlowsd@gmail.com> wrote: On 06/07/2011 15:42, Jason Dagit wrote:
How can I make sure my library works from GHC (with arbitrary
user threads) and from GHCI?
Right, but usually the way this is implemented is with some cooperation from the main thread. [...] So you can't just do this from a library - the main thread has to be in on the game. I suppose you might wonder whether the GHC RTS could implement runInMainThread by preempting the main thread and running some different code on it. [...]
I think the real issue is that GHC has a different behavior than GHCi, and I think this causes a lot of difficulties for people working on GUI and other FFI integration.
Perhaps it would be possible to reverse the default roles of threads in GHCi: the main thread run user commands, and a second bound thread will process user interrupts and such.
Well, GHCi has no main, so it doesn't seem surprising (to me) that it's different.
However, if -fno-ghci-sandbox doesn't have any drawbacks we could just make it the default. I don't actually remember why we run each statement in a new thread, I think it just seemed like a prudent thing to do.
+1 for this change. I'm not sure how we would know if there are drawbacks.
Now that I think about it, the original reason may have been that if the computation grows a large stack, having it in a separate thread means GHCi can recover the memory. However we have been able to recover stack memory for some time now, so that is no longer an issue. Cheers, Simon

On Thu, Jul 7, 2011 at 12:41 AM, Simon Marlow
On 06/07/2011 21:19, Jason Dagit wrote:
On Wed, Jul 6, 2011 at 12:52 PM, Simon Marlow
wrote: On 06/07/11 17:14, David Barbour wrote:
On Wed, Jul 6, 2011 at 8:09 AM, Simon Marlow
mailto:marlowsd@gmail.com> wrote: On 06/07/2011 15:42, Jason Dagit wrote:
How can I make sure my library works from GHC (with arbitrary
user threads) and from GHCI?
Right, but usually the way this is implemented is with some cooperation from the main thread. [...] So you can't just do this from a library - the main thread has to be in on the game. I suppose you might wonder whether the GHC RTS could implement runInMainThread by preempting the main thread and running some different code on it. [...]
I think the real issue is that GHC has a different behavior than GHCi, and I think this causes a lot of difficulties for people working on GUI and other FFI integration.
Perhaps it would be possible to reverse the default roles of threads in GHCi: the main thread run user commands, and a second bound thread will process user interrupts and such.
Well, GHCi has no main, so it doesn't seem surprising (to me) that it's different.
However, if -fno-ghci-sandbox doesn't have any drawbacks we could just make it the default. I don't actually remember why we run each statement in a new thread, I think it just seemed like a prudent thing to do.
+1 for this change. I'm not sure how we would know if there are drawbacks.
Now that I think about it, the original reason may have been that if the computation grows a large stack, having it in a separate thread means GHCi can recover the memory. However we have been able to recover stack memory for some time now, so that is no longer an issue.
Then by all means, please make -fno-ghci-sandbox the default! :) Thanks Jason

On 07/07/2011 08:41, Simon Marlow wrote:
On 06/07/2011 21:19, Jason Dagit wrote:
On Wed, Jul 6, 2011 at 12:52 PM, Simon Marlow
wrote: On 06/07/11 17:14, David Barbour wrote:
On Wed, Jul 6, 2011 at 8:09 AM, Simon Marlow
mailto:marlowsd@gmail.com> wrote: On 06/07/2011 15:42, Jason Dagit wrote:
How can I make sure my library works from GHC (with arbitrary
user threads) and from GHCI?
Right, but usually the way this is implemented is with some cooperation from the main thread. [...] So you can't just do this from a library - the main thread has to be in on the game. I suppose you might wonder whether the GHC RTS could implement runInMainThread by preempting the main thread and running some different code on it. [...]
I think the real issue is that GHC has a different behavior than GHCi, and I think this causes a lot of difficulties for people working on GUI and other FFI integration.
Perhaps it would be possible to reverse the default roles of threads in GHCi: the main thread run user commands, and a second bound thread will process user interrupts and such.
Well, GHCi has no main, so it doesn't seem surprising (to me) that it's different.
However, if -fno-ghci-sandbox doesn't have any drawbacks we could just make it the default. I don't actually remember why we run each statement in a new thread, I think it just seemed like a prudent thing to do.
+1 for this change. I'm not sure how we would know if there are drawbacks.
Now that I think about it, the original reason may have been that if the computation grows a large stack, having it in a separate thread means GHCi can recover the memory. However we have been able to recover stack memory for some time now, so that is no longer an issue.
I discovered the real reason we run statements in a separate thread: the GHCi debugger. If the computation stops at a breakpoint, then we have to save the context and resume GHCi, which can only be done if the computation was running in a separate thread. The way things are arranged right now, each stopped computation gets a different thread. What you want is for all these to be on the main thread. It might be possible to arrange this, but it would require some non-trivial reorganisation in the implementation of interactive evaluation (compiler/main/InteractiveEval.hs). I'm going to have to leave this for now, sorry. In the meantime you'll still be able to use -fno-ghci-sandbox, but the debugging features in GHCi will be disabled. Cheers, Simon

On Tue, Jul 12, 2011 at 2:58 AM, Simon Marlow
I discovered the real reason we run statements in a separate thread: the GHCi debugger. If the computation stops at a breakpoint, then we have to save the context and resume GHCi, which can only be done if the computation was running in a separate thread.
The way things are arranged right now, each stopped computation gets a different thread. What you want is for all these to be on the main thread. It might be possible to arrange this, but it would require some non-trivial reorganisation in the implementation of interactive evaluation (compiler/main/**InteractiveEval.hs). I'm going to have to leave this for now, sorry. In the meantime you'll still be able to use -fno-ghci-sandbox, but the debugging features in GHCi will be disabled.
Cheers, Simon
Thanks for looking into it, Simon. Regards, Dave
participants (6)
-
Brandon Allbery
-
David Barbour
-
Donn Cave
-
Gábor Lehel
-
Jason Dagit
-
Simon Marlow