Proposal: SDL_PARANOIA and SDL_MULTITHREADED

Add a define that enables additional checks in SDL functions.
SDL_PARANOIA == 0 disables all additional checks,
SDL_PARANOIA == 1 enables checks for common errors,
SDL_PARANOIA == 2 enables checks for rare errors or errors that occur
only in extreme situations (such as counter/timer roll over, etc),
SDL_PARANOIA == 3 enables checks for errors caused by programming
errors in the client application (such as passing an invalid mouse
id),
SDL_PARANOIA == 4 enables checks for things which should be impossible
(and therefore indicate bugs in SDL itself).

When debugging SDL, use SDL_PARANOIA == 4.
When debugging a user program, use a libSDL built with SDL_PARANOIA == 3.
In situations where stability and portability is more important than
speed, release your program with a libSDL built with SDL_PARANOIA ==
2.
Usually, you should release your program with a libSDL compiled with
SDL_PARANOIA == 1.
If speed is more important than stability and portability, compile
your program with a libSDL built with SDL_PARANOIA == 0.

Add an additional define to enable additional checks and locks for
multithreaded applications.
SDL_MULTITHREADED == 0 disables support for multithreading,
SDL_MULTITHREADED == 1 enables basic support for multithreaded applications,
SDL_MULTITHREADED == 2 enables additional multithreading support.

Certain checks could then be wrapped by both SDL_MULTITHREADED and SDL_PARANOIA.

Certain functions may behave quite differently with SDL_MULTITHREADED
== 2. For example, in a multithreaded application on Windows you
might need to create a separate thread to handle window messages, then
implement SDL_WaitEventTimeout() using a semaphore.

Like this:

int
SDL_WaitEventTimeout(SDL_Event * event, int timeout)
{
return (SDL_SemWaitTimeout(event_sem, timeout) == 0 &&
SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS) == 1);
}

SDL_PeepEvents would then need to implement a lock on the event queue.
SDL_PumpEvents would either not be necessary, or could be implemented
using a condition variable.

A minor comment - how about making SDL_PARANOIA a bit field? In particular,
you may want your #3 and #4 without #2, for example.

–GabrielOn Tue, Nov 10, 2009 at 4:01 PM, Kenneth Bull wrote:

Add a define that enables additional checks in SDL functions.
SDL_PARANOIA == 0 disables all additional checks,
SDL_PARANOIA == 1 enables checks for common errors,
SDL_PARANOIA == 2 enables checks for rare errors or errors that occur
only in extreme situations (such as counter/timer roll over, etc),
SDL_PARANOIA == 3 enables checks for errors caused by programming
errors in the client application (such as passing an invalid mouse
id),
SDL_PARANOIA == 4 enables checks for things which should be impossible
(and therefore indicate bugs in SDL itself).

When debugging SDL, use SDL_PARANOIA == 4.
When debugging a user program, use a libSDL built with SDL_PARANOIA == 3.
In situations where stability and portability is more important than
speed, release your program with a libSDL built with SDL_PARANOIA ==
2.
Usually, you should release your program with a libSDL compiled with
SDL_PARANOIA == 1.
If speed is more important than stability and portability, compile
your program with a libSDL built with SDL_PARANOIA == 0.

Add an additional define to enable additional checks and locks for
multithreaded applications.
SDL_MULTITHREADED == 0 disables support for multithreading,
SDL_MULTITHREADED == 1 enables basic support for multithreaded
applications,
SDL_MULTITHREADED == 2 enables additional multithreading support.

Certain checks could then be wrapped by both SDL_MULTITHREADED and
SDL_PARANOIA.

Certain functions may behave quite differently with SDL_MULTITHREADED
== 2. For example, in a multithreaded application on Windows you
might need to create a separate thread to handle window messages, then
implement SDL_WaitEventTimeout() using a semaphore.

Like this:

int
SDL_WaitEventTimeout(SDL_Event * event, int timeout)
{
return (SDL_SemWaitTimeout(event_sem, timeout) == 0 &&
SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS) == 1);
}

SDL_PeepEvents would then need to implement a lock on the event queue.
SDL_PumpEvents would either not be necessary, or could be implemented
using a condition variable.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

2009/11/10 Gabriel Gambetta :

A minor comment - how about making SDL_PARANOIA a bit field? In particular,
you may want your #3 and #4 without #2, for example.

I think 3 and 4 pretty much have to include 2, since a programming
error could produce a situation similar to a counter roll over, etc.
Bad programming may cause an otherwise rare error to occur more often.
Likewise, 2 must include 1 to avoid mistaking a common error for a
less common one, and 4 must include 3 because SDL functions call each
other, that is, SDL is it’s own client application.

