cvs commit: src/usr.bin/vmstat vmstat.c src/usr.bin/w w.c

Bruce Evans bde at zeta.org.au
Wed Oct 19 21:02:02 PDT 2005


On Tue, 18 Oct 2005, Poul-Henning Kamp wrote:

> In message <20051018135821.L93164 at delplex.bde.org>, Bruce Evans writes:
>
>> This is bogus, and it breaks vmstat some more in the dead kernel case.
>>
>> In the live kernel case, clock_gettime() returns the time since an
>> unspecified point in the past.  It is still necessary to subtract the
>> boottime, one measured by the same clock, especially under systems
>> like FreeBSD where the "unspecified point in the past" is undocumented.
>
> The unspecified point in the past is actually the exact time the kernel
> booted and therefore clock_gettime(CLOCK_MONOTONIC) does the right thing
> for a running kernel.

This is an undocumented implementation detail.
clock_gettime(CLOCK_MONOTONIC) does a wrong thing partly because it depends
on this detail.

>> For live kernels, subtracting the boot time from the current _real_
>> time using difftime() is the correct method.
>
> Actually it isn't, but it comes close.  CLOCK_MONOTONIC is the true
> elapsed time since boot, whereas boottime is our retrospective UTC
> estimate of that moment.

Actually, both are wrong methods, although both could work:

Using difftime() doesn't because difftime() doesn't understand leap
seconds.  It needs to understand leap seconds, at least under POSIX
where time_t is specified to be broken, but it just does a naive
subtraction of time_t's.  Thus (mis)using difftime() on the time_t's
returned by clock_gettime(CLOCK_MONOTONIC, ...) works because difftime()
is broken, but using difftime() on the time_t's returned by
clock_gettime(CLOCK_REALTIME) doesn't work.  vmstat wants the difference
in seconds, but w converts to a "human readable" time using a naive
method that doesn't understand leap seconds, so it actually wants the
wrong difference provided by not having leap seconds in real times and
not adjusting for them in difftime().

Using CLOCK_MONOTONIC doesn't work because it it gives the system's idea
of the time and doesn't try hard to keep in sync with the real time.
In particular, it doesn't jump when the real time is stepped by
settimeofday(2) or clock_settime(2).  Sometimes such a step is to fix
up the real time after it has drifted.  Since steps are not applied
to the monotonic time, the monotonic time retains the drift and differences
in the monotonic time don't give differences in real time.

Bruce


More information about the cvs-src mailing list