powerpcaix.c | powerpccpuinfo.c | |||
---|---|---|---|---|
#include <time.h> | #include <time.h> | |||
#include <stdio.h> | #include <stdio.h> | |||
#include <unistd.h> | #include <unistd.h> | |||
#include <sys/time.h> | #include <sys/time.h> | |||
#include <sys/types.h> | #include <sys/types.h> | |||
#include "osfreq.c" | ||||
static long myround(double u) | static long myround(double u) | |||
{ | { | |||
long result = u; | long result = u; | |||
while (result + 0.5 < u) result += 1; | while (result + 0.5 < u) result += 1; | |||
while (result - 0.5 > u) result -= 1; | while (result - 0.5 > u) result -= 1; | |||
return result; | return result; | |||
} | } | |||
static long long microseconds(void) | static long long microseconds(void) | |||
{ | { | |||
struct timeval t; | struct timeval t; | |||
gettimeofday(&t,(struct timezone *) 0); | gettimeofday(&t,(struct timezone *) 0); | |||
return t.tv_sec * (long long) 1000000 + t.tv_usec; | return t.tv_sec * (long long) 1000000 + t.tv_usec; | |||
} | } | |||
static int tbshift = 0; | ||||
static long long timebase(void) | static long long timebase(void) | |||
{ | { | |||
unsigned long high; | unsigned long high; | |||
unsigned long low; | unsigned long low; | |||
unsigned long newhigh; | unsigned long newhigh; | |||
unsigned long long result; | unsigned long long result; | |||
asm volatile( | asm volatile( | |||
"7:mftbu %0;mftb %1;mftbu %2;cmpw %0,%2;bne 7b" | "7:mftbu %0;mftb %1;mftbu %2;cmpw %0,%2;bne 7b" | |||
: "=r" (high), "=r" (low), "=r" (newhigh) | : "=r" (high), "=r" (low), "=r" (newhigh) | |||
); | ); | |||
result = high; | result = high; | |||
result <<= 32; | result <<= 32; | |||
result |= low; | result |= low; | |||
return result; | return result >> tbshift; | |||
} | } | |||
static double cpufrequency = 0; | static double cpufrequency = 0; | |||
static long tbcycles = 0; | static long tbcycles = 0; | |||
static double guesstbcycles(void) | static double guesstbcycles(void) | |||
{ | { | |||
long long tb0; long long us0; | long long tb0; long long us0; | |||
long long tb1; long long us1; | long long tb1; long long us1; | |||
skipping to change at line 60 | skipping to change at line 63 | |||
us1 = microseconds(); | us1 = microseconds(); | |||
} while (us1 - us0 < 10000 || tb1 - tb0 < 1000); | } while (us1 - us0 < 10000 || tb1 - tb0 < 1000); | |||
if (tb1 <= tb0) return 0; | if (tb1 <= tb0) return 0; | |||
tb1 -= tb0; | tb1 -= tb0; | |||
us1 -= us0; | us1 -= us0; | |||
return (cpufrequency * 0.000001 * (double) us1) / (double) tb1; | return (cpufrequency * 0.000001 * (double) us1) / (double) tb1; | |||
} | } | |||
static void init(void) | static void init(void) | |||
{ | { | |||
FILE *f; | ||||
int loop; | int loop; | |||
double guess1; | double guess1; | |||
double guess2; | double guess2; | |||
f = popen("/usr/sbin/lsattr -E -l proc0 -a frequency","r"); | cpufrequency = osfreq(); | |||
if (!f) return; | ||||
if (fscanf(f,"frequency %lf",&cpufrequency) < 1) cpufrequency = 0; | ||||
pclose(f); | ||||
if (!cpufrequency) return; | if (!cpufrequency) return; | |||
for (loop = 0;loop < 100;++loop) { | for (tbshift = 0;tbshift < 10;++tbshift) { | |||
guess1 = guesstbcycles(); | for (loop = 0;loop < 100;++loop) { | |||
guess2 = guesstbcycles(); | guess1 = guesstbcycles(); | |||
tbcycles = myround(guess1); | guess2 = guesstbcycles(); | |||
if (guess1 - tbcycles > 0.1) continue; | tbcycles = myround(guess1); | |||
if (tbcycles - guess1 > 0.1) continue; | if (guess1 - tbcycles > 0.1) continue; | |||
if (guess2 - tbcycles > 0.1) continue; | if (tbcycles - guess1 > 0.1) continue; | |||
if (tbcycles - guess2 > 0.1) continue; | if (guess2 - tbcycles > 0.1) continue; | |||
return; | if (tbcycles - guess2 > 0.1) continue; | |||
return; | ||||
} | ||||
} | } | |||
tbcycles = 0; | tbcycles = 0; | |||
} | } | |||
long long cpucycles_powerpcaix(void) | long long cpucycles_powerpccpuinfo(void) | |||
{ | { | |||
if (!tbcycles) init(); | if (!tbcycles) init(); | |||
return timebase() * tbcycles; | return timebase() * tbcycles; | |||
} | } | |||
long long cpucycles_powerpcaix_persecond(void) | long long cpucycles_powerpccpuinfo_persecond(void) | |||
{ | { | |||
if (!tbcycles) init(); | if (!tbcycles) init(); | |||
return cpufrequency; | return cpufrequency; | |||
} | } | |||
End of changes. 8 change blocks. | ||||
17 lines changed or deleted | 18 lines changed or added | |||
This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |