Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 20 Oct 2005 14:01:57 +1000 (EST)
From:      Bruce Evans <bde@zeta.org.au>
To:        Poul-Henning Kamp <phk@phk.freebsd.dk>
Cc:        cvs-src@FreeBSD.org, src-committers@FreeBSD.org, Andre Oppermann <andre@FreeBSD.org>, cvs-all@FreeBSD.org
Subject:   Re: cvs commit: src/usr.bin/vmstat vmstat.c src/usr.bin/w w.c 
Message-ID:  <20051020131450.T99502@delplex.bde.org>
In-Reply-To: <67214.1129620597@critter.freebsd.dk>
References:  <67214.1129620597@critter.freebsd.dk>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, 18 Oct 2005, Poul-Henning Kamp wrote:

> In message <20051018135821.L93164@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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20051020131450.T99502>