[Haskell-cafe] Compiled program using OpenGL fails to trigger GPU switch on Mac, but works in GHCi

Jesper Särnesjö sarnesjo at gmail.com
Mon Mar 18 14:19:28 CET 2013


On Mon, Mar 18, 2013 at 11:27 AM, Brandon Allbery <allbery.b at gmail.com> wrote:
> On Sun, Mar 17, 2013 at 7:58 PM, Jason Dagit <dagitj at gmail.com> wrote:
>> On Sat, Mar 16, 2013 at 6:53 PM, Jesper Särnesjö <sarnesjo at gmail.com wrote:
>>>
>>> To be clear, I think this isn't really an OpenGL problem, but rather
>>> one related to FFI or event handling. If anyone could explain to me,The
>>> release notes for 7.0.1 said this about that flag:
>>
>> There is a new -fno-ghci-sandbox flag, which stops GHCi running
>> computations in a separate thread. In particular, this is useful for GLUT on
>> OS X, which only works if being run on the main thread.
>
> Worth noting is that Jesper said it *works* in ghci, and fails when
> compiled....

Interestingly, running the program in GHCi with the -fno-ghci-sandbox
flag, causes it to misbehave in the same way as when compiled:

    $ ghci -fno-ghci-sandbox -lglfw glfw_test.hs
    [...]
    *Main> main
    Apple Software Renderer

This is starting to smell like a concurrency-related issue, then. I
should note that the GLFW library does use multiple OS threads, and I
know from previous experience that Mac OS X is fussy about GUI actions
being run on the main thread. The curious thing here, of course, is
that the behavior I am seeing is the exact opposite of that mentioned
in the release notes.

I've found some interesting reading material on how GHC handles the
interaction of concurrency and FFI, in particular the paper "Extending
the Haskell Foreign Function Interface with Concurrency" by Simon
Marlow and Simon Peyton-Jones [1], which even brings up OpenGL as an
example of why a programmer must be able to "specify that a related
group of foreign calls are all made by the same OS thread". I haven't
yet had the time to dig too deep into this, but I have tried a few
things:

* I've compiled the program with -threaded (as suggested by John
Lato), with the foreign functions marked as safe and unsafe (as
suggested by Carter Schonwald).
* I've checked that the main thread of my Haskell program is bound to
an OS thread [2], which it is when using the threaded runtime. I've
also tried explicitly running the block of foreign calls in a bound
thread [3].
* I've made sure that there is only one GLFW library on my machine for
-lglfw to link with, and that it is the very same library my C program
links with.

None of the above helped. However, I will keep investigating and see
what I find.

As I final note, I did learn that the GHC runtime generates SIGVTALRM
signals to cause the scheduler to switch contexts [4][5]. Perhaps this
prevents GLFW from running properly? Looks like I'll need to brush up
on my dtrace.

-- 
Jesper Särnesjö
http://jesper.sarnesjo.org/

[1] http://community.haskell.org/~simonmar/papers/conc-ffi.pdf
[2] http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Concurrent.html#v:isCurrentThreadBound
[3] http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Concurrent.html#v:runInBoundThread
[4] http://joeyh.name/blog/entry/ghc_threaded_runtime_gotchas/
[5] http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Signals#RTSAlarmSignalsandForeignLibraries



More information about the Haskell-Cafe mailing list