comparison src/timer/linux/SDL_systimer.c @ 316:d85fc19bf840

Added UNIX RDTSC code by Lompak (disabled by default)
author Sam Lantinga <slouken@libsdl.org>
date Sat, 23 Mar 2002 20:54:17 +0000
parents f6ffac90895c
children 4e8827521296
comparison
equal deleted inserted replaced
315:3333b6e68289 316:d85fc19bf840
16 License along with this library; if not, write to the Free 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 17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 18
19 Sam Lantinga 19 Sam Lantinga
20 slouken@libsdl.org 20 slouken@libsdl.org
21
22 RDTSC stuff by lompik (lompik@voila.fr) 20/03/2002
21 */ 23 */
22 24
23 #ifdef SAVE_RCSID 25 #ifdef SAVE_RCSID
24 static char rcsid = 26 static char rcsid =
25 "@(#) $Id$"; 27 "@(#) $Id$";
52 #define SELECT_SETS_REMAINING 54 #define SELECT_SETS_REMAINING
53 #elif defined(__bsdi__) || defined(__FreeBSD__) || defined(__sun) 55 #elif defined(__bsdi__) || defined(__FreeBSD__) || defined(__sun)
54 #define USE_NANOSLEEP 56 #define USE_NANOSLEEP
55 #endif 57 #endif
56 58
59 #if defined(i386) || defined(__i386__)
60 /* Actually, this isn't reliable on multi-cpu systems, so is disabled */
61 /*#define USE_RDTSC*/
62 #endif
63
64
65 #ifdef USE_RDTSC
66
67 /* The first ticks value of the application */
68 static unsigned long long start;
69 static float cpu_mhz1000 = 0.0f;
70
71 #if 1
72 /* This is for old binutils version that don't recognize rdtsc mnemonics.
73 But all binutils version supports this.
74 */
75 #define rdtsc(t) asm(".byte 0x0f, 0x31; " : "=A" (t));
76 #else
77 #define rdtsc(t) asm("rdtsc" : "=A" (t));
78 #endif
79
80 static float calc_cpu_mhz(void)
81 {
82 float cpu_mhz;
83 unsigned long long tsc_start;
84 unsigned long long tsc_end;
85 struct timeval tv_start, tv_end;
86 long usec_delay;
87
88 rdtsc(tsc_start);
89 gettimeofday(&tv_start, NULL);
90 sleep(1);
91 rdtsc(tsc_end);
92 gettimeofday(&tv_end, NULL);
93 usec_delay = 1000000L * (tv_end.tv_sec - tv_start.tv_sec) +
94 (tv_end.tv_usec - tv_start.tv_usec);
95 cpu_mhz = (float)(tsc_end-tsc_start) / usec_delay;
96 #if 0
97 printf("cpu MHz\t\t: %.3f\n", cpu_mhz);
98 #endif
99 return cpu_mhz;
100 }
101
102 #else
57 103
58 /* The first ticks value of the application */ 104 /* The first ticks value of the application */
59 static struct timeval start; 105 static struct timeval start;
60 106
107 #endif /* USE_RDTSC */
108
109
61 void SDL_StartTicks(void) 110 void SDL_StartTicks(void)
62 { 111 {
63 /* Set first ticks value */ 112 /* Set first ticks value */
113 #ifdef USE_RDTSC
114 if ( ! cpu_mhz1000 ) {
115 cpu_mhz1000 = calc_cpu_mhz() * 1000.0f;
116 }
117 rdtsc(start);
118 #else
64 gettimeofday(&start, NULL); 119 gettimeofday(&start, NULL);
120 #endif /* USE_RDTSC */
65 } 121 }
66 122
67 Uint32 SDL_GetTicks (void) 123 Uint32 SDL_GetTicks (void)
68 { 124 {
125 #ifdef USE_RDTSC
126 unsigned long long now;
127 if ( ! cpu_mhz1000 ) {
128 return 0; /* Shouldn't happen. BUG!! */
129 }
130 rdtsc(now);
131 return (Uint32)((now-start)/cpu_mhz1000);
132 #else
69 struct timeval now; 133 struct timeval now;
70 Uint32 ticks; 134 Uint32 ticks;
71 135
72 gettimeofday(&now, NULL); 136 gettimeofday(&now, NULL);
73 ticks=(now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000; 137 ticks=(now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000;
74 return(ticks); 138 return(ticks);
139 #endif /* USE_RDTSC */
75 } 140 }
76 141
77 void SDL_Delay (Uint32 ms) 142 void SDL_Delay (Uint32 ms)
78 { 143 {
79 int was_error; 144 int was_error;