1.1 --- a/include/SDL_compat.h Thu Jan 27 10:40:17 2011 -0800
1.2 +++ b/include/SDL_compat.h Thu Jan 27 14:45:06 2011 -0800
1.3 @@ -344,6 +344,13 @@
1.4 #define SDL_RenderFill(X) (X) ? SDL_RenderFillRect(X) : SDL_RenderClear()
1.5 #define SDL_KillThread(X)
1.6
1.7 +/* The timeslice and timer resolution are no longer relevant */
1.8 +#define SDL_TIMESLICE 10
1.9 +#define TIMER_RESOLUTION 10
1.10 +
1.11 +typedef Uint32 (SDLCALL * SDL_OldTimerCallback) (Uint32 interval);
1.12 +extern DECLSPEC int SDLCALL SDL_SetTimer(Uint32 interval, SDL_OldTimerCallback callback);
1.13 +
1.14 extern DECLSPEC int SDLCALL SDL_putenv(const char *variable);
1.15
1.16 /*@}*//*Compatibility*/
2.1 --- a/include/SDL_timer.h Thu Jan 27 10:40:17 2011 -0800
2.2 +++ b/include/SDL_timer.h Thu Jan 27 14:45:06 2011 -0800
2.3 @@ -41,104 +41,50 @@
2.4 #endif
2.5
2.6 /**
2.7 - * This is the OS scheduler timeslice, in milliseconds.
2.8 - */
2.9 -#define SDL_TIMESLICE 10
2.10 -
2.11 -/**
2.12 - * This is the maximum resolution of the SDL timer on all platforms.
2.13 - */
2.14 -#define TIMER_RESOLUTION 10 /**< Experimentally determined */
2.15 -
2.16 -/**
2.17 - * Get the number of milliseconds since the SDL library initialization.
2.18 + * \brief Get the number of milliseconds since the SDL library initialization.
2.19 *
2.20 - * Note that this value wraps if the program runs for more than ~49 days.
2.21 + * \note This value wraps if the program runs for more than ~49 days.
2.22 */
2.23 extern DECLSPEC Uint32 SDLCALL SDL_GetTicks(void);
2.24
2.25 /**
2.26 - * Wait a specified number of milliseconds before returning.
2.27 + * \brief Wait a specified number of milliseconds before returning.
2.28 */
2.29 extern DECLSPEC void SDLCALL SDL_Delay(Uint32 ms);
2.30
2.31 /**
2.32 * Function prototype for the timer callback function.
2.33 - */
2.34 -typedef Uint32(SDLCALL * SDL_TimerCallback) (Uint32 interval);
2.35 -
2.36 -/**
2.37 - * Set a callback to run after the specified number of milliseconds has
2.38 - * elapsed. The callback function is passed the current timer interval
2.39 - * and returns the next timer interval. If the returned value is the
2.40 - * same as the one passed in, the periodic alarm continues, otherwise a
2.41 - * new alarm is scheduled. If the callback returns 0, the periodic alarm
2.42 - * is cancelled.
2.43 - *
2.44 - * To cancel a currently running timer, call
2.45 - * \code SDL_SetTimer(0, NULL); \endcode
2.46 - *
2.47 - * The timer callback function may run in a different thread than your
2.48 - * main code, and so shouldn't call any functions from within itself.
2.49 - *
2.50 - * The maximum resolution of this timer is 10 ms, which means that if
2.51 - * you request a 16 ms timer, your callback will run approximately 20 ms
2.52 - * later on an unloaded system. If you wanted to set a flag signaling
2.53 - * a frame update at 30 frames per second (every 33 ms), you might set a
2.54 - * timer for 30 ms:
2.55 - * \code
2.56 - * SDL_SetTimer((33/10)*10, flag_update);
2.57 - * \endcode
2.58 - *
2.59 - * If you use this function, you need to pass ::SDL_INIT_TIMER to SDL_Init().
2.60 - *
2.61 - * Under UNIX, you should not use raise or use SIGALRM and this function
2.62 - * in the same program, as it is implemented using setitimer(). You also
2.63 - * should not use this function in multi-threaded applications as signals
2.64 - * to multi-threaded apps have undefined behavior in some implementations.
2.65 - *
2.66 - * \return 0 if successful, or -1 if there was an error.
2.67 - */
2.68 -extern DECLSPEC int SDLCALL SDL_SetTimer(Uint32 interval,
2.69 - SDL_TimerCallback callback);
2.70 -
2.71 -/**
2.72 - * \name Peter timers
2.73 - * New timer API, supports multiple timers
2.74 - * Written by Stephane Peter <megastep@lokigames.com>
2.75 - */
2.76 -/*@{*/
2.77 -
2.78 -/**
2.79 - * Function prototype for the new timer callback function.
2.80 *
2.81 * The callback function is passed the current timer interval and returns
2.82 * the next timer interval. If the returned value is the same as the one
2.83 * passed in, the periodic alarm continues, otherwise a new alarm is
2.84 * scheduled. If the callback returns 0, the periodic alarm is cancelled.
2.85 */
2.86 -typedef Uint32(SDLCALL * SDL_NewTimerCallback) (Uint32 interval, void *param);
2.87 +typedef Uint32 (SDLCALL * SDL_TimerCallback) (Uint32 interval, void *param);
2.88
2.89 /**
2.90 - * Definition of the timer ID type.
2.91 + * Definition of the timer ID type.
2.92 */
2.93 -typedef struct _SDL_TimerID *SDL_TimerID;
2.94 +typedef int SDL_TimerID;
2.95
2.96 /**
2.97 - * Add a new timer to the pool of timers already running.
2.98 - * \return A timer ID, or NULL when an error occurs.
2.99 + * \brief Add a new timer to the pool of timers already running.
2.100 + *
2.101 + * \return A timer ID, or NULL when an error occurs.
2.102 */
2.103 extern DECLSPEC SDL_TimerID SDLCALL SDL_AddTimer(Uint32 interval,
2.104 - SDL_NewTimerCallback
2.105 - callback, void *param);
2.106 + SDL_TimerCallback callback,
2.107 + void *param);
2.108
2.109 /**
2.110 - * Remove one of the multiple timers knowing its ID.
2.111 - * \return A boolean value indicating success or failure.
2.112 + * \brief Remove a timer knowing its ID.
2.113 + *
2.114 + * \return A boolean value indicating success or failure.
2.115 + *
2.116 + * \warning It is not safe to remove a timer multiple times.
2.117 */
2.118 extern DECLSPEC SDL_bool SDLCALL SDL_RemoveTimer(SDL_TimerID t);
2.119
2.120 -/*@}*//*Peter timers*/
2.121
2.122 /* Ends C function definitions when using C++ */
2.123 #ifdef __cplusplus
3.1 --- a/src/SDL_compat.c Thu Jan 27 10:40:17 2011 -0800
3.2 +++ b/src/SDL_compat.c Thu Jan 27 14:45:06 2011 -0800
3.3 @@ -1760,6 +1760,31 @@
3.4 return previous;
3.5 }
3.6
3.7 +static Uint32
3.8 +SDL_SetTimerCallback(Uint32 interval, void* param)
3.9 +{
3.10 + return ((SDL_OldTimerCallback)param)(interval);
3.11 +}
3.12 +
3.13 +int
3.14 +SDL_SetTimer(Uint32 interval, SDL_OldTimerCallback callback)
3.15 +{
3.16 + static SDL_TimerID compat_timer;
3.17 +
3.18 + if (compat_timer) {
3.19 + SDL_RemoveTimer(compat_timer);
3.20 + compat_timer = 0;
3.21 + }
3.22 +
3.23 + if (interval && callback) {
3.24 + compat_timer = SDL_AddTimer(interval, SDL_SetTimerCallback, callback);
3.25 + if (!compat_timer) {
3.26 + return -1;
3.27 + }
3.28 + }
3.29 + return 0;
3.30 +}
3.31 +
3.32 int
3.33 SDL_putenv(const char *_var)
3.34 {
4.1 --- a/src/events/SDL_events.c Thu Jan 27 10:40:17 2011 -0800
4.2 +++ b/src/events/SDL_events.c Thu Jan 27 14:45:06 2011 -0800
4.3 @@ -123,9 +123,6 @@
4.4
4.5 /* Give up the CPU for the rest of our timeslice */
4.6 SDL_EventLock.safe = 1;
4.7 - if (SDL_timer_running) {
4.8 - SDL_ThreadedTimerCheck();
4.9 - }
4.10 SDL_Delay(1);
4.11
4.12 /* Check for event locking.
4.13 @@ -140,7 +137,6 @@
4.14 SDL_EventLock.safe = 0;
4.15 SDL_mutexV(SDL_EventLock.lock);
4.16 }
4.17 - SDL_SetTimerThreaded(0);
4.18 event_thread = 0;
4.19 return (0);
4.20 }
4.21 @@ -168,8 +164,6 @@
4.22 }
4.23 SDL_EventLock.safe = 0;
4.24
4.25 - /* The event thread will handle timers too */
4.26 - SDL_SetTimerThreaded(2);
4.27 #if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC)
4.28 #undef SDL_CreateThread
4.29 SDL_EventThread =
5.1 --- a/src/timer/SDL_systimer.h Thu Jan 27 10:40:17 2011 -0800
5.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
5.3 @@ -1,42 +0,0 @@
5.4 -/*
5.5 - SDL - Simple DirectMedia Layer
5.6 - Copyright (C) 1997-2010 Sam Lantinga
5.7 -
5.8 - This library is free software; you can redistribute it and/or
5.9 - modify it under the terms of the GNU Lesser General Public
5.10 - License as published by the Free Software Foundation; either
5.11 - version 2.1 of the License, or (at your option) any later version.
5.12 -
5.13 - This library is distributed in the hope that it will be useful,
5.14 - but WITHOUT ANY WARRANTY; without even the implied warranty of
5.15 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5.16 - Lesser General Public License for more details.
5.17 -
5.18 - You should have received a copy of the GNU Lesser General Public
5.19 - License along with this library; if not, write to the Free Software
5.20 - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
5.21 -
5.22 - Sam Lantinga
5.23 - slouken@libsdl.org
5.24 -*/
5.25 -#include "SDL_config.h"
5.26 -
5.27 -/* The system dependent timer handling functions */
5.28 -
5.29 -#include "SDL_timer.h"
5.30 -#include "SDL_timer_c.h"
5.31 -
5.32 -
5.33 -/* Initialize the system dependent timer subsystem */
5.34 -extern int SDL_SYS_TimerInit(void);
5.35 -
5.36 -/* Quit the system dependent timer subsystem */
5.37 -extern void SDL_SYS_TimerQuit(void);
5.38 -
5.39 -/* Start a timer set up by SDL_SetTimer() */
5.40 -extern int SDL_SYS_StartTimer(void);
5.41 -
5.42 -/* Stop a previously started timer */
5.43 -extern void SDL_SYS_StopTimer(void);
5.44 -
5.45 -/* vi: set ts=4 sw=4 expandtab: */
6.1 --- a/src/timer/SDL_timer.c Thu Jan 27 10:40:17 2011 -0800
6.2 +++ b/src/timer/SDL_timer.c Thu Jan 27 14:45:06 2011 -0800
6.3 @@ -23,289 +23,360 @@
6.4
6.5 #include "SDL_timer.h"
6.6 #include "SDL_timer_c.h"
6.7 -#include "SDL_mutex.h"
6.8 -#include "SDL_systimer.h"
6.9 +#include "SDL_atomic.h"
6.10 +#include "SDL_thread.h"
6.11
6.12 /* #define DEBUG_TIMERS */
6.13
6.14 -int SDL_timer_started = 0;
6.15 -int SDL_timer_running = 0;
6.16 +typedef struct _SDL_Timer
6.17 +{
6.18 + int timerID;
6.19 + SDL_TimerCallback callback;
6.20 + void *param;
6.21 + Uint32 interval;
6.22 + Uint32 scheduled;
6.23 + volatile SDL_bool canceled;
6.24 + struct _SDL_Timer *next;
6.25 +} SDL_Timer;
6.26 +
6.27 +typedef struct _SDL_TimerMap
6.28 +{
6.29 + int timerID;
6.30 + SDL_Timer *timer;
6.31 + struct _SDL_TimerMap *next;
6.32 +} SDL_TimerMap;
6.33
6.34 -/* Data to handle a single periodic alarm */
6.35 -Uint32 SDL_alarm_interval = 0;
6.36 -SDL_TimerCallback SDL_alarm_callback;
6.37 +/* A reasonable guess */
6.38 +#define CACHELINE_SIZE 128
6.39 +
6.40 +/* The timers are kept in a sorted list */
6.41 +typedef struct {
6.42 + /* Data used by the main thread */
6.43 + SDL_Thread *thread;
6.44 + SDL_atomic_t nextID;
6.45 + SDL_TimerMap *timermap;
6.46 + SDL_mutex *timermap_lock;
6.47 +
6.48 + /* Padding to separate cache lines between threads */
6.49 + char pad[CACHELINE_SIZE];
6.50 +
6.51 + /* Data used to communicate with the timer thread */
6.52 + SDL_SpinLock lock;
6.53 + SDL_sem *sem;
6.54 + SDL_Timer * volatile pending;
6.55 + SDL_Timer * volatile freelist;
6.56 + volatile SDL_bool active;
6.57
6.58 -/* Data used for a thread-based timer */
6.59 -static int SDL_timer_threaded = 0;
6.60 + /* List of timers - this is only touched by the timer thread */
6.61 + SDL_Timer *timers;
6.62 +} SDL_TimerData;
6.63 +
6.64 +static SDL_TimerData SDL_timer_data;
6.65 +
6.66
6.67 -struct _SDL_TimerID
6.68 +/* The idea here is that any thread might add a timer, but a single
6.69 + * thread manages the active timer queue, sorted by scheduling time.
6.70 + *
6.71 + * Timers are removed by simply setting a canceled flag
6.72 + */
6.73 +
6.74 +static void
6.75 +SDL_AddTimerInternal(SDL_TimerData *data, SDL_Timer *timer)
6.76 {
6.77 - Uint32 interval;
6.78 - SDL_NewTimerCallback cb;
6.79 - void *param;
6.80 - Uint32 last_alarm;
6.81 - struct _SDL_TimerID *next;
6.82 -};
6.83 + SDL_Timer *prev, *curr;
6.84 +
6.85 + prev = NULL;
6.86 + for (curr = data->timers; curr; prev = curr, curr = curr->next) {
6.87 + if ((Sint32)(timer->scheduled-curr->scheduled) < 0) {
6.88 + break;
6.89 + }
6.90 + }
6.91 +
6.92 + /* Insert the timer here! */
6.93 + if (prev) {
6.94 + prev->next = timer;
6.95 + } else {
6.96 + data->timers = timer;
6.97 + }
6.98 + timer->next = curr;
6.99 +}
6.100 +
6.101 +static int
6.102 +SDL_TimerThread(void *_data)
6.103 +{
6.104 + SDL_TimerData *data = (SDL_TimerData *)_data;
6.105 + SDL_Timer *pending;
6.106 + SDL_Timer *current;
6.107 + SDL_Timer *freelist_head = NULL;
6.108 + SDL_Timer *freelist_tail = NULL;
6.109 + Uint32 tick, now, interval, delay;
6.110
6.111 -static SDL_TimerID SDL_timers = NULL;
6.112 -static SDL_mutex *SDL_timer_mutex;
6.113 -static volatile SDL_bool list_changed = SDL_FALSE;
6.114 + /* Threaded timer loop:
6.115 + * 1. Queue timers added by other threads
6.116 + * 2. Handle any timers that should dispatch this cycle
6.117 + * 3. Wait until next dispatch time or new timer arrives
6.118 + */
6.119 + for ( ; ; ) {
6.120 + /* Pending and freelist maintenance */
6.121 + SDL_AtomicLock(&data->lock);
6.122 + {
6.123 + /* Get any timers ready to be queued */
6.124 + pending = data->pending;
6.125 + data->pending = NULL;
6.126 +
6.127 + /* Make any unused timer structures available */
6.128 + if (freelist_head) {
6.129 + freelist_tail->next = data->freelist;
6.130 + data->freelist = freelist_head;
6.131 + }
6.132 + }
6.133 + SDL_AtomicUnlock(&data->lock);
6.134 +
6.135 + /* Sort the pending timers into our list */
6.136 + while (pending) {
6.137 + current = pending;
6.138 + pending = pending->next;
6.139 + SDL_AddTimerInternal(data, current);
6.140 + }
6.141 + freelist_head = NULL;
6.142 + freelist_tail = NULL;
6.143 +
6.144 + /* Check to see if we're still running, after maintenance */
6.145 + if (!data->active) {
6.146 + break;
6.147 + }
6.148 +
6.149 + /* Initial delay if there are no timers */
6.150 + delay = SDL_MUTEX_MAXWAIT;
6.151 +
6.152 + tick = SDL_GetTicks();
6.153 +
6.154 + /* Process all the pending timers for this tick */
6.155 + while (data->timers) {
6.156 + current = data->timers;
6.157
6.158 -/* Set whether or not the timer should use a thread.
6.159 - This should not be called while the timer subsystem is running.
6.160 -*/
6.161 -int
6.162 -SDL_SetTimerThreaded(int value)
6.163 -{
6.164 - int retval;
6.165 + if ((Sint32)(tick-current->scheduled) < 0) {
6.166 + /* Scheduled for the future, wait a bit */
6.167 + delay = (current->scheduled - tick);
6.168 + break;
6.169 + }
6.170 +
6.171 + /* We're going to do something with this timer */
6.172 + data->timers = current->next;
6.173 +
6.174 + if (current->canceled) {
6.175 + interval = 0;
6.176 + } else {
6.177 + interval = current->callback(current->interval, current->param);
6.178 + }
6.179
6.180 - if (SDL_timer_started) {
6.181 - SDL_SetError("Timer already initialized");
6.182 - retval = -1;
6.183 - } else {
6.184 - retval = 0;
6.185 - SDL_timer_threaded = value;
6.186 + if (interval > 0) {
6.187 + /* Reschedule this timer */
6.188 + current->scheduled = tick + interval;
6.189 + SDL_AddTimerInternal(data, current);
6.190 + } else {
6.191 + if (!freelist_head) {
6.192 + freelist_head = current;
6.193 + }
6.194 + if (freelist_tail) {
6.195 + freelist_tail->next = current;
6.196 + }
6.197 + freelist_tail = current;
6.198 +
6.199 + current->canceled = SDL_TRUE;
6.200 + }
6.201 + }
6.202 +
6.203 + /* Adjust the delay based on processing time */
6.204 + now = SDL_GetTicks();
6.205 + interval = (now - tick);
6.206 + if (interval > delay) {
6.207 + delay = 0;
6.208 + } else {
6.209 + delay -= interval;
6.210 + }
6.211 +
6.212 + /* Note that each time a timer is added, this will return
6.213 + immediately, but we process the timers added all at once.
6.214 + That's okay, it just means we run through the loop a few
6.215 + extra times.
6.216 + */
6.217 + SDL_SemWaitTimeout(data->sem, delay);
6.218 }
6.219 - return retval;
6.220 + return 0;
6.221 }
6.222
6.223 int
6.224 SDL_TimerInit(void)
6.225 {
6.226 - int retval;
6.227 + SDL_TimerData *data = &SDL_timer_data;
6.228 +
6.229 + if (!data->active) {
6.230 + data->timermap_lock = SDL_CreateMutex();
6.231 + if (!data->timermap_lock) {
6.232 + return -1;
6.233 + }
6.234
6.235 - retval = 0;
6.236 - if (SDL_timer_started) {
6.237 - SDL_TimerQuit();
6.238 + data->sem = SDL_CreateSemaphore(0);
6.239 + if (!data->sem) {
6.240 + SDL_DestroyMutex(data->timermap_lock);
6.241 + return -1;
6.242 + }
6.243 +
6.244 + data->active = SDL_TRUE;
6.245 + data->thread = SDL_CreateThread(SDL_TimerThread, data);
6.246 + if (!data->thread) {
6.247 + SDL_TimerQuit();
6.248 + return -1;
6.249 + }
6.250 +
6.251 + SDL_AtomicSet(&data->nextID, 1);
6.252 }
6.253 - if (!SDL_timer_threaded) {
6.254 - retval = SDL_SYS_TimerInit();
6.255 - }
6.256 - if (SDL_timer_threaded) {
6.257 - SDL_timer_mutex = SDL_CreateMutex();
6.258 - }
6.259 - if (retval == 0) {
6.260 - SDL_timer_started = 1;
6.261 - }
6.262 - return (retval);
6.263 + return 0;
6.264 }
6.265
6.266 void
6.267 SDL_TimerQuit(void)
6.268 {
6.269 - SDL_SetTimer(0, NULL);
6.270 - if (SDL_timer_threaded < 2) {
6.271 - SDL_SYS_TimerQuit();
6.272 - }
6.273 - if (SDL_timer_threaded) {
6.274 - SDL_DestroyMutex(SDL_timer_mutex);
6.275 - SDL_timer_mutex = NULL;
6.276 - }
6.277 - SDL_timer_started = 0;
6.278 - SDL_timer_threaded = 0;
6.279 -}
6.280 + SDL_TimerData *data = &SDL_timer_data;
6.281 + SDL_Timer *timer;
6.282 + SDL_TimerMap *entry;
6.283 +
6.284 + if (data->active) {
6.285 + data->active = SDL_FALSE;
6.286
6.287 -void
6.288 -SDL_ThreadedTimerCheck(void)
6.289 -{
6.290 - Uint32 now, ms;
6.291 - SDL_TimerID t, prev, next;
6.292 - SDL_bool removed;
6.293 -
6.294 - SDL_mutexP(SDL_timer_mutex);
6.295 + /* Shutdown the timer thread */
6.296 + if (data->thread) {
6.297 + SDL_SemPost(data->sem);
6.298 + SDL_WaitThread(data->thread, NULL);
6.299 + data->thread = NULL;
6.300 + }
6.301
6.302 - now = SDL_GetTicks();
6.303 - do {
6.304 - list_changed = SDL_FALSE;
6.305 - for (prev = NULL, t = SDL_timers; t; t = next) {
6.306 - removed = SDL_FALSE;
6.307 - ms = t->interval - SDL_TIMESLICE;
6.308 - next = t->next;
6.309 - if ((int) (now - t->last_alarm) > (int) ms) {
6.310 - struct _SDL_TimerID timer;
6.311 + SDL_DestroySemaphore(data->sem);
6.312 + data->sem = NULL;
6.313
6.314 - if ((now - t->last_alarm) < t->interval) {
6.315 - t->last_alarm += t->interval;
6.316 - } else {
6.317 - t->last_alarm = now;
6.318 - }
6.319 -#ifdef DEBUG_TIMERS
6.320 - printf("Executing timer %p (thread = %lu)\n",
6.321 - t, SDL_ThreadID());
6.322 -#endif
6.323 - timer = *t;
6.324 - SDL_mutexV(SDL_timer_mutex);
6.325 - ms = timer.cb(timer.interval, timer.param);
6.326 - SDL_mutexP(SDL_timer_mutex);
6.327 - if (list_changed) {
6.328 - next = t->next;
6.329 - for (prev = SDL_timers; prev; prev = prev->next) {
6.330 - if (prev->next == t)
6.331 - break;
6.332 - }
6.333 - }
6.334 - if (ms != t->interval) {
6.335 - if (ms) {
6.336 - t->interval = ROUND_RESOLUTION(ms);
6.337 - } else {
6.338 - /* Remove timer from the list */
6.339 -#ifdef DEBUG_TIMERS
6.340 - printf("SDL: Removing timer %p\n", t);
6.341 -#endif
6.342 - if (prev) {
6.343 - prev->next = next;
6.344 - } else {
6.345 - SDL_timers = next;
6.346 - }
6.347 - SDL_free(t);
6.348 - --SDL_timer_running;
6.349 - removed = SDL_TRUE;
6.350 - }
6.351 - }
6.352 - if (list_changed) {
6.353 - /* Abort, list of timers modified */
6.354 - break;
6.355 - }
6.356 - }
6.357 - /* Don't update prev if the timer has disappeared */
6.358 - if (!removed) {
6.359 - prev = t;
6.360 - }
6.361 + /* Clean up the timer entries */
6.362 + while (data->timers) {
6.363 + timer = data->timers;
6.364 + data->timers = timer->next;
6.365 + SDL_free(timer);
6.366 }
6.367 - } while (list_changed);
6.368 -
6.369 - SDL_mutexV(SDL_timer_mutex);
6.370 -}
6.371 + while (data->freelist) {
6.372 + timer = data->freelist;
6.373 + data->freelist = timer->next;
6.374 + SDL_free(timer);
6.375 + }
6.376 + while (data->timermap) {
6.377 + entry = data->timermap;
6.378 + data->timermap = entry->next;
6.379 + SDL_free(entry);
6.380 + }
6.381
6.382 -static SDL_TimerID
6.383 -SDL_AddTimerInternal(Uint32 interval, SDL_NewTimerCallback callback,
6.384 - void *param)
6.385 -{
6.386 - SDL_TimerID t;
6.387 - t = (SDL_TimerID) SDL_malloc(sizeof(struct _SDL_TimerID));
6.388 - if (t) {
6.389 - t->interval = ROUND_RESOLUTION(interval);
6.390 - t->cb = callback;
6.391 - t->param = param;
6.392 - t->last_alarm = SDL_GetTicks();
6.393 - t->next = SDL_timers;
6.394 - SDL_timers = t;
6.395 - ++SDL_timer_running;
6.396 - list_changed = SDL_TRUE;
6.397 + SDL_DestroyMutex(data->timermap_lock);
6.398 + data->timermap_lock = NULL;
6.399 }
6.400 -#ifdef DEBUG_TIMERS
6.401 - printf("SDL_AddTimer(%d) = %08x num_timers = %d\n", interval, (Uint32) t,
6.402 - SDL_timer_running);
6.403 -#endif
6.404 - return t;
6.405 }
6.406
6.407 SDL_TimerID
6.408 -SDL_AddTimer(Uint32 interval, SDL_NewTimerCallback callback, void *param)
6.409 +SDL_AddTimer(Uint32 interval, SDL_TimerCallback callback, void *param)
6.410 {
6.411 - SDL_TimerID t;
6.412 - if (!SDL_timer_mutex) {
6.413 - if (SDL_timer_started) {
6.414 - SDL_SetError("This platform doesn't support multiple timers");
6.415 - } else {
6.416 - SDL_SetError("You must call SDL_Init(SDL_INIT_TIMER) first");
6.417 + SDL_TimerData *data = &SDL_timer_data;
6.418 + SDL_Timer *timer;
6.419 + SDL_TimerMap *entry;
6.420 +
6.421 + if (!data->active) {
6.422 + int status = 0;
6.423 +
6.424 + SDL_AtomicLock(&data->lock);
6.425 + if (!data->active) {
6.426 + status = SDL_TimerInit();
6.427 + }
6.428 + SDL_AtomicUnlock(&data->lock);
6.429 +
6.430 + if (status < 0) {
6.431 + return 0;
6.432 }
6.433 - return NULL;
6.434 + }
6.435 +
6.436 + SDL_AtomicLock(&data->lock);
6.437 + timer = data->freelist;
6.438 + if (timer) {
6.439 + data->freelist = timer->next;
6.440 + }
6.441 + SDL_AtomicUnlock(&data->lock);
6.442 +
6.443 + if (timer) {
6.444 + SDL_RemoveTimer(timer->timerID);
6.445 + } else {
6.446 + timer = (SDL_Timer *)SDL_malloc(sizeof(*timer));
6.447 + if (!timer) {
6.448 + SDL_OutOfMemory();
6.449 + return 0;
6.450 + }
6.451 }
6.452 - if (!SDL_timer_threaded) {
6.453 - SDL_SetError("Multiple timers require threaded events!");
6.454 - return NULL;
6.455 + timer->timerID = SDL_AtomicIncRef(&data->nextID);
6.456 + timer->callback = callback;
6.457 + timer->param = param;
6.458 + timer->interval = interval;
6.459 + timer->scheduled = SDL_GetTicks() + interval;
6.460 + timer->canceled = SDL_FALSE;
6.461 +
6.462 + entry = (SDL_TimerMap *)SDL_malloc(sizeof(*entry));
6.463 + if (!entry) {
6.464 + SDL_free(timer);
6.465 + SDL_OutOfMemory();
6.466 + return 0;
6.467 }
6.468 - SDL_mutexP(SDL_timer_mutex);
6.469 - t = SDL_AddTimerInternal(interval, callback, param);
6.470 - SDL_mutexV(SDL_timer_mutex);
6.471 - return t;
6.472 + entry->timer = timer;
6.473 + entry->timerID = timer->timerID;
6.474 +
6.475 + SDL_mutexP(data->timermap_lock);
6.476 + entry->next = data->timermap;
6.477 + data->timermap = entry;
6.478 + SDL_mutexV(data->timermap_lock);
6.479 +
6.480 + /* Add the timer to the pending list for the timer thread */
6.481 + SDL_AtomicLock(&data->lock);
6.482 + timer->next = data->pending;
6.483 + data->pending = timer;
6.484 + SDL_AtomicUnlock(&data->lock);
6.485 +
6.486 + /* Wake up the timer thread if necessary */
6.487 + SDL_SemPost(data->sem);
6.488 +
6.489 + return entry->timerID;
6.490 }
6.491
6.492 SDL_bool
6.493 SDL_RemoveTimer(SDL_TimerID id)
6.494 {
6.495 - SDL_TimerID t, prev = NULL;
6.496 - SDL_bool removed;
6.497 + SDL_TimerData *data = &SDL_timer_data;
6.498 + SDL_TimerMap *prev, *entry;
6.499 + SDL_bool canceled = SDL_FALSE;
6.500
6.501 - removed = SDL_FALSE;
6.502 - SDL_mutexP(SDL_timer_mutex);
6.503 - /* Look for id in the linked list of timers */
6.504 - for (t = SDL_timers; t; prev = t, t = t->next) {
6.505 - if (t == id) {
6.506 + /* Find the timer */
6.507 + SDL_mutexP(data->timermap_lock);
6.508 + prev = NULL;
6.509 + for (entry = data->timermap; entry; prev = entry, entry = entry->next) {
6.510 + if (entry->timerID == id) {
6.511 if (prev) {
6.512 - prev->next = t->next;
6.513 + prev->next = entry->next;
6.514 } else {
6.515 - SDL_timers = t->next;
6.516 + data->timermap = entry->next;
6.517 }
6.518 - SDL_free(t);
6.519 - --SDL_timer_running;
6.520 - removed = SDL_TRUE;
6.521 - list_changed = SDL_TRUE;
6.522 break;
6.523 }
6.524 }
6.525 -#ifdef DEBUG_TIMERS
6.526 - printf("SDL_RemoveTimer(%08x) = %d num_timers = %d thread = %lu\n",
6.527 - (Uint32) id, removed, SDL_timer_running, SDL_ThreadID());
6.528 -#endif
6.529 - SDL_mutexV(SDL_timer_mutex);
6.530 - return removed;
6.531 -}
6.532 + SDL_mutexV(data->timermap_lock);
6.533
6.534 -/* Old style callback functions are wrapped through this */
6.535 -static Uint32 SDLCALL
6.536 -callback_wrapper(Uint32 ms, void *param)
6.537 -{
6.538 - SDL_TimerCallback func = (SDL_TimerCallback) param;
6.539 - return (*func) (ms);
6.540 -}
6.541 -
6.542 -int
6.543 -SDL_SetTimer(Uint32 ms, SDL_TimerCallback callback)
6.544 -{
6.545 - int retval;
6.546 -
6.547 -#ifdef DEBUG_TIMERS
6.548 - printf("SDL_SetTimer(%d)\n", ms);
6.549 -#endif
6.550 - retval = 0;
6.551 -
6.552 - if (SDL_timer_threaded) {
6.553 - SDL_mutexP(SDL_timer_mutex);
6.554 + if (entry) {
6.555 + if (!entry->timer->canceled) {
6.556 + entry->timer->canceled = SDL_TRUE;
6.557 + canceled = SDL_TRUE;
6.558 + }
6.559 + SDL_free(entry);
6.560 }
6.561 - if (SDL_timer_running) { /* Stop any currently running timer */
6.562 - if (SDL_timer_threaded) {
6.563 - while (SDL_timers) {
6.564 - SDL_TimerID freeme = SDL_timers;
6.565 - SDL_timers = SDL_timers->next;
6.566 - SDL_free(freeme);
6.567 - }
6.568 - SDL_timer_running = 0;
6.569 - list_changed = SDL_TRUE;
6.570 - } else {
6.571 - SDL_SYS_StopTimer();
6.572 - SDL_timer_running = 0;
6.573 - }
6.574 - }
6.575 - if (ms) {
6.576 - if (SDL_timer_threaded) {
6.577 - if (SDL_AddTimerInternal
6.578 - (ms, callback_wrapper, (void *) callback) == NULL) {
6.579 - retval = -1;
6.580 - }
6.581 - } else {
6.582 - SDL_timer_running = 1;
6.583 - SDL_alarm_interval = ms;
6.584 - SDL_alarm_callback = callback;
6.585 - retval = SDL_SYS_StartTimer();
6.586 - }
6.587 - }
6.588 - if (SDL_timer_threaded) {
6.589 - SDL_mutexV(SDL_timer_mutex);
6.590 - }
6.591 -
6.592 - return retval;
6.593 + return canceled;
6.594 }
6.595
6.596 /* vi: set ts=4 sw=4 expandtab: */
7.1 --- a/src/timer/SDL_timer_c.h Thu Jan 27 10:40:17 2011 -0800
7.2 +++ b/src/timer/SDL_timer_c.h Thu Jan 27 14:45:06 2011 -0800
7.3 @@ -27,21 +27,7 @@
7.4 #define ROUND_RESOLUTION(X) \
7.5 (((X+TIMER_RESOLUTION-1)/TIMER_RESOLUTION)*TIMER_RESOLUTION)
7.6
7.7 -extern int SDL_timer_started;
7.8 -extern int SDL_timer_running;
7.9 -
7.10 -/* Data to handle a single periodic alarm */
7.11 -extern Uint32 SDL_alarm_interval;
7.12 -extern SDL_TimerCallback SDL_alarm_callback;
7.13 -
7.14 -/* Set whether or not the timer should use a thread.
7.15 - This should be called while the timer subsystem is running.
7.16 -*/
7.17 -extern int SDL_SetTimerThreaded(int value);
7.18 -
7.19 extern int SDL_TimerInit(void);
7.20 extern void SDL_TimerQuit(void);
7.21
7.22 -/* This function is called from the SDL event thread if it is available */
7.23 -extern void SDL_ThreadedTimerCheck(void);
7.24 /* vi: set ts=4 sw=4 expandtab: */
8.1 --- a/src/timer/beos/SDL_systimer.c Thu Jan 27 10:40:17 2011 -0800
8.2 +++ b/src/timer/beos/SDL_systimer.c Thu Jan 27 14:45:06 2011 -0800
8.3 @@ -25,9 +25,7 @@
8.4
8.5 #include <be/kernel/OS.h>
8.6
8.7 -#include "SDL_thread.h"
8.8 #include "SDL_timer.h"
8.9 -#include "../SDL_timer_c.h"
8.10
8.11 static bigtime_t start;
8.12
8.13 @@ -50,55 +48,6 @@
8.14 snooze(ms * 1000);
8.15 }
8.16
8.17 -/* Data to handle a single periodic alarm */
8.18 -static int timer_alive = 0;
8.19 -static SDL_Thread *timer = NULL;
8.20 -
8.21 -static int
8.22 -RunTimer(void *unused)
8.23 -{
8.24 - while (timer_alive) {
8.25 - if (SDL_timer_running) {
8.26 - SDL_ThreadedTimerCheck();
8.27 - }
8.28 - SDL_Delay(10);
8.29 - }
8.30 - return (0);
8.31 -}
8.32 +#endif /* SDL_TIMER_BEOS */
8.33
8.34 -/* This is only called if the event thread is not running */
8.35 -int
8.36 -SDL_SYS_TimerInit(void)
8.37 -{
8.38 - timer_alive = 1;
8.39 - timer = SDL_CreateThread(RunTimer, NULL);
8.40 - if (timer == NULL)
8.41 - return (-1);
8.42 - return (SDL_SetTimerThreaded(1));
8.43 -}
8.44 -
8.45 -void
8.46 -SDL_SYS_TimerQuit(void)
8.47 -{
8.48 - timer_alive = 0;
8.49 - if (timer) {
8.50 - SDL_WaitThread(timer, NULL);
8.51 - timer = NULL;
8.52 - }
8.53 -}
8.54 -
8.55 -int
8.56 -SDL_SYS_StartTimer(void)
8.57 -{
8.58 - SDL_SetError("Internal logic error: BeOS uses threaded timer");
8.59 - return (-1);
8.60 -}
8.61 -
8.62 -void
8.63 -SDL_SYS_StopTimer(void)
8.64 -{
8.65 - return;
8.66 -}
8.67 -
8.68 -#endif /* SDL_TIMER_BEOS */
8.69 /* vi: set ts=4 sw=4 expandtab: */
9.1 --- a/src/timer/dummy/SDL_systimer.c Thu Jan 27 10:40:17 2011 -0800
9.2 +++ b/src/timer/dummy/SDL_systimer.c Thu Jan 27 14:45:06 2011 -0800
9.3 @@ -24,7 +24,6 @@
9.4 #if defined(SDL_TIMER_DUMMY) || defined(SDL_TIMERS_DISABLED)
9.5
9.6 #include "SDL_timer.h"
9.7 -#include "../SDL_timer_c.h"
9.8
9.9 void
9.10 SDL_StartTicks(void)
9.11 @@ -44,57 +43,6 @@
9.12 SDL_Unsupported();
9.13 }
9.14
9.15 -#include "SDL_thread.h"
9.16 -
9.17 -/* Data to handle a single periodic alarm */
9.18 -static int timer_alive = 0;
9.19 -static SDL_Thread *timer = NULL;
9.20 -
9.21 -static int
9.22 -RunTimer(void *unused)
9.23 -{
9.24 - while (timer_alive) {
9.25 - if (SDL_timer_running) {
9.26 - SDL_ThreadedTimerCheck();
9.27 - }
9.28 - SDL_Delay(1);
9.29 - }
9.30 - return (0);
9.31 -}
9.32 +#endif /* SDL_TIMER_DUMMY || SDL_TIMERS_DISABLED */
9.33
9.34 -/* This is only called if the event thread is not running */
9.35 -int
9.36 -SDL_SYS_TimerInit(void)
9.37 -{
9.38 - timer_alive = 1;
9.39 - timer = SDL_CreateThread(RunTimer, NULL);
9.40 - if (timer == NULL)
9.41 - return (-1);
9.42 - return (SDL_SetTimerThreaded(1));
9.43 -}
9.44 -
9.45 -void
9.46 -SDL_SYS_TimerQuit(void)
9.47 -{
9.48 - timer_alive = 0;
9.49 - if (timer) {
9.50 - SDL_WaitThread(timer, NULL);
9.51 - timer = NULL;
9.52 - }
9.53 -}
9.54 -
9.55 -int
9.56 -SDL_SYS_StartTimer(void)
9.57 -{
9.58 - SDL_SetError("Internal logic error: threaded timer in use");
9.59 - return (-1);
9.60 -}
9.61 -
9.62 -void
9.63 -SDL_SYS_StopTimer(void)
9.64 -{
9.65 - return;
9.66 -}
9.67 -
9.68 -#endif /* SDL_TIMER_DUMMY || SDL_TIMERS_DISABLED */
9.69 /* vi: set ts=4 sw=4 expandtab: */
10.1 --- a/src/timer/nds/SDL_systimer.c Thu Jan 27 10:40:17 2011 -0800
10.2 +++ b/src/timer/nds/SDL_systimer.c Thu Jan 27 14:45:06 2011 -0800
10.3 @@ -27,22 +27,25 @@
10.4 #include <nds/timers.h>
10.5
10.6 #include "SDL_timer.h"
10.7 -#include "../SDL_timer_c.h"
10.8 -#include "../SDL_systimer.h"
10.9 +
10.10 +
10.11 +static volatile Uint32 timer_ticks;
10.12
10.13 -/* Data to handle a single periodic alarm */
10.14 -static int timer_alive = 0;
10.15 -static Uint32 timer_ticks;
10.16 +static void
10.17 +NDS_TimerInterrupt(void)
10.18 +{
10.19 + timer_ticks++;
10.20 +}
10.21
10.22 void
10.23 SDL_StartTicks(void)
10.24 {
10.25 - if (!timer_alive) {
10.26 - SDL_SYS_TimerInit();
10.27 - SDL_SYS_StartTimer();
10.28 - }
10.29 + timer_ticks = 0;
10.30
10.31 - timer_ticks = 0;
10.32 + TIMER_CR(3) = TIMER_DIV_1024 | TIMER_IRQ_REQ;
10.33 + TIMER_DATA(3) = TIMER_FREQ_1024(1000);
10.34 + irqSet(IRQ_TIMER3, NDS_TimerInterrupt);
10.35 + irqEnable(IRQ_TIMER3);
10.36 }
10.37
10.38 Uint32
10.39 @@ -61,60 +64,6 @@
10.40 }
10.41 }
10.42
10.43 -static int
10.44 -RunTimer(void *unused)
10.45 -{
10.46 - while (timer_alive) {
10.47 - if (SDL_timer_running) {
10.48 - }
10.49 - SDL_Delay(1);
10.50 - }
10.51 - return (0);
10.52 -}
10.53 -
10.54 -void
10.55 -NDS_TimerInterrupt(void)
10.56 -{
10.57 - timer_ticks++;
10.58 -}
10.59 +#endif /* SDL_TIMER_NDS */
10.60
10.61 -/* This is only called if the event thread is not running */
10.62 -int
10.63 -SDL_SYS_TimerInit(void)
10.64 -{
10.65 - timer_alive = 1;
10.66 - timer_ticks = 0;
10.67 - TIMER_CR(3) = TIMER_DIV_1024 | TIMER_IRQ_REQ;
10.68 - TIMER_DATA(3) = TIMER_FREQ_1024(1000);
10.69 - irqSet(IRQ_TIMER3, NDS_TimerInterrupt);
10.70 - irqEnable(IRQ_TIMER3);
10.71 - return 0;
10.72 -}
10.73 -
10.74 -void
10.75 -SDL_SYS_TimerQuit(void)
10.76 -{
10.77 - if (timer_alive) {
10.78 - TIMER_CR(3) = 0;
10.79 - }
10.80 - timer_alive = 0;
10.81 - irqDisable(IRQ_TIMER3);
10.82 -}
10.83 -
10.84 -int
10.85 -SDL_SYS_StartTimer(void)
10.86 -{
10.87 - TIMER_CR(3) |= TIMER_ENABLE;
10.88 - return 0;
10.89 -}
10.90 -
10.91 -void
10.92 -SDL_SYS_StopTimer(void)
10.93 -{
10.94 - TIMER_CR(3) &= ~TIMER_ENABLE;
10.95 - return;
10.96 -}
10.97 -
10.98 -
10.99 -#endif /* SDL_TIMER_NDS */
10.100 /* vi: set ts=4 sw=4 expandtab: */
11.1 --- a/src/timer/unix/SDL_systimer.c Thu Jan 27 10:40:17 2011 -0800
11.2 +++ b/src/timer/unix/SDL_systimer.c Thu Jan 27 14:45:06 2011 -0800
11.3 @@ -25,14 +25,10 @@
11.4
11.5 #include <stdio.h>
11.6 #include <sys/time.h>
11.7 -#include <signal.h>
11.8 #include <unistd.h>
11.9 -#include <string.h>
11.10 #include <errno.h>
11.11
11.12 #include "SDL_timer.h"
11.13 -#include "../SDL_systimer.h"
11.14 -#include "../SDL_timer_c.h"
11.15
11.16 /* The clock_gettime provides monotonous time, so we should use it if
11.17 it's available. The clock_gettime function is behind ifdef
11.18 @@ -43,10 +39,6 @@
11.19 #include <time.h>
11.20 #endif
11.21
11.22 -#if SDL_THREADS_DISABLED
11.23 -#define USE_ITIMER
11.24 -#endif
11.25 -
11.26 /* The first ticks value of the application */
11.27 #ifdef HAVE_CLOCK_GETTIME
11.28 static struct timespec start;
11.29 @@ -131,118 +123,6 @@
11.30 } while (was_error && (errno == EINTR));
11.31 }
11.32
11.33 -#ifdef USE_ITIMER
11.34 -
11.35 -static void
11.36 -HandleAlarm(int sig)
11.37 -{
11.38 - Uint32 ms;
11.39 -
11.40 - if (SDL_alarm_callback) {
11.41 - ms = (*SDL_alarm_callback) (SDL_alarm_interval);
11.42 - if (ms != SDL_alarm_interval) {
11.43 - SDL_SetTimer(ms, SDL_alarm_callback);
11.44 - }
11.45 - }
11.46 -}
11.47 -
11.48 -int
11.49 -SDL_SYS_TimerInit(void)
11.50 -{
11.51 - struct sigaction action;
11.52 -
11.53 - /* Set the alarm handler (Linux specific) */
11.54 - SDL_memset(&action, 0, sizeof(action));
11.55 - action.sa_handler = HandleAlarm;
11.56 - action.sa_flags = SA_RESTART;
11.57 - sigemptyset(&action.sa_mask);
11.58 - sigaction(SIGALRM, &action, NULL);
11.59 - return (0);
11.60 -}
11.61 -
11.62 -void
11.63 -SDL_SYS_TimerQuit(void)
11.64 -{
11.65 - SDL_SetTimer(0, NULL);
11.66 -}
11.67 -
11.68 -int
11.69 -SDL_SYS_StartTimer(void)
11.70 -{
11.71 - struct itimerval timer;
11.72 -
11.73 - timer.it_value.tv_sec = (SDL_alarm_interval / 1000);
11.74 - timer.it_value.tv_usec = (SDL_alarm_interval % 1000) * 1000;
11.75 - timer.it_interval.tv_sec = (SDL_alarm_interval / 1000);
11.76 - timer.it_interval.tv_usec = (SDL_alarm_interval % 1000) * 1000;
11.77 - setitimer(ITIMER_REAL, &timer, NULL);
11.78 - return (0);
11.79 -}
11.80 -
11.81 -void
11.82 -SDL_SYS_StopTimer(void)
11.83 -{
11.84 - struct itimerval timer;
11.85 -
11.86 - SDL_memset(&timer, 0, (sizeof timer));
11.87 - setitimer(ITIMER_REAL, &timer, NULL);
11.88 -}
11.89 +#endif /* SDL_TIMER_UNIX */
11.90
11.91 -#else /* USE_ITIMER */
11.92 -
11.93 -#include "SDL_thread.h"
11.94 -
11.95 -/* Data to handle a single periodic alarm */
11.96 -static int timer_alive = 0;
11.97 -static SDL_Thread *timer = NULL;
11.98 -
11.99 -static int
11.100 -RunTimer(void *unused)
11.101 -{
11.102 - while (timer_alive) {
11.103 - if (SDL_timer_running) {
11.104 - SDL_ThreadedTimerCheck();
11.105 - }
11.106 - SDL_Delay(1);
11.107 - }
11.108 - return (0);
11.109 -}
11.110 -
11.111 -/* This is only called if the event thread is not running */
11.112 -int
11.113 -SDL_SYS_TimerInit(void)
11.114 -{
11.115 - timer_alive = 1;
11.116 - timer = SDL_CreateThread(RunTimer, NULL);
11.117 - if (timer == NULL)
11.118 - return (-1);
11.119 - return (SDL_SetTimerThreaded(1));
11.120 -}
11.121 -
11.122 -void
11.123 -SDL_SYS_TimerQuit(void)
11.124 -{
11.125 - timer_alive = 0;
11.126 - if (timer) {
11.127 - SDL_WaitThread(timer, NULL);
11.128 - timer = NULL;
11.129 - }
11.130 -}
11.131 -
11.132 -int
11.133 -SDL_SYS_StartTimer(void)
11.134 -{
11.135 - SDL_SetError("Internal logic error: Linux uses threaded timer");
11.136 - return (-1);
11.137 -}
11.138 -
11.139 -void
11.140 -SDL_SYS_StopTimer(void)
11.141 -{
11.142 - return;
11.143 -}
11.144 -
11.145 -#endif /* USE_ITIMER */
11.146 -
11.147 -#endif /* SDL_TIMER_UNIX */
11.148 /* vi: set ts=4 sw=4 expandtab: */
12.1 --- a/src/timer/wince/SDL_systimer.c Thu Jan 27 10:40:17 2011 -0800
12.2 +++ b/src/timer/wince/SDL_systimer.c Thu Jan 27 14:45:06 2011 -0800
12.3 @@ -24,11 +24,8 @@
12.4 #ifdef SDL_TIMER_WINCE
12.5
12.6 #include "../../core/windows/SDL_windows.h"
12.7 -#include <mmsystem.h>
12.8
12.9 -#include "SDL_thread.h"
12.10 #include "SDL_timer.h"
12.11 -#include "../SDL_timer_c.h"
12.12
12.13 static Uint64 start_date;
12.14 static Uint64 start_ticks;
12.15 @@ -69,6 +66,14 @@
12.16 return ((Sint32) (wce_date() - start_date));
12.17 }
12.18
12.19 +/* Recard start-time of application for reference */
12.20 +void
12.21 +SDL_StartTicks(void)
12.22 +{
12.23 + start_date = wce_date();
12.24 + start_ticks = wce_ticks();
12.25 +}
12.26 +
12.27 /* Return time in ms relative to when SDL was started */
12.28 Uint32
12.29 SDL_GetTicks()
12.30 @@ -89,122 +94,6 @@
12.31 Sleep(ms);
12.32 }
12.33
12.34 -/* Recard start-time of application for reference */
12.35 -void
12.36 -SDL_StartTicks(void)
12.37 -{
12.38 - start_date = wce_date();
12.39 - start_ticks = wce_ticks();
12.40 -}
12.41 -
12.42 -static UINT WIN_timer;
12.43 -
12.44 -#if ( _WIN32_WCE <= 420 )
12.45 -
12.46 -static HANDLE timersThread = 0;
12.47 -static HANDLE timersQuitEvent = 0;
12.48 -
12.49 -DWORD
12.50 -TimersThreadProc(void *data)
12.51 -{
12.52 - while (WaitForSingleObject(timersQuitEvent, 10) == WAIT_TIMEOUT) {
12.53 - SDL_ThreadedTimerCheck();
12.54 - }
12.55 - return 0;
12.56 -}
12.57 -
12.58 -int
12.59 -SDL_SYS_TimerInit(void)
12.60 -{
12.61 - // create a thread to process a threaded timers
12.62 - // SetTimer does not suit the needs because
12.63 - // TimerCallbackProc will be called only when WM_TIMER occured
12.64 -
12.65 - timersQuitEvent = CreateEvent(0, TRUE, FALSE, 0);
12.66 - if (!timersQuitEvent) {
12.67 - SDL_SetError("Cannot create event for timers thread");
12.68 - return -1;
12.69 - }
12.70 - timersThread = CreateThread(NULL, 0, TimersThreadProc, 0, 0, 0);
12.71 - if (!timersThread) {
12.72 - SDL_SetError
12.73 - ("Cannot create timers thread, check amount of RAM available");
12.74 - return -1;
12.75 - }
12.76 - SetThreadPriority(timersThread, THREAD_PRIORITY_HIGHEST);
12.77 -
12.78 - return (SDL_SetTimerThreaded(1));
12.79 -}
12.80 -
12.81 -void
12.82 -SDL_SYS_TimerQuit(void)
12.83 -{
12.84 - SetEvent(timersQuitEvent);
12.85 - if (WaitForSingleObject(timersThread, 2000) == WAIT_TIMEOUT)
12.86 - TerminateThread(timersThread, 0);
12.87 - CloseHandle(timersThread);
12.88 - CloseHandle(timersQuitEvent);
12.89 - return;
12.90 -}
12.91 -
12.92 -#else
12.93 +#endif /* SDL_TIMER_WINCE */
12.94
12.95 -#pragma comment(lib, "mmtimer.lib")
12.96 -
12.97 -/* Data to handle a single periodic alarm */
12.98 -static UINT timerID = 0;
12.99 -
12.100 -static void CALLBACK
12.101 -HandleAlarm(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
12.102 -{
12.103 - SDL_ThreadedTimerCheck();
12.104 -}
12.105 -
12.106 -
12.107 -int
12.108 -SDL_SYS_TimerInit(void)
12.109 -{
12.110 - MMRESULT result;
12.111 -
12.112 - /* Set timer resolution */
12.113 - result = timeBeginPeriod(TIMER_RESOLUTION);
12.114 - if (result != TIMERR_NOERROR) {
12.115 - SDL_SetError("Warning: Can't set %d ms timer resolution",
12.116 - TIMER_RESOLUTION);
12.117 - }
12.118 - /* Allow 10 ms of drift so we don't chew on CPU */
12.119 - timerID =
12.120 - timeSetEvent(TIMER_RESOLUTION, 1, HandleAlarm, 0, TIME_PERIODIC);
12.121 - if (!timerID) {
12.122 - SDL_SetError("timeSetEvent() failed");
12.123 - return (-1);
12.124 - }
12.125 - return (SDL_SetTimerThreaded(1));
12.126 -}
12.127 -
12.128 -void
12.129 -SDL_SYS_TimerQuit(void)
12.130 -{
12.131 - if (timerID) {
12.132 - timeKillEvent(timerID);
12.133 - }
12.134 - timeEndPeriod(TIMER_RESOLUTION);
12.135 -}
12.136 -
12.137 -#endif
12.138 -
12.139 -int
12.140 -SDL_SYS_StartTimer(void)
12.141 -{
12.142 - SDL_SetError("Internal logic error: WinCE uses threaded timer");
12.143 - return (-1);
12.144 -}
12.145 -
12.146 -void
12.147 -SDL_SYS_StopTimer(void)
12.148 -{
12.149 - return;
12.150 -}
12.151 -
12.152 -#endif /* SDL_TIMER_WINCE */
12.153 /* vi: set ts=4 sw=4 expandtab: */
13.1 --- a/src/timer/windows/SDL_systimer.c Thu Jan 27 10:40:17 2011 -0800
13.2 +++ b/src/timer/windows/SDL_systimer.c Thu Jan 27 14:45:06 2011 -0800
13.3 @@ -24,10 +24,8 @@
13.4 #ifdef SDL_TIMER_WINDOWS
13.5
13.6 #include "../../core/windows/SDL_windows.h"
13.7 -#include <mmsystem.h>
13.8
13.9 #include "SDL_timer.h"
13.10 -#include "../SDL_timer_c.h"
13.11
13.12 #ifdef _WIN32_WCE
13.13 #error This is WinCE. Please use src/timer/wince/SDL_systimer.c instead.
13.14 @@ -106,60 +104,6 @@
13.15 Sleep(ms);
13.16 }
13.17
13.18 -/* Data to handle a single periodic alarm */
13.19 -static UINT timerID = 0;
13.20 -
13.21 -static void CALLBACK
13.22 -HandleAlarm(UINT uID, UINT uMsg, DWORD_PTR dwUser,
13.23 - DWORD_PTR dw1, DWORD_PTR dw2)
13.24 -{
13.25 - SDL_ThreadedTimerCheck();
13.26 -}
13.27 -
13.28 -
13.29 -int
13.30 -SDL_SYS_TimerInit(void)
13.31 -{
13.32 - MMRESULT result;
13.33 -
13.34 - /* Set timer resolution */
13.35 - result = timeBeginPeriod(TIMER_RESOLUTION);
13.36 - if (result != TIMERR_NOERROR) {
13.37 - SDL_SetError("Warning: Can't set %d ms timer resolution",
13.38 - TIMER_RESOLUTION);
13.39 - }
13.40 - /* Allow 10 ms of drift so we don't chew on CPU */
13.41 - timerID =
13.42 - timeSetEvent(TIMER_RESOLUTION, 1, HandleAlarm, 0, TIME_PERIODIC);
13.43 - if (!timerID) {
13.44 - SDL_SetError("timeSetEvent() failed");
13.45 - return (-1);
13.46 - }
13.47 - return (SDL_SetTimerThreaded(1));
13.48 -}
13.49 -
13.50 -void
13.51 -SDL_SYS_TimerQuit(void)
13.52 -{
13.53 - if (timerID) {
13.54 - timeKillEvent(timerID);
13.55 - }
13.56 - timeEndPeriod(TIMER_RESOLUTION);
13.57 -}
13.58 -
13.59 -int
13.60 -SDL_SYS_StartTimer(void)
13.61 -{
13.62 - SDL_SetError("Internal logic error: Win32 uses threaded timer");
13.63 - return (-1);
13.64 -}
13.65 -
13.66 -void
13.67 -SDL_SYS_StopTimer(void)
13.68 -{
13.69 - return;
13.70 -}
13.71 -
13.72 #endif /* SDL_TIMER_WINDOWS */
13.73
13.74 /* vi: set ts=4 sw=4 expandtab: */