diff options
author | Dave Jones <davej@redhat.com> | 2008-07-02 12:20:43 -0400 |
---|---|---|
committer | Dave Jones <davej@redhat.com> | 2008-07-02 12:20:43 -0400 |
commit | 0a201b3dfb8fe7bca0c4ee9e6299693625dd30c7 (patch) | |
tree | 2e7bfc0eacd8b8e4a127c851ae8a9da263caa734 /bench | |
parent | c24284a637a67694f3788d585862a7928cc6ed73 (diff) |
The estimate MHz routine is utterly busted.
At the least it should be binding to a CPU.
Also, the usleep doesn't make the CPU busy, so replace it with a loop
and wake up on an alarm after 3 seconds.
It's still wildly inaccurate. Not sure what to do yet, but this
is no more broken than it already was.
Diffstat (limited to 'bench')
-rw-r--r-- | bench/MHz.c | 48 |
1 files changed, 35 insertions, 13 deletions
diff --git a/bench/MHz.c b/bench/MHz.c index 0d429d7..87315a9 100644 --- a/bench/MHz.c +++ b/bench/MHz.c @@ -1,39 +1,50 @@ /* - * This file is part of x86info. * (C) 2001 Dave Jones. * * Licensed under the terms of the GNU GPL License version 2. - * - * Estimate CPU MHz routine by Andrea Arcangeli <andrea@suse.de> - * Small changes by David Sterba <sterd9am@ss1000.ms.mff.cuni.cz> */ #include <stdio.h> #include <sys/time.h> -#include <string.h> #include <unistd.h> +#include <stdlib.h> + +#define _GNU_SOURCE +#define __USE_GNU +#include <sched.h> +#include <string.h> +#include <signal.h> #include "../x86info.h" -unsigned long long int rdtsc(void) +static unsigned long long int rdtsc(void) { unsigned long long int x; __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x)); return x; } +static volatile int nosignal = 0; + +static void sighandler(int sig __attribute__((unused))) +{ + nosignal = 1; +} + void estimate_MHz(struct cpudata *cpu) { + cpu_set_t set; struct timezone tz; struct timeval tvstart, tvstop; unsigned long long int cycles[2]; /* gotta be 64 bit */ unsigned long microseconds; /* total time taken */ unsigned int eax, ebx, ecx, edx; unsigned long freq = 1; + unsigned long i; /* Make sure we have a TSC (and hence RDTSC) */ cpuid(cpu->number, 1, &eax, &ebx, &ecx, &edx); - if ((edx & (1<<4))==0) { + if ((edx & (1<<4)) == 0) { printf("No TSC, MHz calculation cannot be performed.\n"); cpu->MHz = 0; return; @@ -41,15 +52,25 @@ void estimate_MHz(struct cpudata *cpu) memset(&tz, 0, sizeof(tz)); - /* get this function in cached memory */ - gettimeofday(&tvstart, &tz); + if (sched_getaffinity(getpid(), sizeof(set), &set) == 0) { + CPU_ZERO(&set); + CPU_SET(cpu->number, &set); + sched_setaffinity(getpid(), sizeof(set), &set); + } + + if (signal(SIGALRM, sighandler) == SIG_ERR) { + printf("Some kind of signal failure.\n"); + return; + } + cycles[0] = rdtsc(); gettimeofday(&tvstart, &tz); - /* we don't trust that this is any specific length of time */ - usleep(250000); + alarm(3); + while (!nosignal) { + i = i * rand(); + } - gettimeofday(&tvstop, &tz); cycles[1] = rdtsc(); gettimeofday(&tvstop, &tz); @@ -62,5 +83,6 @@ void estimate_MHz(struct cpudata *cpu) cpu->MHz = ((cpu->MHz / 50) * 50) + 50; else cpu->MHz = ((cpu->MHz / 50) * 50); -} + nosignal = 0; +} |