mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-09-28 22:18:28 +00:00
Remove almost all instances of "volatile" keyword.
As Tiffany pointed out in Bugzilla, volatile is not useful for thread safety: https://software.intel.com/en-us/blogs/2007/11/30/volatile-almost-useless-for-multi-threaded-programming/ Some of these volatiles didn't need to be, some were otherwise protected by spinlocks or mutexes, and some got moved over to SDL_atomic_t data, etc. Fixes Bugzilla #3220.
This commit is contained in:
@@ -293,7 +293,7 @@ SDL_InitDynamicAPI(void)
|
||||
* SDL_CreateThread() would also call this function before building the
|
||||
* new thread).
|
||||
*/
|
||||
static volatile SDL_bool already_initialized = SDL_FALSE;
|
||||
static SDL_bool already_initialized = SDL_FALSE;
|
||||
|
||||
/* SDL_AtomicLock calls SDL mutex functions to emulate if
|
||||
SDL_ATOMIC_DISABLED, which we can't do here, so in such a
|
||||
|
@@ -73,15 +73,15 @@ typedef struct _SDL_SysWMEntry
|
||||
static struct
|
||||
{
|
||||
SDL_mutex *lock;
|
||||
volatile SDL_bool active;
|
||||
volatile int count;
|
||||
volatile int max_events_seen;
|
||||
SDL_atomic_t active;
|
||||
SDL_atomic_t count;
|
||||
int max_events_seen;
|
||||
SDL_EventEntry *head;
|
||||
SDL_EventEntry *tail;
|
||||
SDL_EventEntry *free;
|
||||
SDL_SysWMEntry *wmmsg_used;
|
||||
SDL_SysWMEntry *wmmsg_free;
|
||||
} SDL_EventQ = { NULL, SDL_TRUE, 0, 0, NULL, NULL, NULL, NULL, NULL };
|
||||
} SDL_EventQ = { NULL, { 1 }, { 0 }, 0, NULL, NULL, NULL, NULL, NULL };
|
||||
|
||||
|
||||
/* Public functions */
|
||||
@@ -98,7 +98,7 @@ SDL_StopEventLoop(void)
|
||||
SDL_LockMutex(SDL_EventQ.lock);
|
||||
}
|
||||
|
||||
SDL_EventQ.active = SDL_FALSE;
|
||||
SDL_AtomicSet(&SDL_EventQ.active, 0);
|
||||
|
||||
if (report && SDL_atoi(report)) {
|
||||
SDL_Log("SDL EVENT QUEUE: Maximum events in-flight: %d\n",
|
||||
@@ -127,7 +127,7 @@ SDL_StopEventLoop(void)
|
||||
wmmsg = next;
|
||||
}
|
||||
|
||||
SDL_EventQ.count = 0;
|
||||
SDL_AtomicSet(&SDL_EventQ.count, 0);
|
||||
SDL_EventQ.max_events_seen = 0;
|
||||
SDL_EventQ.head = NULL;
|
||||
SDL_EventQ.tail = NULL;
|
||||
@@ -171,7 +171,7 @@ SDL_StartEventLoop(void)
|
||||
SDL_EventQ.lock = SDL_CreateMutex();
|
||||
}
|
||||
if (SDL_EventQ.lock == NULL) {
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
#endif /* !SDL_THREADS_DISABLED */
|
||||
|
||||
@@ -180,9 +180,9 @@ SDL_StartEventLoop(void)
|
||||
SDL_EventState(SDL_TEXTEDITING, SDL_DISABLE);
|
||||
SDL_EventState(SDL_SYSWMEVENT, SDL_DISABLE);
|
||||
|
||||
SDL_EventQ.active = SDL_TRUE;
|
||||
SDL_AtomicSet(&SDL_EventQ.active, 1);
|
||||
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -191,9 +191,11 @@ static int
|
||||
SDL_AddEvent(SDL_Event * event)
|
||||
{
|
||||
SDL_EventEntry *entry;
|
||||
const int initial_count = SDL_AtomicGet(&SDL_EventQ.count);
|
||||
int final_count;
|
||||
|
||||
if (SDL_EventQ.count >= SDL_MAX_QUEUED_EVENTS) {
|
||||
SDL_SetError("Event queue is full (%d events)", SDL_EventQ.count);
|
||||
if (initial_count >= SDL_MAX_QUEUED_EVENTS) {
|
||||
SDL_SetError("Event queue is full (%d events)", initial_count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -225,10 +227,10 @@ SDL_AddEvent(SDL_Event * event)
|
||||
entry->prev = NULL;
|
||||
entry->next = NULL;
|
||||
}
|
||||
++SDL_EventQ.count;
|
||||
|
||||
if (SDL_EventQ.count > SDL_EventQ.max_events_seen) {
|
||||
SDL_EventQ.max_events_seen = SDL_EventQ.count;
|
||||
final_count = SDL_AtomicAdd(&SDL_EventQ.count, 1) + 1;
|
||||
if (final_count > SDL_EventQ.max_events_seen) {
|
||||
SDL_EventQ.max_events_seen = final_count;
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -256,8 +258,8 @@ SDL_CutEvent(SDL_EventEntry *entry)
|
||||
|
||||
entry->next = SDL_EventQ.free;
|
||||
SDL_EventQ.free = entry;
|
||||
SDL_assert(SDL_EventQ.count > 0);
|
||||
--SDL_EventQ.count;
|
||||
SDL_assert(SDL_AtomicGet(&SDL_EventQ.count) > 0);
|
||||
SDL_AtomicAdd(&SDL_EventQ.count, -1);
|
||||
}
|
||||
|
||||
/* Lock the event queue, take a peep at it, and unlock it */
|
||||
@@ -268,7 +270,7 @@ SDL_PeepEvents(SDL_Event * events, int numevents, SDL_eventaction action,
|
||||
int i, used;
|
||||
|
||||
/* Don't look after we've quit */
|
||||
if (!SDL_EventQ.active) {
|
||||
if (!SDL_AtomicGet(&SDL_EventQ.active)) {
|
||||
/* We get a few spurious events at shutdown, so don't warn then */
|
||||
if (action != SDL_ADDEVENT) {
|
||||
SDL_SetError("The event system has been shut down");
|
||||
@@ -363,7 +365,7 @@ void
|
||||
SDL_FlushEvents(Uint32 minType, Uint32 maxType)
|
||||
{
|
||||
/* Don't look after we've quit */
|
||||
if (!SDL_EventQ.active) {
|
||||
if (!SDL_AtomicGet(&SDL_EventQ.active)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -255,7 +255,7 @@ SDL_SYS_HapticQuit(void)
|
||||
for (hapticitem = SDL_haptics; hapticitem; hapticitem = hapticitem->next) {
|
||||
if ((hapticitem->hwdata->bXInputHaptic) && (hapticitem->hwdata->thread)) {
|
||||
/* we _have_ to stop the thread before we free the XInput DLL! */
|
||||
hapticitem->hwdata->stopThread = 1;
|
||||
SDL_AtomicSet(&hapticitem->hwdata->stopThread, 1);
|
||||
SDL_WaitThread(hapticitem->hwdata->thread, NULL);
|
||||
hapticitem->hwdata->thread = NULL;
|
||||
}
|
||||
|
@@ -42,8 +42,8 @@ struct haptic_hwdata
|
||||
Uint8 userid; /* XInput userid index for this joystick */
|
||||
SDL_Thread *thread;
|
||||
SDL_mutex *mutex;
|
||||
volatile Uint32 stopTicks;
|
||||
volatile int stopThread;
|
||||
Uint32 stopTicks;
|
||||
SDL_atomic_t stopThread;
|
||||
};
|
||||
|
||||
|
||||
|
@@ -146,7 +146,7 @@ SDL_RunXInputHaptic(void *arg)
|
||||
{
|
||||
struct haptic_hwdata *hwdata = (struct haptic_hwdata *) arg;
|
||||
|
||||
while (!hwdata->stopThread) {
|
||||
while (!SDL_AtomicGet(&hwdata->stopThread)) {
|
||||
SDL_Delay(50);
|
||||
SDL_LockMutex(hwdata->mutex);
|
||||
/* If we're currently running and need to stop... */
|
||||
@@ -261,7 +261,7 @@ SDL_XINPUT_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick)
|
||||
void
|
||||
SDL_XINPUT_HapticClose(SDL_Haptic * haptic)
|
||||
{
|
||||
haptic->hwdata->stopThread = 1;
|
||||
SDL_AtomicSet(&haptic->hwdata->stopThread, 1);
|
||||
SDL_WaitThread(haptic->hwdata->thread, NULL);
|
||||
SDL_DestroyMutex(haptic->hwdata->mutex);
|
||||
}
|
||||
|
@@ -35,7 +35,7 @@ typedef struct _SDL_Timer
|
||||
void *param;
|
||||
Uint32 interval;
|
||||
Uint32 scheduled;
|
||||
volatile SDL_bool canceled;
|
||||
SDL_atomic_t canceled;
|
||||
struct _SDL_Timer *next;
|
||||
} SDL_Timer;
|
||||
|
||||
@@ -60,9 +60,9 @@ typedef struct {
|
||||
/* 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;
|
||||
@@ -138,7 +138,7 @@ SDL_TimerThread(void *_data)
|
||||
freelist_tail = NULL;
|
||||
|
||||
/* Check to see if we're still running, after maintenance */
|
||||
if (!data->active) {
|
||||
if (!SDL_AtomicGet(&data->active)) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ SDL_TimerThread(void *_data)
|
||||
/* We're going to do something with this timer */
|
||||
data->timers = current->next;
|
||||
|
||||
if (current->canceled) {
|
||||
if (SDL_AtomicGet(¤t->canceled)) {
|
||||
interval = 0;
|
||||
} else {
|
||||
interval = current->callback(current->interval, current->param);
|
||||
@@ -179,7 +179,7 @@ SDL_TimerThread(void *_data)
|
||||
}
|
||||
freelist_tail = current;
|
||||
|
||||
current->canceled = SDL_TRUE;
|
||||
SDL_AtomicSet(¤t->canceled, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ SDL_TimerInit(void)
|
||||
{
|
||||
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) {
|
||||
@@ -220,7 +220,7 @@ SDL_TimerInit(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
data->active = SDL_TRUE;
|
||||
SDL_AtomicSet(&data->active, 1);
|
||||
/* !!! FIXME: this is nasty. */
|
||||
#if defined(__WIN32__) && !defined(HAVE_LIBC)
|
||||
#undef SDL_CreateThread
|
||||
@@ -249,9 +249,7 @@ SDL_TimerQuit(void)
|
||||
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);
|
||||
@@ -291,21 +289,14 @@ SDL_AddTimer(Uint32 interval, SDL_TimerCallback callback, void *param)
|
||||
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;
|
||||
@@ -326,7 +317,7 @@ SDL_AddTimer(Uint32 interval, SDL_TimerCallback callback, void *param)
|
||||
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) {
|
||||
@@ -377,8 +368,8 @@ SDL_RemoveTimer(SDL_TimerID id)
|
||||
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);
|
||||
|
@@ -50,7 +50,7 @@ static void Android_GetWindowCoordinates(float x, float y,
|
||||
*window_y = (int)(y * window_h);
|
||||
}
|
||||
|
||||
static volatile SDL_bool separate_mouse_and_touch = SDL_FALSE;
|
||||
static SDL_bool separate_mouse_and_touch = SDL_FALSE;
|
||||
|
||||
static void
|
||||
SeparateEventsHintWatcher(void *userdata, const char *name,
|
||||
|
Reference in New Issue
Block a user