The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
Another topic about threading
Muf


Joined: 16 May 2013
Posts: 2
First off, I know the general consensus on this board seems to be "do everything in the main thread because you don't need threading and everything will break otherwise". I'm not here to get that thrown at me, it's 2013, my CPU has eight cores and I should be able to thread things if I want to.

That said, I'm running into a problem. Or rather, my friend who is on Linux is running into it. On Windows, everything runs perfectly.

I'm writing an arcade-style game, and it works like this:

There are three threads:
- The main thread handles SDL events and gathers input
- The game thread processes game logic and generates a list of high-level drawing commands
- The render thread reads the list of objects to be drawn and calls OpenGL to render them

The reason these are running in separate threads is because the input thread runs at some user-configurable poll rate (anywhere between 60Hz and 1000Hz - some players are very picky about input lag and whatnot), the game thread runs at a fixed 60Hz, and the render thread tries to run at 60Hz but realistically can't be expected to do so 100% of the time.

Now, on Windows this works in practice as well I would've hoped -- all the thread synchronisation is done with opportunistic sleeping so CPU usage is very low while input is always up-to-date, and every processed frame gets rendered.

However, on Linux, everything seems to kind of break down after a couple of seconds. First warnings that the nvidia XGL driver is missing pop up, and a while later the whole thing segfaults (I'll amend this post later with some more detailed info on how and where it crashes).

Reading around, I've read things like "X11 isn't thread-safe". Windows isn't exactly thread-safe either, but as long as you don't go crazy, you usually won't run into much problems. I've also read things like that you should make a hidden window in the main thread, make an OpenGL context in it, and then make a new window in your rendering thread and transfer the context to it, or another topic on the forum here that suggests making a window, then calling SDL_GL_MakeCurrent(window, NULL), then making an OpenGL context and, in the rendering thread, making it current. Neither of these options work at all for me, one gives me a broken OpenGL window that doesn't pump its message queue, and the other fails to initialise OpenGL (which I would expect with such a strange ordering of calls).

Instead, what I do, and what works on Windows, but apparently not on Linux, is this:

From the main thread, initialise SDL, make a window and initialise OpenGL. After setting up some basic things like GLEW, clear colour, shaders, the projection, etc. the main thread calls SDL_GL_MakeCurrent(window, NULL) and launches the render thread. The render thread then calls SDL_GL_MakeCurrent(window, context) and picks up where the main thread left off.

Is there anything obviously wrong about this way of doing things and/or can I fix the weird behaviour on Linux without overthrowing my entire architecture? Before, when I was on SDL 1.2, I had to have rendering and input/events share the main thread and it was kind of crowded. I was so happy to move to SDL 2.0 and have proper threading so I could free up the main thread. Sad
Muf


Joined: 16 May 2013
Posts: 2
Nevermind, turns out it was a miscommunication sprinkled with some forgetfulness on my part :lol:

The segfault/driver errors only occurred when quitting the game, and armed with that information I quickly localised it to a destructor that didn't properly wait for the thread to exit and reacquire the context before trying to clean up :oops:

Move along now, nothing to see here!
Nathaniel J Fries


Joined: 30 Mar 2010
Posts: 444
I was going to say, Xlib supports multi-threading better than Windows API does.