Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 6 Jun 1995 09:34:00 -0500
From:      Jim Lowe <james@miller.cs.uwm.edu>
To:        bde@zeta.org.au, freebsd-hackers@FreeBSD.ORG
Subject:   Re: Interval timer/System clock
Message-ID:  <199506061434.JAA01498@miller.cs.uwm.edu>

next in thread | raw e-mail | index | archive | help
> This breaks sleep() again.  sleep(n) shall sleep at least n seconds (POSIX
> spec), but if the 1 is added then sleep(n) is only guaranteed to sleep
> at least (n - 1/hz) seconds; it sleeps an average of about (n - 1/(2*hz))
> seconds for random calls and about (n - (time for sleep() call)) seconds
> for calls in a loop.
> 
> No.  hzto() is better placed than most callers to someday handle the partial
> tick more accurately.  Only realitexpire() is better placed.
> 

I think I now understand the problem, but I beleive the interval timers and
select is still broken in FreeBSD.  Having my druthers, I would rather have
the timers return after a 10ms sleep, than have the sleep system call be off
by +-0.5ms.

Every other system I tested implemented these timers so a user program could
clock at the same speed as the system clock.  In FreeBSD, the select
and interval timers can't return at the time specified since that would
break sleep.  Actaully, in FreeBSD they return 10ms late.

I am at a loss to provide a fix for this.  I beleive the attached select
system call should return after approx 10ms -- not 20ms, don't you?
Is the correct fix for this to subtract 1 from the hzto() call in
sys_generic.c.

Also, for the Interval timers, is the correct fix to subtract 1 from the
realitexpire?  Since sleep uses the interval timers -- will this fix
the interval timers and break posix sleep?

FreeBSD is the only system I have a problem with the interval timers and
the select system call.  I have looked at code on the other systems and
they seem to ignore this posix problem -- but their timers actually return
on time rather than 10ms later.

Is there a clean solution that will fix this 1/2 tick problem and still
allow select and the interval timers to work the way they do on other OSes?
Or will FreeBSD be known as the system that is always 10ms late? :-)

	-Jim
--------------------------stest.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#include <signal.h>

#define WAIT_TIME	10000

int
main(int ac, char **av)
{
struct timeval tv, tvo;
struct timeval tvs;
double u,v;
int		nwaits;

	gettimeofday(&tvo, NULL);

	tvs.tv_sec = 0;
	if(ac == 2)
		tvs.tv_usec = atoi(av[1]);
	else
		tvs.tv_usec = WAIT_TIME;
	nwaits = 1;
	u = 0;
	while(1) {
		select(0,0,0,0, &tvs);
		gettimeofday(&tv, NULL);
		v = (tv.tv_sec - tvo.tv_sec) + 1e-6 * (tv.tv_sec - tvo.tv_sec);
		if(v - u > 1.0) {
			printf("%d %8.8f %8.8f %8.8f\r", nwaits, v,
						(double)nwaits/v,
						v/(double)nwaits);
			fflush(stdout);
			u = v;
		}
		nwaits++;
	}

}	



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