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 */