Timekeeping [Was: Re: cvs commit: src/usr.bin/vmstat vmstat.c src/usr.bin/w w.c]

Poul-Henning Kamp phk at phk.freebsd.dk
Fri Oct 21 07:47:39 PDT 2005


In message <20051021230751.Q5110 at delplex.bde.org>, Bruce Evans writes:
>On Thu, 20 Oct 2005, Poul-Henning Kamp wrote:

>> ...
>> If people do stupid things like use hard steps (*settime*()) to
>> correct rate problems, then they get what they deserve, including
>> potentially backwards jumps in time, but the integral over time of
>> all steps apart from the first one amounts to a rate correction.
>
>Using *settime*() isn't stupid.

Using it more than once per boot is stupid, and abundantly makes
it clear that precise timekeeping is not what you are attempting.

>> In summary:  CLOCK_MONOTONIC is our best estimate of how many SI
>> seconds the system have been runing [3].
>
>Actual testing shows that CLOCK_MONOTONIC, or possibly CLOCK_REALTIME
>less the boot time, gives a very bad estimate of how long the system has
>been running.  The difference between these clocks was about 500 seconds
>on all systems tested:
>
>% sledge:
>%  1:03PM  up 22:45, 1 user, load averages: 0.23, 0.08, 0.02
>% uptime 1 81900
>% uptime 2 82887

Works fine for me:

	sledge phk> cat > a.c
	#include <stdio.h>
	#include <sys/time.h>
	
	int
	main(int argc __unused, char **argv __unused)
	{
		struct timeval boottime;
		struct timespec up, utc;
		size_t s;

		s = sizeof boottime;
		sysctlbyname("kern.boottime", &boottime, &s, NULL, 0);
		printf("Boottime\t%ld.%06d\n",
		    boottime.tv_sec, boottime.tv_usec);
		clock_gettime(CLOCK_MONOTONIC, &up);
		printf("Uptime\t\t%ld.%09d\n", up.tv_sec, up.tv_nsec);
		clock_gettime(CLOCK_REALTIME, &utc);
		printf("UTC\t\t%ld.%09d\n", utc.tv_sec, utc.tv_nsec);
		return(0);
	}
	^D
	sledge phk> make a
	cc -O2 -fno-strict-aliasing -pipe   a.c  -o a
	sledge phk> ./a
	Boottime        1129904420.816916
	Uptime          1317.689747507
	UTC             1129905738.506671500
	sledge phk> bc
	[...]
	1129904420.816916+1317.689747507
	1129905738.506663507

Mind you, there is no way the above cannot work because that is how
the math in the kernel works.

>Not given, and not true.  After syncing with an accurate external clock
>by a step, we know the real time very accurately.  Normally we sync
>soon after booting.  Then we know the boot time very accurately (it
>is the current real time less CLOCK_MONOTONIC).  Then if we resync
>with the external clock later using a step, we again know the real
>time very accurately, [...]

But have resigned ourselves to not caring about the actual length
of seconds and therefore, presumably, having no serious interest
in timekeeping quality.

-- 
Poul-Henning Kamp       | UNIX since Zilog Zeus 3.20
phk at FreeBSD.ORG         | TCP/IP since RFC 956
FreeBSD committer       | BSD since 4.3-tahoe    
Never attribute to malice what can adequately be explained by incompetence.


More information about the cvs-src mailing list