Mercurial > sdl-ios-xcode
comparison src/timer/linux/SDL_systimer.c @ 1157:baf35853ad54
Date: Mon, 10 Oct 2005 13:09:32 +0300
From: Tommi Kyntola <tommi.kyntola@ray.fi>
To: sdl@libsdl.org
Subject: [SDL] [RFC] get_ticks broken on linux
It uses gettimeofday to calculate the timedifference.
Gettimeofday returns current time which is seldom monotonous.
This breaks SDL timer subsystem. (time callbacks and all that
get borked when the time difference ms is suddenly ~ 2^32)
I posted a message about this earlier but got no response.
Some thoughts on this matter would be appreciated.
(Or even an explanation for the lack of interest.)
A patch below would use the posix timers that have been around
since posix 93 and do provide a good source of monotonous time
on linux boxes (and on few others too).
The following patch is also availabe at:
http://www.hut.fi/u/tkyntola/SDL-1.2.9-clockfix.patch
It's against 1.2.9, but I can easily rediffit against
the cvs branch is needed.
cheers,
Tommi Kyntola tommi.kyntola@ray.fi
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Tue, 11 Oct 2005 18:16:12 +0000 |
parents | 8521404a33c7 |
children | ec446adf8cb2 |
comparison
equal
deleted
inserted
replaced
1156:8521404a33c7 | 1157:baf35853ad54 |
---|---|
32 #include <signal.h> | 32 #include <signal.h> |
33 #include <unistd.h> | 33 #include <unistd.h> |
34 #include <string.h> | 34 #include <string.h> |
35 #include <errno.h> | 35 #include <errno.h> |
36 | 36 |
37 /* The clock_gettime provides monotonous time, so we should use it if | |
38 it's available. The clock_gettime function is behind ifdef | |
39 for __USE_POSIX199309 | |
40 Tommi Kyntola (tommi.kyntola@ray.fi) 27/09/2005 | |
41 */ | |
42 #if (defined _POSIX_TIMERS && _POSIX_TIMERS > 0) | |
43 #include <time.h> | |
44 #define USE_CLOCK_GETTIME | |
45 #endif | |
46 | |
37 #include "SDL_error.h" | 47 #include "SDL_error.h" |
38 #include "SDL_timer.h" | 48 #include "SDL_timer.h" |
39 #include "SDL_timer_c.h" | 49 #include "SDL_timer_c.h" |
40 | 50 |
41 #if _POSIX_THREAD_SYSCALL_SOFT | 51 #if _POSIX_THREAD_SYSCALL_SOFT |
84 static float calc_cpu_mhz(void) | 94 static float calc_cpu_mhz(void) |
85 { | 95 { |
86 float cpu_mhz; | 96 float cpu_mhz; |
87 unsigned long long tsc_start; | 97 unsigned long long tsc_start; |
88 unsigned long long tsc_end; | 98 unsigned long long tsc_end; |
99 /* Slight code doubling here for the sake of readability */ | |
100 #ifdef USE_CLOCK_GETTIME | |
101 struct timespec tv_start, tv_end; | |
102 long usec_delay; | |
103 | |
104 rdtsc(tsc_start); | |
105 clock_gettime(CLOCK_MONOTONIC,&tv_start); | |
106 sleep(1); | |
107 rdtsc(tsc_end); | |
108 clock_gettime(CLOCK_MONOTONIC,&tv_end); | |
109 usec_delay = (1000000000L * (tv_end.tv_sec - tv_start.tv_sec) + | |
110 (tv_end.tv_nsec - tv_start.tv_nsec)) / 1000; | |
111 #else | |
89 struct timeval tv_start, tv_end; | 112 struct timeval tv_start, tv_end; |
90 long usec_delay; | 113 long usec_delay; |
91 | 114 |
92 rdtsc(tsc_start); | 115 rdtsc(tsc_start); |
93 gettimeofday(&tv_start, NULL); | 116 gettimeofday(&tv_start, NULL); |
94 sleep(1); | 117 sleep(1); |
95 rdtsc(tsc_end); | 118 rdtsc(tsc_end); |
96 gettimeofday(&tv_end, NULL); | 119 gettimeofday(&tv_end, NULL); |
97 usec_delay = 1000000L * (tv_end.tv_sec - tv_start.tv_sec) + | 120 usec_delay = 1000000L * (tv_end.tv_sec - tv_start.tv_sec) + |
98 (tv_end.tv_usec - tv_start.tv_usec); | 121 (tv_end.tv_usec - tv_start.tv_usec); |
122 #endif /* USE_CLOCK_GETTIME */ | |
99 cpu_mhz = (float)(tsc_end-tsc_start) / usec_delay; | 123 cpu_mhz = (float)(tsc_end-tsc_start) / usec_delay; |
100 #if 0 | 124 #if 0 |
101 printf("cpu MHz\t\t: %.3f\n", cpu_mhz); | 125 printf("cpu MHz\t\t: %.3f\n", cpu_mhz); |
102 #endif | 126 #endif |
103 return cpu_mhz; | 127 return cpu_mhz; |
104 } | 128 } |
105 | 129 |
106 #else | 130 #else |
107 | 131 |
108 /* The first ticks value of the application */ | 132 /* The first ticks value of the application */ |
133 #ifdef USE_CLOCK_GETTIME | |
134 static struct timespec start; | |
135 #else | |
109 static struct timeval start; | 136 static struct timeval start; |
137 #endif /* USE_CLOCK_GETTIME */ | |
110 | 138 |
111 #endif /* USE_RDTSC */ | 139 #endif /* USE_RDTSC */ |
112 | 140 |
113 | 141 |
114 void SDL_StartTicks(void) | 142 void SDL_StartTicks(void) |
117 #ifdef USE_RDTSC | 145 #ifdef USE_RDTSC |
118 if ( ! cpu_mhz1000 ) { | 146 if ( ! cpu_mhz1000 ) { |
119 cpu_mhz1000 = calc_cpu_mhz() * 1000.0f; | 147 cpu_mhz1000 = calc_cpu_mhz() * 1000.0f; |
120 } | 148 } |
121 rdtsc(start); | 149 rdtsc(start); |
150 #elif defined(USE_CLOCK_GETTIME) | |
151 clock_gettime(CLOCK_MONOTONIC,&start); | |
122 #else | 152 #else |
123 gettimeofday(&start, NULL); | 153 gettimeofday(&start, NULL); |
124 #endif /* USE_RDTSC */ | 154 #endif |
125 } | 155 } |
126 | 156 |
127 Uint32 SDL_GetTicks (void) | 157 Uint32 SDL_GetTicks (void) |
128 { | 158 { |
129 #ifdef USE_RDTSC | 159 #ifdef USE_RDTSC |
131 if ( ! cpu_mhz1000 ) { | 161 if ( ! cpu_mhz1000 ) { |
132 return 0; /* Shouldn't happen. BUG!! */ | 162 return 0; /* Shouldn't happen. BUG!! */ |
133 } | 163 } |
134 rdtsc(now); | 164 rdtsc(now); |
135 return (Uint32)((now-start)/cpu_mhz1000); | 165 return (Uint32)((now-start)/cpu_mhz1000); |
136 #else | 166 #elif defined(USE_CLOCK_GETTIME) |
167 Uint32 ticks; | |
168 struct timespec now; | |
169 clock_gettime(CLOCK_MONOTONIC,&now); | |
170 ticks=(now.tv_sec-start.tv_sec)*1000+(now.tv_nsec-start.tv_nsec)/1000000; | |
171 return(ticks); | |
172 #else | |
173 Uint32 ticks; | |
137 struct timeval now; | 174 struct timeval now; |
138 Uint32 ticks; | |
139 | |
140 gettimeofday(&now, NULL); | 175 gettimeofday(&now, NULL); |
141 ticks=(now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000; | 176 ticks=(now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000; |
142 return(ticks); | 177 return(ticks); |
143 #endif /* USE_RDTSC */ | 178 #endif |
144 } | 179 } |
145 | 180 |
146 void SDL_Delay (Uint32 ms) | 181 void SDL_Delay (Uint32 ms) |
147 { | 182 { |
148 #ifdef ENABLE_PTH | 183 #ifdef ENABLE_PTH |