Mercurial > sdl-ios-xcode
comparison src/timer/os2/SDL_systimer.c @ 1668:4da1ee79c9af SDL-1.3
more tweaking indent options
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 29 May 2006 04:04:35 +0000 |
parents | 782fd950bd46 |
children |
comparison
equal
deleted
inserted
replaced
1667:1fddae038bc8 | 1668:4da1ee79c9af |
---|---|
43 static long long hires_start_ticks; | 43 static long long hires_start_ticks; |
44 /* The number of ticks per second of the high-resolution performance counter */ | 44 /* The number of ticks per second of the high-resolution performance counter */ |
45 static ULONG hires_ticks_per_second; | 45 static ULONG hires_ticks_per_second; |
46 | 46 |
47 void | 47 void |
48 SDL_StartTicks (void) | 48 SDL_StartTicks(void) |
49 { | 49 { |
50 DosTmrQueryFreq (&hires_ticks_per_second); | 50 DosTmrQueryFreq(&hires_ticks_per_second); |
51 DosTmrQueryTime ((PQWORD) & hires_start_ticks); | 51 DosTmrQueryTime((PQWORD) & hires_start_ticks); |
52 } | 52 } |
53 | 53 |
54 DECLSPEC Uint32 SDLCALL | 54 DECLSPEC Uint32 SDLCALL |
55 SDL_GetTicks (void) | 55 SDL_GetTicks(void) |
56 { | 56 { |
57 long long hires_now; | 57 long long hires_now; |
58 ULONG ticks = ticks; | 58 ULONG ticks = ticks; |
59 | 59 |
60 DosTmrQueryTime ((PQWORD) & hires_now); | 60 DosTmrQueryTime((PQWORD) & hires_now); |
61 /* | 61 /* |
62 hires_now -= hires_start_ticks; | 62 hires_now -= hires_start_ticks; |
63 hires_now *= 1000; | 63 hires_now *= 1000; |
64 hires_now /= hires_ticks_per_second; | 64 hires_now /= hires_ticks_per_second; |
65 */ | 65 */ |
88 | 88 |
89 } | 89 } |
90 | 90 |
91 /* High resolution sleep, originally made by Ilya Zakharevich */ | 91 /* High resolution sleep, originally made by Ilya Zakharevich */ |
92 DECLSPEC void SDLCALL | 92 DECLSPEC void SDLCALL |
93 SDL_Delay (Uint32 ms) | 93 SDL_Delay(Uint32 ms) |
94 { | 94 { |
95 /* This is similar to DosSleep(), but has 8ms granularity in time-critical | 95 /* This is similar to DosSleep(), but has 8ms granularity in time-critical |
96 threads even on Warp3. */ | 96 threads even on Warp3. */ |
97 HEV hevEvent1 = 0; /* Event semaphore handle */ | 97 HEV hevEvent1 = 0; /* Event semaphore handle */ |
98 HTIMER htimerEvent1 = 0; /* Timer handle */ | 98 HTIMER htimerEvent1 = 0; /* Timer handle */ |
103 PTIB tib; | 103 PTIB tib; |
104 char *e = NULL; | 104 char *e = NULL; |
105 APIRET badrc; | 105 APIRET badrc; |
106 int switch_priority = 50; | 106 int switch_priority = 50; |
107 | 107 |
108 DosCreateEventSem (NULL, /* Unnamed */ | 108 DosCreateEventSem(NULL, /* Unnamed */ |
109 &hevEvent1, /* Handle of semaphore returned */ | 109 &hevEvent1, /* Handle of semaphore returned */ |
110 DC_SEM_SHARED, /* Shared needed for DosAsyncTimer */ | 110 DC_SEM_SHARED, /* Shared needed for DosAsyncTimer */ |
111 FALSE); /* Semaphore is in RESET state */ | 111 FALSE); /* Semaphore is in RESET state */ |
112 | 112 |
113 if (ms >= switch_priority) | 113 if (ms >= switch_priority) |
114 switch_priority = 0; | 114 switch_priority = 0; |
115 if (switch_priority) { | 115 if (switch_priority) { |
116 if (DosGetInfoBlocks (&tib, &pib) != NO_ERROR) | 116 if (DosGetInfoBlocks(&tib, &pib) != NO_ERROR) |
117 switch_priority = 0; | 117 switch_priority = 0; |
118 else { | 118 else { |
119 /* In Warp3, to switch scheduling to 8ms step, one needs to do | 119 /* In Warp3, to switch scheduling to 8ms step, one needs to do |
120 DosAsyncTimer() in time-critical thread. On laters versions, | 120 DosAsyncTimer() in time-critical thread. On laters versions, |
121 more and more cases of wait-for-something are covered. | 121 more and more cases of wait-for-something are covered. |
129 switch_priority = 0; | 129 switch_priority = 0; |
130 /* Make us time-critical. Just modifying TIB is not enough... */ | 130 /* Make us time-critical. Just modifying TIB is not enough... */ |
131 /* tib->tib_ptib2->tib2_ulpri = 0x0300; */ | 131 /* tib->tib_ptib2->tib2_ulpri = 0x0300; */ |
132 /* We do not want to run at high priority if a signal causes us | 132 /* We do not want to run at high priority if a signal causes us |
133 to longjmp() out of this section... */ | 133 to longjmp() out of this section... */ |
134 if (DosEnterMustComplete (&nesting)) | 134 if (DosEnterMustComplete(&nesting)) |
135 switch_priority = 0; | 135 switch_priority = 0; |
136 else | 136 else |
137 DosSetPriority (PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0); | 137 DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0); |
138 } | 138 } |
139 } | 139 } |
140 | 140 |
141 if ((badrc = DosAsyncTimer (ms, (HSEM) hevEvent1, /* Semaphore to post */ | 141 if ((badrc = DosAsyncTimer(ms, (HSEM) hevEvent1, /* Semaphore to post */ |
142 &htimerEvent1))) /* Timer handler (returned) */ | 142 &htimerEvent1))) /* Timer handler (returned) */ |
143 e = "DosAsyncTimer"; | 143 e = "DosAsyncTimer"; |
144 | 144 |
145 if (switch_priority && tib->tib_ptib2->tib2_ulpri == 0x0300) { | 145 if (switch_priority && tib->tib_ptib2->tib2_ulpri == 0x0300) { |
146 /* Nobody switched priority while we slept... Ignore errors... */ | 146 /* Nobody switched priority while we slept... Ignore errors... */ |
147 /* tib->tib_ptib2->tib2_ulpri = priority; *//* Get back... */ | 147 /* tib->tib_ptib2->tib2_ulpri = priority; *//* Get back... */ |
148 if (! | 148 if (! |
149 (rc = | 149 (rc = DosSetPriority(PRTYS_THREAD, (priority >> 8) & 0xFF, 0, 0))) |
150 DosSetPriority (PRTYS_THREAD, (priority >> 8) & 0xFF, 0, 0))) | 150 rc = DosSetPriority(PRTYS_THREAD, 0, priority & 0xFF, 0); |
151 rc = DosSetPriority (PRTYS_THREAD, 0, priority & 0xFF, 0); | |
152 } | 151 } |
153 if (switch_priority) | 152 if (switch_priority) |
154 rc = DosExitMustComplete (&nesting); /* Ignore errors */ | 153 rc = DosExitMustComplete(&nesting); /* Ignore errors */ |
155 | 154 |
156 /* The actual blocking call is made with "normal" priority. This way we | 155 /* The actual blocking call is made with "normal" priority. This way we |
157 should not bother with DosSleep(0) etc. to compensate for us interrupting | 156 should not bother with DosSleep(0) etc. to compensate for us interrupting |
158 higher-priority threads. The goal is to prohibit the system spending too | 157 higher-priority threads. The goal is to prohibit the system spending too |
159 much time halt()ing, not to run us "no matter what". */ | 158 much time halt()ing, not to run us "no matter what". */ |
160 if (!e) /* Wait for AsyncTimer event */ | 159 if (!e) /* Wait for AsyncTimer event */ |
161 badrc = DosWaitEventSem (hevEvent1, SEM_INDEFINITE_WAIT); | 160 badrc = DosWaitEventSem(hevEvent1, SEM_INDEFINITE_WAIT); |
162 | 161 |
163 if (e); /* Do nothing */ | 162 if (e); /* Do nothing */ |
164 else if (badrc == ERROR_INTERRUPT) | 163 else if (badrc == ERROR_INTERRUPT) |
165 ret = 0; | 164 ret = 0; |
166 else if (badrc) | 165 else if (badrc) |
167 e = "DosWaitEventSem"; | 166 e = "DosWaitEventSem"; |
168 if ((rc = DosCloseEventSem (hevEvent1)) && !e) { /* Get rid of semaphore */ | 167 if ((rc = DosCloseEventSem(hevEvent1)) && !e) { /* Get rid of semaphore */ |
169 e = "DosCloseEventSem"; | 168 e = "DosCloseEventSem"; |
170 badrc = rc; | 169 badrc = rc; |
171 } | 170 } |
172 if (e) { | 171 if (e) { |
173 SDL_SetError ("[SDL_Delay] : Had error in %s(), rc is 0x%x\n", e, | 172 SDL_SetError("[SDL_Delay] : Had error in %s(), rc is 0x%x\n", e, |
174 badrc); | 173 badrc); |
175 } | 174 } |
176 } | 175 } |
177 | 176 |
178 /* Data to handle a single periodic alarm */ | 177 /* Data to handle a single periodic alarm */ |
179 static int timer_alive = 0; | 178 static int timer_alive = 0; |
180 static SDL_Thread *timer = NULL; | 179 static SDL_Thread *timer = NULL; |
181 | 180 |
182 static int | 181 static int |
183 RunTimer (void *unused) | 182 RunTimer(void *unused) |
184 { | 183 { |
185 DosSetPriority (PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0); | 184 DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0); |
186 while (timer_alive) { | 185 while (timer_alive) { |
187 if (SDL_timer_running) { | 186 if (SDL_timer_running) { |
188 SDL_ThreadedTimerCheck (); | 187 SDL_ThreadedTimerCheck(); |
189 } | 188 } |
190 SDL_Delay (10); | 189 SDL_Delay(10); |
191 } | 190 } |
192 return (0); | 191 return (0); |
193 } | 192 } |
194 | 193 |
195 /* This is only called if the event thread is not running */ | 194 /* This is only called if the event thread is not running */ |
196 int | 195 int |
197 SDL_SYS_TimerInit (void) | 196 SDL_SYS_TimerInit(void) |
198 { | 197 { |
199 timer_alive = 1; | 198 timer_alive = 1; |
200 timer = SDL_CreateThread (RunTimer, NULL); | 199 timer = SDL_CreateThread(RunTimer, NULL); |
201 if (timer == NULL) | 200 if (timer == NULL) |
202 return (-1); | 201 return (-1); |
203 return (SDL_SetTimerThreaded (1)); | 202 return (SDL_SetTimerThreaded(1)); |
204 } | 203 } |
205 | 204 |
206 void | 205 void |
207 SDL_SYS_TimerQuit (void) | 206 SDL_SYS_TimerQuit(void) |
208 { | 207 { |
209 timer_alive = 0; | 208 timer_alive = 0; |
210 if (timer) { | 209 if (timer) { |
211 SDL_WaitThread (timer, NULL); | 210 SDL_WaitThread(timer, NULL); |
212 timer = NULL; | 211 timer = NULL; |
213 } | 212 } |
214 } | 213 } |
215 | 214 |
216 int | 215 int |
217 SDL_SYS_StartTimer (void) | 216 SDL_SYS_StartTimer(void) |
218 { | 217 { |
219 SDL_SetError ("Internal logic error: OS/2 uses threaded timer"); | 218 SDL_SetError("Internal logic error: OS/2 uses threaded timer"); |
220 return (-1); | 219 return (-1); |
221 } | 220 } |
222 | 221 |
223 void | 222 void |
224 SDL_SYS_StopTimer (void) | 223 SDL_SYS_StopTimer(void) |
225 { | 224 { |
226 return; | 225 return; |
227 } | 226 } |
228 | 227 |
229 #endif /* SDL_TIMER_OS2 */ | 228 #endif /* SDL_TIMER_OS2 */ |