Just a sanity check before I sumbit a buig report
Jon Noack
noackjr at alumni.rice.edu
Thu Mar 10 12:42:18 PST 2005
Pete French wrote:
>>'sysctl kern.clockrate' will return this information if you don't want to
>>write a program to do it for you :)
>
> I was just using the code from time(1). Inteesring though - heres the
> output:
>
> kern.clockrate: { hz = 100, tick = 10000, tickadj = 5, profhz = 100, stathz = 100 }
>
> So that thinks stathz is 100, but sysconf(_SC_CLK_TCK) is returning 128!
>
>>What are the two machines? stathz is 128 on i386, 100 on sparc64, and 130
>>on amd64. Or thats the defaults at least.
>
> These are all i386 machines - I have a number of them, all running 4.11.
> I can take the same a.out and run it on all of them - on some both
> numbers are 128, on other the numbers are 100 and 128.
>
> If I go to one where both the calls return 128 though, the output
> of 'sysctl kern.clockrate' is this:
>
> kern.clockrate: { hz = 100, tick = 10000, tickadj = 5, profhz = 1024, stathz = 128 }
>
> So, it looks like theres a bug in sysconf(_SC_CLK_TCK) possibly ? because
> it seems to be always returning 128, regardless of the value of stathz
> as returned by 'sysctl kern.clockrate'
>
> I can reproduce this on a number of machines BTW - the only things they have in
> common is that I wrote their kernel config files at various points in time...
I infer from your kern.clockrate output that you are running 4.x.
Why does sysconf(_SC_CLK_TCK) always returns 128? Check out sysconf()
in src/lib/libc/gen/sysconf.c (lines 83-84 of rev. 1.10):
**********************************************************************
case _SC_CLK_TCK:
return (CLK_TCK);
**********************************************************************
CLK_TCK is defined in src/include/time.h (line 52 of rev. 1.15):
**********************************************************************
#define CLK_TCK _BSD_CLK_TCK_
**********************************************************************
_BSD_CLK_TCK_ is defined in src/sys/i386/include/ansi.h (line 101 of
rev. 1.18.2.4):
**********************************************************************
#define _BSD_CLK_TCK_ 128
**********************************************************************
So on i386 (and FreeBSD 4.x), sysconf(_SC_CLK_TCK) will always return
128. If you look in src/sys/alpha/include/ansi.h, you'll see that on
alpha it will always return 100.
To determine how stathz can vary, we'll have to dig deeper. Check out
initclocks() in src/sys/kern/kern_clock.c (lines 196-213 of rev.
1.105.2.11):
**********************************************************************
/*
* Set divisors to 1 (normal case) and let the machine-specific
* code do its bit.
*/
psdiv = pscnt = 1;
cpu_initclocks();
#ifdef DEVICE_POLLING
init_device_poll();
#endif
/*
* Compute profhz/stathz, and fix profhz if needed.
*/
i = stathz ? stathz : hz;
if (profhz == 0)
profhz = i;
psratio = profhz / i;
**********************************************************************
stathz and profhz are originally set by cpu_initclocks() (which is MD).
If they are not set at this point, hz is used. This must be the case
for some of your machines as both stathz and profhz equal hz. So why
aren't stathz and profhz being set earlier? Check out cpu_initclocks()
in src/sys/i386/isa/clock.c (lines 995-1008 of rev. 1.149.2.6):
********************************************************************** if
(statclock_disable) {
/*
* The stat interrupt mask is different without the
* statistics clock. Also, don't set the interrupt
* flag which would normally cause the RTC to generate
* interrupts.
*/
stat_imask = HWI_MASK | SWI_MASK;
rtc_statusb = RTCSB_24HR;
} else {
/* Setting stathz to nonzero early helps avoid races. */
stathz = RTC_NOPROFRATE;
profhz = RTC_PROFRATE;
}
**********************************************************************
If you look in src/sys/isa/rtc.h, you'll see that RTC_NOPROFRATE=128 and
RTC_PROFRATE=1024. The only way stathz and profhz will not be set here
is if statclock_disable is true. Where is statclock_disable set? Check
out apm_attach() in src/sys/i386/apm/apm.c (lines 1032-1033 of rev.
1.114.2.6):
**********************************************************************
if (flags & 0x20)
statclock_disable = 1;
**********************************************************************
Thus, you must have "device apm0 flags 0x20" or something similar in
your kernel config file for you to get stathz and profhz as 100. apm is
disabled in GENERIC, so by default this is not a problem; apm_attach
won't be called if apm is disabled, so the fact that GENERIC includes
"flags 0x20" is irrelevant.
Jon
More information about the freebsd-stable
mailing list