Mercurial > sdl-ios-xcode
annotate src/timer/linux/SDL_systimer.c @ 317:4e8827521296
*** empty log message ***
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 24 Mar 2002 01:12:57 +0000 |
parents | d85fc19bf840 |
children | 71fe0b713085 |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
297
f6ffac90895c
Updated copyright information for 2002
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
3 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga |
0 | 4 |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Library General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2 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 Library General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Library General Public | |
16 License along with this library; if not, write to the Free | |
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | |
19 Sam Lantinga | |
252
e8157fcb3114
Updated the source with the correct e-mail address
Sam Lantinga <slouken@libsdl.org>
parents:
166
diff
changeset
|
20 slouken@libsdl.org |
316
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
21 |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
22 RDTSC stuff by lompik (lompik@voila.fr) 20/03/2002 |
0 | 23 */ |
24 | |
25 #ifdef SAVE_RCSID | |
26 static char rcsid = | |
27 "@(#) $Id$"; | |
28 #endif | |
29 | |
30 #include <stdio.h> | |
31 #include <sys/time.h> | |
32 #include <signal.h> | |
33 #include <unistd.h> | |
34 #include <string.h> | |
35 #include <errno.h> | |
36 | |
37 #include "SDL_error.h" | |
38 #include "SDL_timer.h" | |
39 #include "SDL_timer_c.h" | |
40 | |
1
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
41 #if _POSIX_THREAD_SYSCALL_SOFT |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
42 #include <pthread.h> |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
43 #endif |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
44 |
0 | 45 #if defined(DISABLE_THREADS) || defined(FORK_HACK) |
46 #define USE_ITIMER | |
47 #endif | |
48 | |
49 /* The following defines should really be determined at configure time */ | |
50 | |
166
39877400bd1e
Fixed Solaris nitpicks (thanks Mattias!)
Sam Lantinga <slouken@libsdl.org>
parents:
1
diff
changeset
|
51 #if defined(linux) |
0 | 52 /* Linux select() changes its timeout parameter upon return to contain |
53 the remaining time. Most other unixen leave it unchanged or undefined. */ | |
54 #define SELECT_SETS_REMAINING | |
166
39877400bd1e
Fixed Solaris nitpicks (thanks Mattias!)
Sam Lantinga <slouken@libsdl.org>
parents:
1
diff
changeset
|
55 #elif defined(__bsdi__) || defined(__FreeBSD__) || defined(__sun) |
0 | 56 #define USE_NANOSLEEP |
57 #endif | |
58 | |
316
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
59 #if defined(i386) || defined(__i386__) |
317
4e8827521296
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
316
diff
changeset
|
60 /* This only works on pentium or newer x86 processors */ |
316
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
61 /* Actually, this isn't reliable on multi-cpu systems, so is disabled */ |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
62 /*#define USE_RDTSC*/ |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
63 #endif |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
64 |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
65 |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
66 #ifdef USE_RDTSC |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
67 |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
68 /* The first ticks value of the application */ |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
69 static unsigned long long start; |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
70 static float cpu_mhz1000 = 0.0f; |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
71 |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
72 #if 1 |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
73 /* This is for old binutils version that don't recognize rdtsc mnemonics. |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
74 But all binutils version supports this. |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
75 */ |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
76 #define rdtsc(t) asm(".byte 0x0f, 0x31; " : "=A" (t)); |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
77 #else |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
78 #define rdtsc(t) asm("rdtsc" : "=A" (t)); |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
79 #endif |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
80 |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
81 static float calc_cpu_mhz(void) |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
82 { |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
83 float cpu_mhz; |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
84 unsigned long long tsc_start; |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
85 unsigned long long tsc_end; |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
86 struct timeval tv_start, tv_end; |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
87 long usec_delay; |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
88 |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
89 rdtsc(tsc_start); |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
90 gettimeofday(&tv_start, NULL); |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
91 sleep(1); |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
92 rdtsc(tsc_end); |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
93 gettimeofday(&tv_end, NULL); |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
94 usec_delay = 1000000L * (tv_end.tv_sec - tv_start.tv_sec) + |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
95 (tv_end.tv_usec - tv_start.tv_usec); |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
96 cpu_mhz = (float)(tsc_end-tsc_start) / usec_delay; |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
97 #if 0 |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
98 printf("cpu MHz\t\t: %.3f\n", cpu_mhz); |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
99 #endif |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
100 return cpu_mhz; |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
101 } |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
102 |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
103 #else |
0 | 104 |
105 /* The first ticks value of the application */ | |
106 static struct timeval start; | |
107 | |
316
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
108 #endif /* USE_RDTSC */ |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
109 |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
110 |
0 | 111 void SDL_StartTicks(void) |
112 { | |
113 /* Set first ticks value */ | |
316
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
114 #ifdef USE_RDTSC |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
115 if ( ! cpu_mhz1000 ) { |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
116 cpu_mhz1000 = calc_cpu_mhz() * 1000.0f; |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
117 } |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
118 rdtsc(start); |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
119 #else |
0 | 120 gettimeofday(&start, NULL); |
316
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
121 #endif /* USE_RDTSC */ |
0 | 122 } |
123 | |
124 Uint32 SDL_GetTicks (void) | |
125 { | |
316
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
126 #ifdef USE_RDTSC |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
127 unsigned long long now; |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
128 if ( ! cpu_mhz1000 ) { |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
129 return 0; /* Shouldn't happen. BUG!! */ |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
130 } |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
131 rdtsc(now); |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
132 return (Uint32)((now-start)/cpu_mhz1000); |
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
133 #else |
0 | 134 struct timeval now; |
135 Uint32 ticks; | |
136 | |
137 gettimeofday(&now, NULL); | |
138 ticks=(now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000; | |
139 return(ticks); | |
316
d85fc19bf840
Added UNIX RDTSC code by Lompak (disabled by default)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
140 #endif /* USE_RDTSC */ |
0 | 141 } |
142 | |
143 void SDL_Delay (Uint32 ms) | |
144 { | |
145 int was_error; | |
146 | |
147 #ifdef USE_NANOSLEEP | |
148 struct timespec elapsed, tv; | |
149 #else | |
150 struct timeval tv; | |
151 #ifndef SELECT_SETS_REMAINING | |
152 Uint32 then, now, elapsed; | |
153 #endif | |
154 #endif | |
155 | |
156 /* Set the timeout interval - Linux only needs to do this once */ | |
157 #ifdef SELECT_SETS_REMAINING | |
158 tv.tv_sec = ms/1000; | |
159 tv.tv_usec = (ms%1000)*1000; | |
160 #elif defined(USE_NANOSLEEP) | |
161 elapsed.tv_sec = ms/1000; | |
162 elapsed.tv_nsec = (ms%1000)*1000000; | |
163 #else | |
164 then = SDL_GetTicks(); | |
165 #endif | |
166 do { | |
167 errno = 0; | |
168 | |
1
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
169 #if _POSIX_THREAD_SYSCALL_SOFT |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
170 pthread_yield_np(); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
171 #endif |
0 | 172 #ifdef USE_NANOSLEEP |
173 tv.tv_sec = elapsed.tv_sec; | |
174 tv.tv_nsec = elapsed.tv_nsec; | |
175 was_error = nanosleep(&tv, &elapsed); | |
176 #else | |
177 #ifndef SELECT_SETS_REMAINING | |
178 /* Calculate the time interval left (in case of interrupt) */ | |
179 now = SDL_GetTicks(); | |
180 elapsed = (now-then); | |
181 then = now; | |
182 if ( elapsed >= ms ) { | |
183 break; | |
184 } | |
185 ms -= elapsed; | |
186 tv.tv_sec = ms/1000; | |
187 tv.tv_usec = (ms%1000)*1000; | |
188 #endif | |
189 was_error = select(0, NULL, NULL, NULL, &tv); | |
190 #endif /* USE_NANOSLEEP */ | |
191 } while ( was_error && (errno == EINTR) ); | |
192 } | |
193 | |
194 #ifdef USE_ITIMER | |
195 | |
196 static void HandleAlarm(int sig) | |
197 { | |
198 Uint32 ms; | |
199 | |
200 if ( SDL_alarm_callback ) { | |
201 ms = (*SDL_alarm_callback)(SDL_alarm_interval); | |
202 if ( ms != SDL_alarm_interval ) { | |
203 SDL_SetTimer(ms, SDL_alarm_callback); | |
204 } | |
205 } | |
206 } | |
207 | |
208 int SDL_SYS_TimerInit(void) | |
209 { | |
210 struct sigaction action; | |
211 | |
212 /* Set the alarm handler (Linux specific) */ | |
213 memset(&action, 0, sizeof(action)); | |
214 action.sa_handler = HandleAlarm; | |
215 action.sa_flags = SA_RESTART; | |
216 sigemptyset(&action.sa_mask); | |
217 sigaction(SIGALRM, &action, NULL); | |
218 return(0); | |
219 } | |
220 | |
221 void SDL_SYS_TimerQuit(void) | |
222 { | |
223 SDL_SetTimer(0, NULL); | |
224 } | |
225 | |
226 int SDL_SYS_StartTimer(void) | |
227 { | |
228 struct itimerval timer; | |
229 | |
230 timer.it_value.tv_sec = (SDL_alarm_interval/1000); | |
231 timer.it_value.tv_usec = (SDL_alarm_interval%1000)*1000; | |
232 timer.it_interval.tv_sec = (SDL_alarm_interval/1000); | |
233 timer.it_interval.tv_usec = (SDL_alarm_interval%1000)*1000; | |
234 setitimer(ITIMER_REAL, &timer, NULL); | |
235 return(0); | |
236 } | |
237 | |
238 void SDL_SYS_StopTimer(void) | |
239 { | |
240 struct itimerval timer; | |
241 | |
242 memset(&timer, 0, (sizeof timer)); | |
243 setitimer(ITIMER_REAL, &timer, NULL); | |
244 } | |
245 | |
246 #else /* USE_ITIMER */ | |
247 | |
248 #include "SDL_thread.h" | |
249 | |
250 /* Data to handle a single periodic alarm */ | |
251 static int timer_alive = 0; | |
252 static SDL_Thread *timer = NULL; | |
253 | |
254 static int RunTimer(void *unused) | |
255 { | |
256 while ( timer_alive ) { | |
257 if ( SDL_timer_running ) { | |
258 SDL_ThreadedTimerCheck(); | |
259 } | |
260 SDL_Delay(1); | |
261 } | |
262 return(0); | |
263 } | |
264 | |
265 /* This is only called if the event thread is not running */ | |
266 int SDL_SYS_TimerInit(void) | |
267 { | |
268 timer_alive = 1; | |
269 timer = SDL_CreateThread(RunTimer, NULL); | |
270 if ( timer == NULL ) | |
271 return(-1); | |
272 return(SDL_SetTimerThreaded(1)); | |
273 } | |
274 | |
275 void SDL_SYS_TimerQuit(void) | |
276 { | |
277 timer_alive = 0; | |
278 if ( timer ) { | |
279 SDL_WaitThread(timer, NULL); | |
280 timer = NULL; | |
281 } | |
282 } | |
283 | |
284 int SDL_SYS_StartTimer(void) | |
285 { | |
286 SDL_SetError("Internal logic error: Linux uses threaded timer"); | |
287 return(-1); | |
288 } | |
289 | |
290 void SDL_SYS_StopTimer(void) | |
291 { | |
292 return; | |
293 } | |
294 | |
295 #endif /* USE_ITIMER */ |