Keep in mind that I’m talking about internal checks that occur
whenever an SDL function is called, not a test suite.

Overall I like the idea.

My native paranoia is level 3. I’d never want to release a library
publicly that didn’t have that level of checking.

It might be worth having one more level of “assume the client code is
correct and only check things that might normally fail”, but in
general error checking doesn’t impact the performance of SDL functions
that much, so finer granularity than that probably isn’t necessary.

Having a super paranoid level is a great idea, and will probably catch
a bunch of conditions we’re not expecting.

I’m a little less sold on the multi-threading levels. Formally
supporting arbitrary multi-threading greatly increases the complexity
of the code and is impossible with some platforms’ system libraries.

Both of these are hefty endeavors beyond what I have time to do right
now. Are you interested in combing through the code and implementing
them?On Tue, Nov 10, 2009 at 10:01 AM, Kenneth Bull wrote:

Add a define that enables additional checks in SDL functions.
SDL_PARANOIA == 0 disables all additional checks,
SDL_PARANOIA == 1 enables checks for common errors,
SDL_PARANOIA == 2 enables checks for rare errors or errors that occur
only in extreme situations (such as counter/timer roll over, etc),
SDL_PARANOIA == 3 enables checks for errors caused by programming
errors in the client application (such as passing an invalid mouse
id),
SDL_PARANOIA == 4 enables checks for things which should be impossible
(and therefore indicate bugs in SDL itself).

When debugging SDL, use SDL_PARANOIA == 4.
When debugging a user program, use a libSDL built with SDL_PARANOIA == 3.
In situations where stability and portability is more important than
speed, release your program with a libSDL built with SDL_PARANOIA ==
2.
Usually, you should release your program with a libSDL compiled with
SDL_PARANOIA == 1.
If speed is more important than stability and portability, compile
your program with a libSDL built with SDL_PARANOIA == 0.

Add an additional define to enable additional checks and locks for
multithreaded applications.
SDL_MULTITHREADED == 0 disables support for multithreading,
SDL_MULTITHREADED == 1 enables basic support for multithreaded applications,
SDL_MULTITHREADED == 2 enables additional multithreading support.

Certain checks could then be wrapped by both SDL_MULTITHREADED and SDL_PARANOIA.

Certain functions may behave quite differently with SDL_MULTITHREADED
== 2. ?For example, in a multithreaded application on Windows you
might need to create a separate thread to handle window messages, then
implement SDL_WaitEventTimeout() using a semaphore.

Like this:

int
SDL_WaitEventTimeout(SDL_Event * event, int timeout)
{
? ?return (SDL_SemWaitTimeout(event_sem, timeout) == 0 &&
SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS) == 1);
}

SDL_PeepEvents would then need to implement a lock on the event queue.
SDL_PumpEvents would either not be necessary, or could be implemented
using a condition variable.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


-Sam Lantinga, Founder and President, Galaxy Gameworks LLC

2009/11/12 Sam Lantinga :

Overall I like the idea.

My native paranoia is level 3. ?I’d never want to release a library
publicly that didn’t have that level of checking.

For releasing software (other than development libraries), I’d
probably aim for 2, but if I’m making a utility, demo or test that
nobody else is likely to see or that I know will be running on a well
configured system, I might want to aim lower. During development, I’d
want 3 or 4.

It might be worth having one more level of “assume the client code is
correct and only check things that might normally fail”, but in
general error checking doesn’t impact the performance of SDL functions
that much, so finer granularity than that probably isn’t necessary.

Having a super paranoid level is a great idea, and will probably catch
a bunch of conditions we’re not expecting.

I’m a little less sold on the multi-threading levels. ?Formally
supporting arbitrary multi-threading greatly increases the complexity
of the code and is impossible with some platforms’ system libraries.

Having a flag to turn multithreading OFF would probably be an
advantage on such systems and the same flag (in SDL_config.h) would
also let the client application know it’s not available.

Adding multithreading support to the video subsystem would also be a
big plus. I know it’s mostly a Windows issue, but Windows is probably
still your biggest target audience…

Both of these are hefty endeavors beyond what I have time to do right
now. ?Are you interested in combing through the code and implementing
them?

I’ll be without internet access for a while within a few days, so if
I’m doing it myself, it will have to wait a bit. I have a demo for a
new input system I’ll send your way before I disappear, which will
include SDL_PARANOIA style checks, but not multithreading (at least,
not yet).