mirror of
https://bitbucket.org/cosmicvoids/vide_public.git
synced 2025-07-05 07:41:11 +00:00
91 lines
1.9 KiB
C
91 lines
1.9 KiB
C
#include <stdio.h>
|
|
#include <string.h>
|
|
#include "error.h"
|
|
#include "hwclock.h"
|
|
|
|
static double hwtick_val;
|
|
#define two_to_32 4294967296.0
|
|
|
|
static double hwclock_offset;
|
|
|
|
#if defined(__x86_64__) && defined(__GNUC__)
|
|
#define DEFAULT_MHZ 1200.e6
|
|
static double
|
|
mhz_from_proc(){
|
|
FILE *fp = fopen("/proc/cpuinfo", "r");
|
|
char line[512];
|
|
|
|
if( fp == NULL ){
|
|
Warning("Can't open /proc/cpuinfo\n");
|
|
return DEFAULT_MHZ;
|
|
}
|
|
|
|
while( fgets(line, sizeof(line), fp) ){
|
|
char *m;
|
|
int nscan;
|
|
double mhz;
|
|
|
|
if( (m = strstr(line, "cpu MHz")) ){
|
|
/* sscanf should match any amount of whitespace around the : */
|
|
nscan = sscanf(m, "cpu MHz : %lf\n", &mhz);
|
|
if( nscan == 1 ){
|
|
fclose(fp);
|
|
return mhz*1.0e6;
|
|
}else{
|
|
Warning("sscanf returns %d, on '%s' of /proc/cpuinfo mhz line failed\n", nscan, line);
|
|
fclose(fp);
|
|
return DEFAULT_MHZ; /* let's just guess 200Mhz */
|
|
}
|
|
}
|
|
}
|
|
Warning("Did not find cpu MHz in /proc/cpuinfo\n");
|
|
fclose(fp);
|
|
return DEFAULT_MHZ;
|
|
}
|
|
#endif
|
|
|
|
/* This doesn't belong here, but I can't be bothered to figure out where
|
|
it does belong! */
|
|
double
|
|
hwclock(void)
|
|
{
|
|
#if defined(__x86_64__)
|
|
static int init = 1;
|
|
unsigned int counter[2];
|
|
|
|
__asm__("rdtsc \n\t"
|
|
"movl %%eax,%0 \n\t"
|
|
"movl %%edx,%1 \n\t"
|
|
: "=m" (((unsigned *)counter)[0]), "=m" (((unsigned *)counter)[1])
|
|
:
|
|
: "eax" , "edx");
|
|
|
|
if (init) {
|
|
init = 0;
|
|
hwtick_val = 1.0/mhz_from_proc();
|
|
hwclock_offset = hwtick_val*((double)counter[1]*two_to_32 + (double)counter[0]);
|
|
return 0.0;
|
|
}
|
|
return(hwtick_val*((double)counter[1]*two_to_32 + (double)counter[0])-hwclock_offset);
|
|
#else
|
|
{
|
|
struct timeval tp;
|
|
struct timezone tzp;
|
|
|
|
gettimeofday(&tp,&tzp);
|
|
return ( (double) tp.tv_sec + (double) tp.tv_usec * 1.e-6 );
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void
|
|
zero_hwclock(void)
|
|
{
|
|
hwclock_offset += hwclock();
|
|
}
|
|
|
|
double
|
|
hwtick(void)
|
|
{
|
|
return hwtick_val;
|
|
}
|