/*
Simple DirectMedia Layer
- Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
#include "SDL_timer_c.h"
#include "SDL_atomic.h"
#include "SDL_cpuinfo.h"
-#include "SDL_thread.h"
+#include "../thread/SDL_systhread.h"
#include "xf86drm.h"
#include <fcntl.h>
void *param;
Uint32 interval;
Uint32 scheduled;
- volatile SDL_bool canceled;
+ SDL_atomic_t canceled;
struct _SDL_Timer *next;
} SDL_Timer;
/* Data used to communicate with the timer thread */
SDL_SpinLock lock;
SDL_sem *sem;
- SDL_Timer * volatile pending;
- SDL_Timer * volatile freelist;
- volatile SDL_bool active;
+ SDL_Timer *pending;
+ SDL_Timer *freelist;
+ SDL_atomic_t active;
/* List of timers - this is only touched by the timer thread */
SDL_Timer *timers;
timer->next = curr;
}
-static int
+static int SDLCALL
SDL_TimerThread(void *_data)
{
SDL_TimerData *data = (SDL_TimerData *)_data;
for ( ; ; ) {
#if defined(__TIZEN__)
if(data->drm_fd > -1) {
- if(!data->active)
+ if(!SDL_AtomicGet(&data->active))
break;
if(drmWaitVBlank(data->drm_fd, &(data->vblankInfo)) == 0) {
if(data->pending) {
freelist_head = NULL;
freelist_tail = NULL;
+ /* Check to see if we're still running, after maintenance */
+ if (!SDL_AtomicGet(&data->active)) {
+
/* Check to see if we're still running, after maintenance */
- if (!data->active) {
break;
}
/* We're going to do something with this timer */
data->timers = current->next;
- if (current->canceled) {
- interval = 0;
- } else {
- interval = current->callback(current->interval, current->param);
- }
+ if (SDL_AtomicGet(¤t->canceled)) {
+ interval = 0;
+ } else {
+ interval = current->callback(current->interval, current->param);
+ }
+
+ if (interval > 0) {
+ /* Reschedule this timer */
+ current->interval = interval;
- if (interval > 0) {
/* Reschedule this timer */
current->scheduled = tick + interval;
SDL_AddTimerInternal(data, current);
}
freelist_tail = current;
- current->canceled = SDL_TRUE;
+ SDL_AtomicSet(¤t->canceled, 1);
}
}
{
SDL_TimerData *data = &SDL_timer_data;
- if (!data->active) {
+ if (!SDL_AtomicGet(&data->active)) {
const char *name = "SDLTimer";
data->timermap_lock = SDL_CreateMutex();
if (!data->timermap_lock) {
return -1;
}
- data->active = SDL_TRUE;
+ SDL_AtomicSet(&data->active, 1);
#if defined(__TIZEN__)
const char* DRM_DEVICE = "/dev/dri/card0";
}
#endif
/* !!! FIXME: this is nasty. */
-#if defined(__WIN32__) && !defined(HAVE_LIBC)
-#undef SDL_CreateThread
-#if SDL_DYNAMIC_API
- data->thread = SDL_CreateThread_REAL(SDL_TimerThread, name, data, NULL, NULL);
-#else
- data->thread = SDL_CreateThread(SDL_TimerThread, name, data, NULL, NULL);
-#endif
-#else
- data->thread = SDL_CreateThread(SDL_TimerThread, name, data);
-#endif
+
+ /* Timer threads use a callback into the app, so we can't set a limited stack size here. */
+ data->thread = SDL_CreateThreadInternal(SDL_TimerThread, name, 0, data);
if (!data->thread) {
SDL_TimerQuit();
return -1;
SDL_Timer *timer;
SDL_TimerMap *entry;
- if (data->active) {
- data->active = SDL_FALSE;
-
+ if (SDL_AtomicCAS(&data->active, 1, 0)) { /* active? Move to inactive. */
/* Shutdown the timer thread */
if (data->thread) {
SDL_SemPost(data->sem);
SDL_Timer *timer;
SDL_TimerMap *entry;
- if (!data->active) {
- int status = 0;
-
- SDL_AtomicLock(&data->lock);
- if (!data->active) {
- status = SDL_TimerInit();
- }
- SDL_AtomicUnlock(&data->lock);
-
- if (status < 0) {
+ SDL_AtomicLock(&data->lock);
+ if (!SDL_AtomicGet(&data->active)) {
+ if (SDL_TimerInit() < 0) {
+ SDL_AtomicUnlock(&data->lock);
return 0;
}
}
- SDL_AtomicLock(&data->lock);
timer = data->freelist;
if (timer) {
data->freelist = timer->next;
timer->param = param;
timer->interval = interval;
timer->scheduled = SDL_GetTicks() + interval;
- timer->canceled = SDL_FALSE;
+ SDL_AtomicSet(&timer->canceled, 0);
entry = (SDL_TimerMap *)SDL_malloc(sizeof(*entry));
if (!entry) {
SDL_UnlockMutex(data->timermap_lock);
if (entry) {
- if (!entry->timer->canceled) {
- entry->timer->canceled = SDL_TRUE;
+ if (!SDL_AtomicGet(&entry->timer->canceled)) {
+ SDL_AtomicSet(&entry->timer->canceled, 1);
canceled = SDL_TRUE;
}
SDL_free(entry);