[SDL] SDL, Threads & multicore (was: SDL Digest, Vol 18, Issue 7)
Christian Walther
cwalther at gmx.ch
Thu Jun 5 12:17:50 PDT 2008
Chris T wrote:
> Alright; fair enough. Here's the source code for it:
>
> #define NumCPU 4
>
> SDL_cond *Cond;
> SDL_mutex *Mutex;
> SDL_Thread *Threads[NumCPU] = {0};
>
> int FilterImage(void *ID)
> {
> do {
> // Synchronize threads on start
> SDL_CondWait(Cond, Mutex);
>
> // Do some work
> } while (1);
>
> return -1;
> }
>
>
>
> int main(int ArgC, char *Args[])
> {
> if (SDL_Init(SDL_INIT_VIDEO) < 0)
> return -2;
>
> if ((Mutex = SDL_CreateMutex()) == NULL)
> goto Exit;
>
> if ((Cond = SDL_CreateCond()) == NULL)
> goto Exit;
>
> for (int i = 0; i < NumCPU; i++)
> Threads[i] = SDL_CreateThread(&FilterImage, (void *)i);
>
> SDL_Delay(1000);
> SDL_CondBroadcast(Cond);
>
> do {
> // Do some work
> } while (1);
> }
OK, what happens here is exactly what I described: you're serializing
your worker threads using the mutex. Also, note that you should lock the
mutex before calling SDL_CondWait (I don't know what happens when you
don't). It will unlock it before going to sleep, and re-lock it before
returning. Your thread function should look something like this:
int FilterImage(void *ID)
{
do {
SDL_LockMutex(Mutex);
// Check whether there is any work for me (at a shared source
// that needs to be protected by the mutex)
while (there is no work for me to do) {
SDL_CondWait(Cond, Mutex);
}
// Fetch some work from the shared source
SDL_UnlockMutex(Mutex);
// Do the work (other threads can run concurrently now)
} while (1);
return -1;
}
The while loop around the SDL_CondWait() is important too: by the time
you're getting the mutex after being awakened by a condition broadcast,
other waiting threads that got to run before you may already have used
up all pending jobs, and you can go to sleep again.
> I am making sure that the threads are created
> fully before broadcasting by adding a temporary artificial delay of 1-2s
> before the broadcast.
I hope you're aware that you're not making sure of anything by this? All
you're doing is increasing the likelihood that the threads will be ready
(to probably close enough to 100% that it doesn't matter in practice,
but still). Plus, you slow down your application launch needlessly. To
do this properly, you need to have the worker threads notify the main
thread when they're ready, using another condition, or a semaphore.
Have you considered whether a semaphore might be a better solution for
what you're trying to achieve than a condition? Unlike the latter, it
doesn't "lose" the notifications that happen while no one is waiting on
it. And generally, I find that semaphores are easier to get your head
around than conditions. :)
Hope this helps somewhat. Thread synchronization is complicated to do
properly, it took me a while to come to grips with it too, and I'm still
not sure I get it completely right (so corrections are welcome if
anything I wrote above is incorrect).
-Christian
More information about the SDL
mailing list