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.
This commit is contained in:
Bruce Evans 2004-05-26 09:43:38 +00:00
parent 30346936cf
commit 026afdcc05
2 changed files with 20 additions and 6 deletions

View File

@ -220,8 +220,15 @@ cputime()
#ifndef 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);
}
@ -330,7 +337,7 @@ startguprof(gp)
gp->profrate = timer_freq << CPUTIME_CLOCK_I8254_SHIFT;
#ifndef 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() &&

View File

@ -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() &&