SDL_WaitEvent not waking up properly? |
SDL_WaitEvent not waking up properly? |
marksibly
|
Ok, just found the SDL_Delay(10) in SDL_WaitEventTimeout()!
This is a bit disappointing. I had assumed all the event queue stuff was properly synchronized, but this throws a big nasty 10ms spanner in the works! Oh well, at least I know what's going on now. On Sun, May 22, 2016 at 10:26 AM, Mark Sibly wrote:
|
|||||||||||||
|
Re: SDL_WaitEvent not waking up properly? |
rtrussell
|
I second that! I really miss 'proper' thread synchronization capabilities; my event-polling loop wastes a lot of CPU time spinning with no delay to achieve an acceptable latency. Would it not be possible for SDL to call WaitForSingleObject() in Windows or pthread_cond_timedwait() in Linux? Richard. |
|||||||||||||
|
SDL_WaitEvent not waking up properly? |
marksibly
|
Actually, I sort of got this going using a semaphore - it's as ugly as hell but seems to work in my code. Can share the code if you want, but it might be a bit dodgy.
There also appears to be a bug in the timer logic - it 'skips' every now and then if a tick happens at a certain place in the timer thread loop. Perhaps the timer aren't designed to be that accurate, but this prevented me implementing a 60hz timer via the timer returning 16,17,17,16,17,17 etc. intervals. I've got a quick 'n' dirty fix for this too, but it probably needs attention from someone who knows what they're doing (if it is in fact a bug). On Sun, May 22, 2016 at 9:46 PM, rtrussell wrote:
|
|||||||||||||
|
Re: SDL_WaitEvent not waking up properly? |
rtrussell
|
I use a semaphore too, but only as a means of signalling back to the 'sending' thread that the event has been read (I need a functionality like SendMessage in Windows). I suppose the key question is whether SDL_SemWaitTimeout uses a more efficient waiting mechanism (in terms of latency and CPU usage) than SDL_WaitEventTimeout. If it does then I might be able to improve on my existing approach, but in that case why wouldn't SDL do the same itself? Richard. |
|||||||||||||
|
SDL_WaitEvent not waking up properly? |
marksibly
|
My goal was basically to make WaitEvent block properly instead of 'spin'. I still like to do all my coding on the 'main' thread, so the timer callbacks just push a user event and return very quickly. But this does mean WaitEvent needs to be precise and not just delay(10) arbitrarily. I got this going by posting to a semaphore in peepevents just after any events are added, and doing a wait on this semaphore in WaitEvent instead of the delay(10) when there are no events. The semaphore wait will often return immediately here because I'm posting in peepevents more than I need to, but that's OK because it'll eventually 'flush' the semaphore and block for real. Not 100% nice, but better than just thrashing delay(0). The real fix is probably to only post when an event as added to an empty queue. The semaphore will still probably spin sometimes depending on how events are being pulled from the queue, but it should be generally better.
Good question. Looking at the code, the windows one does, but the linux one only does if you have #defined HAVE_SEM_TIMEDWAIT - which I haven't done (yet)! But the above fix doesn't even need a timed semaphore now that I think about it... On Mon, May 23, 2016 at 8:14 PM, rtrussell wrote:
|
|||||||||||||||||
|
Re: SDL_WaitEvent not waking up properly? |
rtrussell
|
Presumably the HAVE_SEM_TIMEDWAIT is only useful if you're rebuilding SDL from the source. Normally I will be using the pre-built SDL2.DLL in Windows and libsdl2.so in Linux. So I guess whether I can take advantage of a more efficient wait in SDL_SemWaitTimeout depends on how the standard Linux packages are compiled, and indeed what the reason for the #define is in the first place. Do you know?
It would in my case because I'm creating my renderer with SDL_RENDERER_PRESENTVSYNC so once a frame I need it to spin in SDL_RenderPresent rather than waiting for an event to arrive. If there was some way of posting a user event synchronously with (and slightly before) the Vsync it would be different, but I don't think there is. Richard. |
|||||||||||||||
|