src/timer/linux/SDL_systimer.c
changeset 316 d85fc19bf840
parent 297 f6ffac90895c
child 317 4e8827521296
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;