Skip to content

Commit

Permalink
Added UNIX RDTSC code by Lompak (disabled by default)
Browse files Browse the repository at this point in the history
  • Loading branch information
slouken committed Mar 23, 2002
1 parent d65ffef commit a5b2506
Showing 1 changed file with 65 additions and 0 deletions.
65 changes: 65 additions & 0 deletions src/timer/linux/SDL_systimer.c
Expand Up @@ -18,6 +18,8 @@
Sam Lantinga
slouken@libsdl.org
RDTSC stuff by lompik (lompik@voila.fr) 20/03/2002
*/

#ifdef SAVE_RCSID
Expand Down Expand Up @@ -54,24 +56,87 @@ static char rcsid =
#define USE_NANOSLEEP
#endif

#if defined(i386) || defined(__i386__)
/* Actually, this isn't reliable on multi-cpu systems, so is disabled */
/*#define USE_RDTSC*/
#endif


#ifdef USE_RDTSC

/* The first ticks value of the application */
static unsigned long long start;
static float cpu_mhz1000 = 0.0f;

#if 1
/* This is for old binutils version that don't recognize rdtsc mnemonics.
But all binutils version supports this.
*/
#define rdtsc(t) asm(".byte 0x0f, 0x31; " : "=A" (t));
#else
#define rdtsc(t) asm("rdtsc" : "=A" (t));
#endif

static float calc_cpu_mhz(void)
{
float cpu_mhz;
unsigned long long tsc_start;
unsigned long long tsc_end;
struct timeval tv_start, tv_end;
long usec_delay;

rdtsc(tsc_start);
gettimeofday(&tv_start, NULL);
sleep(1);
rdtsc(tsc_end);
gettimeofday(&tv_end, NULL);
usec_delay = 1000000L * (tv_end.tv_sec - tv_start.tv_sec) +
(tv_end.tv_usec - tv_start.tv_usec);
cpu_mhz = (float)(tsc_end-tsc_start) / usec_delay;
#if 0
printf("cpu MHz\t\t: %.3f\n", cpu_mhz);
#endif
return cpu_mhz;
}

#else

/* The first ticks value of the application */
static struct timeval start;

#endif /* USE_RDTSC */


void SDL_StartTicks(void)
{
/* Set first ticks value */
#ifdef USE_RDTSC
if ( ! cpu_mhz1000 ) {
cpu_mhz1000 = calc_cpu_mhz() * 1000.0f;
}
rdtsc(start);
#else
gettimeofday(&start, NULL);
#endif /* USE_RDTSC */
}

Uint32 SDL_GetTicks (void)
{
#ifdef USE_RDTSC
unsigned long long now;
if ( ! cpu_mhz1000 ) {
return 0; /* Shouldn't happen. BUG!! */
}
rdtsc(now);
return (Uint32)((now-start)/cpu_mhz1000);
#else
struct timeval now;
Uint32 ticks;

gettimeofday(&now, NULL);
ticks=(now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000;
return(ticks);
#endif /* USE_RDTSC */
}

void SDL_Delay (Uint32 ms)
Expand Down

0 comments on commit a5b2506

Please sign in to comment.