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>