summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>2004-05-26 09:43:38 +0000
committerbde <bde@FreeBSD.org>2004-05-26 09:43:38 +0000
commit8be6dace2bc14f1cd052e5bf5a868d62885110c1 (patch)
treebd05f5ae9574c66016064bcf95c9f6380fcce0a0 /sys/i386/isa
parentf3d67a1356f86fc772d88ffcc2c7b92d00bb9bca (diff)
downloadFreeBSD-src-8be6dace2bc14f1cd052e5bf5a868d62885110c1.zip
FreeBSD-src-8be6dace2bc14f1cd052e5bf5a868d62885110c1.tar.gz
Quick fix for overflow when tsc_freq >= 2^31. "int profrate" in struct
gmon and struct gmonhdr was originally just to represent the kernel (profiling) clock frequency and it remains poorly suited to representing the frequencies of fast counters like the TSC. It broke a year or two ago. This quick fix keeps it working for another year or month or two until TSC frequencies can exceed 2^32, by dividing the frequency by 2. Dividing the frequency by 4 would work for a little longer but would lose a little too much precision.
Diffstat (limited to 'sys/i386/isa')
-rw-r--r--sys/i386/isa/prof_machdep.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/sys/i386/isa/prof_machdep.c b/sys/i386/isa/prof_machdep.c
index 31b1c2a..57d2342 100644
--- a/sys/i386/isa/prof_machdep.c
+++ b/sys/i386/isa/prof_machdep.c
@@ -190,8 +190,15 @@ cputime()
#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP)
if (cputime_clock == CPUTIME_CLOCK_TSC) {
- count = (u_int)rdtsc();
- delta = (int)(count - prev_count);
+ /*
+ * Scale the TSC a little to make cputime()'s frequency
+ * fit in an int, assuming that the TSC frequency fits
+ * in a u_int. Use a fixed scale since dynamic scaling
+ * would be slower and we can't really use the low bit
+ * of precision.
+ */
+ count = (u_int)rdtsc() & ~1u;
+ delta = (int)(count - prev_count) >> 1;
prev_count = count;
return (delta);
}
@@ -300,7 +307,7 @@ startguprof(gp)
gp->profrate = timer_freq << CPUTIME_CLOCK_I8254_SHIFT;
#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP)
if (cputime_clock == CPUTIME_CLOCK_TSC)
- gp->profrate = tsc_freq;
+ gp->profrate = tsc_freq >> 1;
#if defined(PERFMON) && defined(I586_PMC_GUPROF)
else if (cputime_clock == CPUTIME_CLOCK_I586_PMC) {
if (perfmon_avail() &&
OpenPOWER on IntegriCloud