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:
parent
f3d67a1356
commit
8be6dace2b
@ -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() &&
|
||||
|
@ -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() &&
|
||||
|
Loading…
Reference in New Issue
Block a user