diff options
Diffstat (limited to 'apps/plugins/sdl/src/timer/os2/SDL_systimer.c')
-rw-r--r-- | apps/plugins/sdl/src/timer/os2/SDL_systimer.c | 227 |
1 files changed, 0 insertions, 227 deletions
diff --git a/apps/plugins/sdl/src/timer/os2/SDL_systimer.c b/apps/plugins/sdl/src/timer/os2/SDL_systimer.c deleted file mode 100644 index c82d53146d..0000000000 --- a/apps/plugins/sdl/src/timer/os2/SDL_systimer.c +++ /dev/null | |||
@@ -1,227 +0,0 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifdef SDL_TIMER_OS2 | ||
25 | |||
26 | #define INCL_DOSMISC | ||
27 | #define INCL_DOSERRORS | ||
28 | #define INCL_DOSSEMAPHORES | ||
29 | #define INCL_DOSDATETIME | ||
30 | #define INCL_DOSPROCESS | ||
31 | #define INCL_DOSPROFILE | ||
32 | #define INCL_DOSEXCEPTIONS | ||
33 | #include <os2.h> | ||
34 | |||
35 | #include "SDL_thread.h" | ||
36 | #include "SDL_timer.h" | ||
37 | #include "../SDL_timer_c.h" | ||
38 | |||
39 | |||
40 | #define TIME_WRAP_VALUE (~(DWORD)0) | ||
41 | |||
42 | /* The first high-resolution ticks value of the application */ | ||
43 | static long long hires_start_ticks; | ||
44 | /* The number of ticks per second of the high-resolution performance counter */ | ||
45 | static ULONG hires_ticks_per_second; | ||
46 | |||
47 | void SDL_StartTicks(void) | ||
48 | { | ||
49 | DosTmrQueryFreq(&hires_ticks_per_second); | ||
50 | DosTmrQueryTime((PQWORD)&hires_start_ticks); | ||
51 | } | ||
52 | |||
53 | DECLSPEC Uint32 SDLCALL SDL_GetTicks(void) | ||
54 | { | ||
55 | long long hires_now; | ||
56 | ULONG ticks = ticks; | ||
57 | |||
58 | DosTmrQueryTime((PQWORD)&hires_now); | ||
59 | /* | ||
60 | hires_now -= hires_start_ticks; | ||
61 | hires_now *= 1000; | ||
62 | hires_now /= hires_ticks_per_second; | ||
63 | */ | ||
64 | /* inline asm to avoid runtime inclusion */ | ||
65 | _asm { | ||
66 | push edx | ||
67 | push eax | ||
68 | mov eax, dword ptr hires_now | ||
69 | mov edx, dword ptr hires_now+4 | ||
70 | sub eax, dword ptr hires_start_ticks | ||
71 | sbb edx, dword ptr hires_start_ticks+4 | ||
72 | mov ebx,1000 | ||
73 | mov ecx,edx | ||
74 | mul ebx | ||
75 | push eax | ||
76 | push edx | ||
77 | mov eax,ecx | ||
78 | mul ebx | ||
79 | pop eax | ||
80 | add edx,eax | ||
81 | pop eax | ||
82 | mov ebx, dword ptr hires_ticks_per_second | ||
83 | div ebx | ||
84 | mov dword ptr ticks, eax | ||
85 | pop edx | ||
86 | pop eax | ||
87 | } | ||
88 | |||
89 | return ticks; | ||
90 | |||
91 | } | ||
92 | |||
93 | /* High resolution sleep, originally made by Ilya Zakharevich */ | ||
94 | DECLSPEC void SDLCALL SDL_Delay(Uint32 ms) | ||
95 | { | ||
96 | /* This is similar to DosSleep(), but has 8ms granularity in time-critical | ||
97 | threads even on Warp3. */ | ||
98 | HEV hevEvent1 = 0; /* Event semaphore handle */ | ||
99 | HTIMER htimerEvent1 = 0; /* Timer handle */ | ||
100 | APIRET rc = NO_ERROR; /* Return code */ | ||
101 | int ret = 1; | ||
102 | ULONG priority = 0, nesting; /* Shut down the warnings */ | ||
103 | PPIB pib; | ||
104 | PTIB tib; | ||
105 | char *e = NULL; | ||
106 | APIRET badrc; | ||
107 | int switch_priority = 50; | ||
108 | |||
109 | DosCreateEventSem(NULL, /* Unnamed */ | ||
110 | &hevEvent1, /* Handle of semaphore returned */ | ||
111 | DC_SEM_SHARED, /* Shared needed for DosAsyncTimer */ | ||
112 | FALSE); /* Semaphore is in RESET state */ | ||
113 | |||
114 | if (ms >= switch_priority) | ||
115 | switch_priority = 0; | ||
116 | if (switch_priority) | ||
117 | { | ||
118 | if (DosGetInfoBlocks(&tib, &pib)!=NO_ERROR) | ||
119 | switch_priority = 0; | ||
120 | else | ||
121 | { | ||
122 | /* In Warp3, to switch scheduling to 8ms step, one needs to do | ||
123 | DosAsyncTimer() in time-critical thread. On laters versions, | ||
124 | more and more cases of wait-for-something are covered. | ||
125 | |||
126 | It turns out that on Warp3fp42 it is the priority at the time | ||
127 | of DosAsyncTimer() which matters. Let's hope that this works | ||
128 | with later versions too... XXXX | ||
129 | */ | ||
130 | priority = (tib->tib_ptib2->tib2_ulpri); | ||
131 | if ((priority & 0xFF00) == 0x0300) /* already time-critical */ | ||
132 | switch_priority = 0; | ||
133 | /* Make us time-critical. Just modifying TIB is not enough... */ | ||
134 | /* tib->tib_ptib2->tib2_ulpri = 0x0300;*/ | ||
135 | /* We do not want to run at high priority if a signal causes us | ||
136 | to longjmp() out of this section... */ | ||
137 | if (DosEnterMustComplete(&nesting)) | ||
138 | switch_priority = 0; | ||
139 | else | ||
140 | DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0); | ||
141 | } | ||
142 | } | ||
143 | |||
144 | if ((badrc = DosAsyncTimer(ms, | ||
145 | (HSEM) hevEvent1, /* Semaphore to post */ | ||
146 | &htimerEvent1))) /* Timer handler (returned) */ | ||
147 | e = "DosAsyncTimer"; | ||
148 | |||
149 | if (switch_priority && tib->tib_ptib2->tib2_ulpri == 0x0300) | ||
150 | { | ||
151 | /* Nobody switched priority while we slept... Ignore errors... */ | ||
152 | /* tib->tib_ptib2->tib2_ulpri = priority; */ /* Get back... */ | ||
153 | if (!(rc = DosSetPriority(PRTYS_THREAD, (priority>>8) & 0xFF, 0, 0))) | ||
154 | rc = DosSetPriority(PRTYS_THREAD, 0, priority & 0xFF, 0); | ||
155 | } | ||
156 | if (switch_priority) | ||
157 | rc = DosExitMustComplete(&nesting); /* Ignore errors */ | ||
158 | |||
159 | /* The actual blocking call is made with "normal" priority. This way we | ||
160 | should not bother with DosSleep(0) etc. to compensate for us interrupting | ||
161 | higher-priority threads. The goal is to prohibit the system spending too | ||
162 | much time halt()ing, not to run us "no matter what". */ | ||
163 | if (!e) /* Wait for AsyncTimer event */ | ||
164 | badrc = DosWaitEventSem(hevEvent1, SEM_INDEFINITE_WAIT); | ||
165 | |||
166 | if (e) ; /* Do nothing */ | ||
167 | else if (badrc == ERROR_INTERRUPT) | ||
168 | ret = 0; | ||
169 | else if (badrc) | ||
170 | e = "DosWaitEventSem"; | ||
171 | if ((rc = DosCloseEventSem(hevEvent1)) && !e) { /* Get rid of semaphore */ | ||
172 | e = "DosCloseEventSem"; | ||
173 | badrc = rc; | ||
174 | } | ||
175 | if (e) | ||
176 | { | ||
177 | SDL_SetError("[SDL_Delay] : Had error in %s(), rc is 0x%x\n", e, badrc); | ||
178 | } | ||
179 | } | ||
180 | |||
181 | /* Data to handle a single periodic alarm */ | ||
182 | static int timer_alive = 0; | ||
183 | static SDL_Thread *timer = NULL; | ||
184 | |||
185 | static int SDLCALL RunTimer(void *unused) | ||
186 | { | ||
187 | DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0); | ||
188 | while ( timer_alive ) { | ||
189 | if ( SDL_timer_running ) { | ||
190 | SDL_ThreadedTimerCheck(); | ||
191 | } | ||
192 | SDL_Delay(10); | ||
193 | } | ||
194 | return(0); | ||
195 | } | ||
196 | |||
197 | /* This is only called if the event thread is not running */ | ||
198 | int SDL_SYS_TimerInit(void) | ||
199 | { | ||
200 | timer_alive = 1; | ||
201 | timer = SDL_CreateThread(RunTimer, NULL); | ||
202 | if ( timer == NULL ) | ||
203 | return(-1); | ||
204 | return(SDL_SetTimerThreaded(1)); | ||
205 | } | ||
206 | |||
207 | void SDL_SYS_TimerQuit(void) | ||
208 | { | ||
209 | timer_alive = 0; | ||
210 | if ( timer ) { | ||
211 | SDL_WaitThread(timer, NULL); | ||
212 | timer = NULL; | ||
213 | } | ||
214 | } | ||
215 | |||
216 | int SDL_SYS_StartTimer(void) | ||
217 | { | ||
218 | SDL_SetError("Internal logic error: OS/2 uses threaded timer"); | ||
219 | return(-1); | ||
220 | } | ||
221 | |||
222 | void SDL_SYS_StopTimer(void) | ||
223 | { | ||
224 | return; | ||
225 | } | ||
226 | |||
227 | #endif /* SDL_TIMER_OS2 */ | ||