Messages in this thread | | | Subject | Re: 'Detected 19943xxx Hz processor'-fluctuations... | From | Florian Weimer <> | Date | 14 Jan 1999 17:58:21 +0100 |
| |
Robert Woodcock <rcw@debian.org> writes:
> > Aren't you trying to measure the precision of a clock with the same > > clock? > > No wonder it was working so well :> > > Anyone wanna fill me in on how well it works with a kernel compiled to > use do_slow_gettimeoffset?
Here's something new to play with. The program gives the correct processor frequency most of the time, but some values are awefully wrong (about 40 or 400 MHz for a PII/266MHz...).
Of course, the questions still is whether the program really measures clocks per RTC interrupt (and nothing else is disturbing the results).
/* * Comparision of Pentium TSC and RTC. * * Copyright (c) 1999 by Florian Weimer. * Based on Paul Gortmaker's /dev/rtc example program. * * Released under the GNU General Public License, version 2. * * Compile with: gcc -O2 -Wall tsc-rtc.c -o tsc-rtc * Invoke with: tsc-rtc frequency * For example: tsc-rtc 16 * means 16 measurements per second * Frequency should a power of two between 1 and 64. * Higher powers of two are possible, but require superuser privileges. * The program perpetually prints approximations of the processors * clock frequency. Requires RDTSC instruction and /dev/rtc kernel * support. Doesn't work with SMP, of course. * */
#include <stdio.h> #include <stdlib.h>
#include <unistd.h> #include <fcntl.h> #include <errno.h> #include <sys/ioctl.h>
#include <linux/mc146818rtc.h>
typedef unsigned long long int tsc_t; extern __inline__ tsc_t rdtsc(void) { tsc_t x; __asm__ volatile ("rdtsc" : "=A" (x)); return x; }
int main(int argc, char ** argv) { int fd, retval, first; unsigned int freq; tsc_t old_tsc = 0;
if (argc != 2) { fprintf(stderr, "usage: %s frequency\n", argv[0]); exit(EINVAL); }
freq = atoi(argv[1]);
fd = open ("/dev/rtc", O_RDONLY); if (fd == -1) { perror("open(\"/dev/rtc\")"); exit(errno); }
/* Turn off update interrupts */ retval = ioctl(fd, RTC_UIE_OFF, 0); if (retval == -1) { perror("ioctl(RTC_UIE_OFF)"); exit(errno); } /* Set periodic interrupt frequency */ retval = ioctl(fd, RTC_IRQP_SET, freq); if (retval == -1) { perror("ioctl(RTC_IRQP_SET"); exit(errno); }
/* Enable periodic interrupts */ retval = ioctl(fd, RTC_PIE_ON, 0); if (retval == -1) { perror("ioctl(RTC_PIE_ON)"); exit(errno); }
first = 1; while (1) { tsc_t new_tsc; unsigned int count; /* This blocks */ retval = read(fd, &count, sizeof(count)); if (retval == -1) { perror("read(\"/dev/rtc\")"); exit(errno); } new_tsc = rdtsc(); count >>= 8; /* Calculate IRQ count */
if (!first) { int diff; diff = ((unsigned)new_tsc - (unsigned)old_tsc); /* First divide, then multiply to avoid overflow. */ printf("%d\n", (diff / count) * freq); } else { first = 0; } old_tsc = new_tsc; }
return 0; }
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |