diff options
author | bde <bde@FreeBSD.org> | 2004-05-26 09:43:38 +0000 |
---|---|---|
committer | bde <bde@FreeBSD.org> | 2004-05-26 09:43:38 +0000 |
commit | 8be6dace2bc14f1cd052e5bf5a868d62885110c1 (patch) | |
tree | bd05f5ae9574c66016064bcf95c9f6380fcce0a0 /sys/i386/isa | |
parent | f3d67a1356f86fc772d88ffcc2c7b92d00bb9bca (diff) | |
download | FreeBSD-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.c | 13 |
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() && |