SDL_CreateThread and SDL_AddTimer are not always working

Hi all,

I started using SDL2 a while ago and I am trying to figure out why my thread/timer starts most of the time (>95%) but once in a while it does not. I am developing on Windows 8.1 using Msdev 2017.

When the problem occurs, the ‘while (Current_Timer == 0)’ and ‘while (Low_Thread_Tick == 0)’ below never exits (even after waiting several minutes) which would mean that the timer/thread is never called. I don’t see any errors in my log.

Is there something missing/wrong in what I am doing?
Do I need to check for some other errors even if SDL_AddTimer returns a non-zero value and SDL_CreateThread returns a non-NULL pointer?

Here is the code I am using to start it:

SDL_Thread *Low_Thread;
long Low_Thread_Tick;

static int Low(void *ptr)
{
   if (SDL_SetThreadPriority(SDL_THREAD_PRIORITY_LOW))
   {
      log("Could not set thread priority, err %ld", SDL_GetError());
   }

   log("thread Low started");
   while (1)
   {
      Low_Thread_Tick++;
   }
}


long start_low_thread(void)
{
   SDL_Thread *Low_Thread;

   Low_Thread_Tick = 0;
   
   Low_Thread = SDL_CreateThread(Low, "Low", NULL);
   if (Low_Thread == NULL) {
      log("Thread Low failed to start: %s\n", SDL_GetError());
      return 0;
   } else {

      // Wait for the thread to start
      while (Low_Thread_Tick == 0)
         log("tick: %d", Low_Thread_Tick);
   }

   return 1;
}

   Uint32 Timer_Proc(Uint32 interval, void *param)
   {
      Current_Timer++;
      return interval;
   }

void another_function()
{
   Current_Timer = 0;

   Uint32 delay    = 10;
   Update_Timer_ID = SDL_AddTimer(delay, (SDL_TimerCallback)Timer_Proc, NULL);
   if (Update_Timer_ID == 0)
   {
      log("Timer did not start, error: %s", SDL_GetError());
   }
   while (Current_Timer == 0)
   {
      log("   Waiting for timer to increment (CPU time stamp %lf)", read_cpu_time_stamp());
   }
}

It’s not exactly “wrong” but I don’t like spinning in a busy-wait loop indefinitely, if it can be avoided (especially if there’s a low-priority thread ready to run). Does it make a difference if you add a delay:

while (Low_Thread_Tick == 0)
{
   SDL_Delay(1);
   log("tick: %d", Low_Thread_Tick);
}

and:

while (Current_Timer == 0)
{
   SDL_Delay(1);
   log("   Waiting for timer to increment (CPU time stamp %lf)", read_cpu_time_stamp());
}

So what does SDL_GetError() say why it fails?

Thanks.

Next time it occurs I’ll break and add some code to add the SDL_Delay(1) as suggested and call SDL_GetError() to see is there are any errors.

Right now I did not check for errors because the functions that create a thread/timer returned a valid result.

It occurred again in the create thread. I added a call to SDL_Delay(1) as you suggested in the waiting loop but that did not help.

The SDL_GetError() returned “Passed a NULL mutex” even though the SDL_CreateThread returned what looks like a valid (non NULL) pointer.

Are you even sure the thread isn’t created? A debugger should be able to tell you what threads are running and what they’re doing.

If it is created, maybe Low_Thread_Tick isn’t properly synchronized between threads? After all, you’re not using a mutex or similar to protect it, and it’s not atomic either.
Maybe using an atomic instead of long works better? See https://wiki.libsdl.org/CategoryAtomic ; https://wiki.libsdl.org/SDL_atomic_t has a short example

Thank, I forgot to check using the debugger. I will try what you are suggesting the next time it occurs.