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
SDL_WaitEvent not waking up properly?
marksibly


Joined: 02 Jul 2015
Posts: 14
Hi,

Windows 10 SDL2 user here!


I'm using an SDL timer to SDL_PushEvent a user event to the event queue, but this does not appear to be 'waking up' SDL_WaitEvent immediately - there's some weird delay between when I push the event (from the timer thread) and when SDL_WaitEvent wakes up.


However, if I replace this:


SDL_WaitEvent( Null );
ProcessEvents();  //polls/pops events



...with this...


SDL_Delay(1);
ProcessEvents();


It all starts to work properly, ie: timer user events are processed immediately.


With SDL_WaitEvent, the delivery of the user event gets 'delayed' by some amount of time - or more precisely, appears to be 'quantized' to 10ms-ish.


I have tried both SDL_PushEvent and SDL_PeepEvents from the timer thread, same result.


Is this expected behaviour of SDL_WaitEvent? Does it always wait at least 10ms or something? Can it not be interrupted by pushing an event?


Bye!
Mark
SDL_WaitEvent not waking up properly?
marksibly


Joined: 02 Jul 2015
Posts: 14
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:
Quote:
Hi,

Windows 10 SDL2 user here!


I'm using an SDL timer to SDL_PushEvent a user event to the event queue, but this does not appear to be 'waking up' SDL_WaitEvent immediately - there's some weird delay between when I push the event (from the timer thread) and when SDL_WaitEvent wakes up.


However, if I replace this:


SDL_WaitEvent( Null );
ProcessEvents();  //polls/pops events



...with this...


SDL_Delay(1);
ProcessEvents();


It all starts to work properly, ie: timer user events are processed immediately.


With SDL_WaitEvent, the delivery of the user event gets 'delayed' by some amount of time - or more precisely, appears to be 'quantized' to 10ms-ish.


I have tried both SDL_PushEvent and SDL_PeepEvents from the timer thread, same result.


Is this expected behaviour of SDL_WaitEvent? Does it always wait at least 10ms or something? Can it not be interrupted by pushing an event?


Bye!
Mark




Re: SDL_WaitEvent not waking up properly?
rtrussell


Joined: 10 Feb 2016
Posts: 88
marksibly wrote:
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!

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


Joined: 02 Jul 2015
Posts: 14
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:
Quote:



marksibly wrote:

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!



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 mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Re: SDL_WaitEvent not waking up properly?
rtrussell


Joined: 10 Feb 2016
Posts: 88
marksibly wrote:
Actually, I sort of got this going using a semaphore

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


Joined: 02 Jul 2015
Posts: 14
Quote:
I use a semaphore too, but only as a means of signalling back to the 'sending' thread that the event has been read

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.


Quote:
I suppose the key question is whether SDL_SemWaitTimeout uses a more efficient waiting mechanism



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:
Quote:



marksibly wrote:

Actually, I sort of got this going using a semaphore



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 mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Re: SDL_WaitEvent not waking up properly?
rtrussell


Joined: 10 Feb 2016
Posts: 88
marksibly wrote:
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)!

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?

Quote:
But the above fix doesn't even need a timed semaphore now that I think about it...

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.