RE: [HOpenGL] HOpenGL and --enable-threaded-rts

Has anyone already thought about how to solve this problem? I'm thinking about adding hooks to the RTS (in grabCapability, releaseCapability and scheduleThread_) which would be used for setting up the correct thread-local state whenever Haskell execution "switches" to a different OS thread. Those hook routines would have to be written in C and would be platform-specific most of the time. It's not a nice solution, but it's the only one I can think of at this time. Unless someone comes up with a better idea _quickly_, I'll try it out and then report how ugly it really is... :-)
I can't see a nice solution to this problem - it really invalidates one of the key assumptions in the threaded implementation of the RTS, namely that it doesn't matter which OS thread we use to execute Haskell code. I suspect that a "safe" foreign import could be made to switch threads to the right OS thread before entering C land, but that's way too much overhead to impose on every single FFI call from Haskell. Yes, my guess is that this will probably have to be done by manipulating the thread-local state in the RTS - grab the current thread-local state whenever a call is made into Haskell, and whenever we run a Haskell thread we have to set the appropriate thread-local state. Perhaps it should be stored in the TSO and inherited by child threads too. The trouble is that there isn't a single object representing the whole thread-local state. Does OpenGL use pthread_getspecific() and pthread_setspecific() to access its thread-local state? Cheers, Simon

SimonM:
Yes, my guess is that this will probably have to be done by manipulating the thread-local state in the RTS - grab the current thread-local state whenever a call is made into Haskell, and whenever we run a Haskell thread we have to set the appropriate thread-local state. Perhaps it should be stored in the TSO and inherited by child threads too.
The trouble is that there isn't a single object representing the whole thread-local state. Does OpenGL use pthread_getspecific() and pthread_setspecific() to access its thread-local state?
This sounds like a lot of work and a porting nightmare (what do you mean Linux/Win32/HPUX/... doesn't have thread manipulation function X, it's available on FreeBSD/Win32/... What if there are other forms of thread-local state (e.g., errno)? What about setjmp/longjmp?). The only viable solution I can see is to provide a way to capture the calling thread (as a first class entity) when you call into Haskell and to explicitly specify whcih thread to use when you call out from Haskell. (Hmmm, sounds like callcc for C :-)) Off the top of my head, this might look like this: foreign export "static capture_thread" mycallback :: HsThread -> Int -> Char which would provide a C function with this prototype: HsChar mycallback(HsInt); and, on the callout side: foreign import "static with_thread" foo :: HsThread -> Float -> IO Double which would invoke a C function with this type: HsDouble foo(HsFloat); -- Alastair Reid reid@cs.utah.edu http://www.cs.utah.edu/~reid/

Simon Marlow wrote:
The trouble is that there isn't a single object representing the whole thread-local state. Does OpenGL use pthread_getspecific() and pthread_setspecific() to access its thread-local state?
The libGL supplied with XFree86 uses xthread_{get,set}_specific. These
are macros which expand to the appropriate native function, one of:
thr_{set,get}specific
Tls{Set,Get}Value
tis_{set,get}specific
pthread_{set,get}specific
The XFree86 libGL source code carries SGI copyright notices, so it's a
good bet that that other Unix OpenGL implementations are similar.
Mesa's libGL has a similar abstraction, _glthread_{Get,Set}TSD. These
are functions which call the appropriate native function. Mesa
supports the thr_*, pthread_* and Tls* functions, but not the tis_*
functions; however, it also has versions which use the xthread_*
macros.
I have no idea as to the situation on Windows.
--
Glynn Clements
participants (3)
-
Alastair Reid
-
Glynn Clements
-
Simon Marlow