Mercurial > sdl-ios-xcode
comparison src/timer/nds/SDL_systimer.c @ 5113:481dabb098ef
Improved timer implementation
The new timer model is formalized as using a separate thread to handle timer callbacks. This was the case on almost every platform before, but it's now a requirement, and simplifies the implementation and makes it perform consistently across platforms.
Goals:
* Minimize timer thread blocking
* Dispatch timers as accurately as possible
* SDL_AddTimer() and SDL_RemoveTimer() are completely threadsafe
* SDL_RemoveTimer() doesn't crash with a timer that's expired or removed
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Thu, 27 Jan 2011 14:45:06 -0800 |
parents | f7b03b6838cb |
children | b530ef003506 |
comparison
equal
deleted
inserted
replaced
5112:0846f18eb625 | 5113:481dabb098ef |
---|---|
25 | 25 |
26 #include <nds.h> | 26 #include <nds.h> |
27 #include <nds/timers.h> | 27 #include <nds/timers.h> |
28 | 28 |
29 #include "SDL_timer.h" | 29 #include "SDL_timer.h" |
30 #include "../SDL_timer_c.h" | |
31 #include "../SDL_systimer.h" | |
32 | 30 |
33 /* Data to handle a single periodic alarm */ | 31 |
34 static int timer_alive = 0; | 32 static volatile Uint32 timer_ticks; |
35 static Uint32 timer_ticks; | 33 |
34 static void | |
35 NDS_TimerInterrupt(void) | |
36 { | |
37 timer_ticks++; | |
38 } | |
36 | 39 |
37 void | 40 void |
38 SDL_StartTicks(void) | 41 SDL_StartTicks(void) |
39 { | 42 { |
40 if (!timer_alive) { | 43 timer_ticks = 0; |
41 SDL_SYS_TimerInit(); | |
42 SDL_SYS_StartTimer(); | |
43 } | |
44 | 44 |
45 timer_ticks = 0; | 45 TIMER_CR(3) = TIMER_DIV_1024 | TIMER_IRQ_REQ; |
46 TIMER_DATA(3) = TIMER_FREQ_1024(1000); | |
47 irqSet(IRQ_TIMER3, NDS_TimerInterrupt); | |
48 irqEnable(IRQ_TIMER3); | |
46 } | 49 } |
47 | 50 |
48 Uint32 | 51 Uint32 |
49 SDL_GetTicks(void) | 52 SDL_GetTicks(void) |
50 { | 53 { |
59 if ((SDL_GetTicks() - start) >= ms) | 62 if ((SDL_GetTicks() - start) >= ms) |
60 break; | 63 break; |
61 } | 64 } |
62 } | 65 } |
63 | 66 |
64 static int | 67 #endif /* SDL_TIMER_NDS */ |
65 RunTimer(void *unused) | |
66 { | |
67 while (timer_alive) { | |
68 if (SDL_timer_running) { | |
69 } | |
70 SDL_Delay(1); | |
71 } | |
72 return (0); | |
73 } | |
74 | 68 |
75 void | |
76 NDS_TimerInterrupt(void) | |
77 { | |
78 timer_ticks++; | |
79 } | |
80 | |
81 /* This is only called if the event thread is not running */ | |
82 int | |
83 SDL_SYS_TimerInit(void) | |
84 { | |
85 timer_alive = 1; | |
86 timer_ticks = 0; | |
87 TIMER_CR(3) = TIMER_DIV_1024 | TIMER_IRQ_REQ; | |
88 TIMER_DATA(3) = TIMER_FREQ_1024(1000); | |
89 irqSet(IRQ_TIMER3, NDS_TimerInterrupt); | |
90 irqEnable(IRQ_TIMER3); | |
91 return 0; | |
92 } | |
93 | |
94 void | |
95 SDL_SYS_TimerQuit(void) | |
96 { | |
97 if (timer_alive) { | |
98 TIMER_CR(3) = 0; | |
99 } | |
100 timer_alive = 0; | |
101 irqDisable(IRQ_TIMER3); | |
102 } | |
103 | |
104 int | |
105 SDL_SYS_StartTimer(void) | |
106 { | |
107 TIMER_CR(3) |= TIMER_ENABLE; | |
108 return 0; | |
109 } | |
110 | |
111 void | |
112 SDL_SYS_StopTimer(void) | |
113 { | |
114 TIMER_CR(3) &= ~TIMER_ENABLE; | |
115 return; | |
116 } | |
117 | |
118 | |
119 #endif /* SDL_TIMER_NDS */ | |
120 /* vi: set ts=4 sw=4 expandtab: */ | 69 /* vi: set ts=4 sw=4 expandtab: */ |