Timers and multithreading

Hi,

I’ve been playing around with SDL_Timers stuff both under Linux and
Windows and I’m a bit confused as nothing I’ve done works well.

I mean I did a simple test program making a sprite moving and the
behaviour is really strange.

On the Pentium 200 of friend it workd perfectly under Windows 98 SDL
1.1.4

On the Athlon 800 it crashes under Windows98 SDL 1.1.6

And it fails too on my K6-2 450 under Linux and SDL 1.1.6

In an another program, the app is locked as soon as I Init SDL by
passing SDL_INIT_TIMER.

So I just want to know how is done timers functions internally.

I asked on the channel and it seems that lots of people are confused
about the way to use Timers or thread.

Lawouach

In an another program, the app is locked as soon as I Init SDL by
passing SDL_INIT_TIMER.

that doesn’t sound right — please post a minimal failing example,
and the exact circumstances of the crash (platform, SDL version, etc)

So I just want to know how is done timers functions internally.

Timers may be implemented as signals or as threads internally, so there
isn’t much you can do inside a timer handle portably. A good solution
is to just post a user-defined event in your handler, and do the actual
work from your main event loop instead

Mattias Engdeg?rd wrote:

In an another program, the app is locked as soon as I Init SDL by
passing SDL_INIT_TIMER.

that doesn’t sound right — please post a minimal failing example,
and the exact circumstances of the crash (platform, SDL version, etc)

I’ll do it as soon as possible…

So I just want to know how is done timers functions internally.

Timers may be implemented as signals or as threads internally, so there
isn’t much you can do inside a timer handle portably. A good solution
is to just post a user-defined event in your handler, and do the actual
work from your main event loop instead

I remember you told me that solution on the irc and I use it but that
solution isn’t good enough for me so that why I’m here to insist on the
SDL_Timers.

Moreover i know it’s difficult to create non-machine dependant timers
and i just want to know the limits of SDL implementation about that !

I remember you told me that solution on the irc and I use it but that
solution isn’t good enough for me so that why I’m here to insist on the
SDL_Timers.

timers probably aren’t the right solution for you then

Moreover i know it’s difficult to create non-machine dependant timers
and i just want to know the limits of SDL implementation about that !

For portable code you cannot do anything from a timer handler
which you can’t do from a Unix signal handler or from a thread.
This includes:

  • calling any SDL function, except SDL_PushEvent()
  • most other library function calls (stdio, memory allocation etc)
    because of asynch signal reentrancy problems

As a matter of fact I’m not convinced that even SDL_PushEvent() is
signal-safe but that should be fixed

For more about the limitations of signals and threads, see any good unix
text, such as Advanced Programming in the Unix Environment by Richard
Stevens

“Mattias Engdeg?rd”

As a matter of fact I’m not convinced that even SDL_PushEvent() is
signal-safe but that should be fixed

:o !!

mattias, go easy on my heart!
heh, well i have assumed this was safe and have been calling it as
such. haven’t noticed anything uncanny on win and linux platforms,
but maybe i’m just gettin lucky?

i glanced at the code and saw it grabbing some thread locks and
assumed it was safe without digging in.

“Mattias Engdeg?rd”

As a matter of fact I’m not convinced that even SDL_PushEvent() is
signal-safe but that should be fixed

:o !!

mattias, go easy on my heart!
heh, well i have assumed this was safe and have been calling it as
such. haven’t noticed anything uncanny on win and linux platforms,
but maybe i’m just gettin lucky?

No, you’re fine. What Mattias is referring to is that if a second
timer interrupt happens while the first handler is still running,
then some environments will fire off a second handler which would
deadlock with the first in any locking code. SDL sets up signal
handlers with flags that tell the OS to block further signals while
the signal handler is running. Any theoretical DOS port would do
the same.

Linux, Win32, and BeOS platforms implement timers as a separate thread
periodically calling timer callbacks, so the signal issue isn’t a
problem.

See ya,
-Sam Lantinga, Lead Programmer, Loki Entertainment Software

No, you’re fine. What Mattias is referring to is that if a second
timer interrupt happens while the first handler is still running,
then some environments will fire off a second handler which would
deadlock with the first in any locking code.

No, I was concerned about the re-entrancy of SDL_PushEvent() itself
and other associated event code. It’s protected from threads by a
mutex but not from asynch signals

Linux, Win32, and BeOS platforms implement timers as a separate thread
periodically calling timer callbacks, so the signal issue isn’t a
problem.

I’ve noticed that, but since the signal code was there and presumably
functional it seems dangerous to rely on threads being used. Perhaps
we need a way to find out whether this is true, so a game that relies
on it can print out a warning if signals are used

No, you’re fine. What Mattias is referring to is that if a second
timer interrupt happens while the first handler is still running,
then some environments will fire off a second handler which would
deadlock with the first in any locking code.

No, I was concerned about the re-entrancy of SDL_PushEvent() itself
and other associated event code. It’s protected from threads by a
mutex but not from asynch signals

nod signals are dangerous in any application. It took me a long time
to learn that, but for example what happens when you call malloc() from
within a signal handler that interrupts a call to malloc()? You can get
mystery heap corruption. Really the only safe thing to do from signal
handlers is set global variables, and then not if they would normally
need to be protected by mutexes in multi-threaded code.

See ya,
-Sam Lantinga, Lead Programmer, Loki Entertainment Software

Really the only safe thing to do from signal
handlers is set global variables, and then not if they would normally
need to be protected by mutexes in multi-threaded code.

this is why I would like SDL_PushEvent to be async-signal-safe, since it
does just that — schedules useful work to be done outside the handler.
I’ll have a look at the code and see what I can do