Subject: setitimer discrepancy between Netbsd 1.4.1 and 1.5.1 or later
To: , <tech-kern@netbsd.org>
From: Stuart Brooks <stuartb@cat.co.za>
List: tech-kern
Date: 10/08/2004 15:26:24
This is a multi-part message in MIME format.

------=_NextPart_000_1B9A_01C4AD4B.2BD68CD0
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

On my i386 (Celeron 1.2G) machine I have noticed a discrepancy in the
interrupts generated by setitimer between NetBSD 1.4.1 (which does what I
expect) and later versions. I understand the granularity of the clock tick
is 10ms but NetBSD 1.5.1 refuses to timeout at less than 20ms, although it
will happily timeout at 20,30,40,50ms etc.

Here is the printout from a sample program (which I have attached) :

Netbsd 1.4.1 (as expected):
Delay set to 10000us
- 3907us
- 9964us
- 10061us
- 9962us
- 9974us
- 10026us
- 9975us
- 10031us

Netbsd 1.5.1 (incorrect):
Delay set to 10000us
- 15248us
- 20011us
- 19991us
- 20072us
- 19914us
- 19991us
- 20001us
- 20006us

I thought that it might be because I was just missing a clock tick because
the 10ms timer is "on the edge" but I get exactly the same results with a
1ms timer (20ms on 1.5.1 and 10ms on 1.4.1).

Is this the correct operation? And if so then it effectively means that it
is impossible to have more than 50 timed interrupts a second.
Any help would be appreciated,

 Stuart

------=_NextPart_000_1B9A_01C4AD4B.2BD68CD0
Content-Type: application/octet-stream;
	name="testprog.cpp"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="testprog.cpp"

#include <cstdio>=0A=
#include <unistd.h>=0A=
#include <signal.h>=0A=
#include <sys/time.h>=0A=
=0A=
#define DELAY_MS (10)=0A=
=0A=
//----------------------------------------------------------------------/=
/=0A=
void displayTimeDiff(timespec &start_t,timespec &stop_t)=0A=
{=0A=
	timespec diff_t;=0A=
	timespecsub(&stop_t,&start_t,&diff_t);=0A=
	=0A=
	int microsec=3Ddiff_t.tv_sec*1000000+diff_t.tv_nsec/1000;=0A=
	printf(" - %dus\n",microsec);=0A=
}=0A=
=0A=
//----------------------------------------------------------------------/=
/=0A=
void testSignalTimeout()=0A=
{=0A=
	printf("Delay set to %dus\n",DELAY_MS*1000);=0A=
=0A=
	timespec start_t,stop_t;=0A=
	timeval t=3D{0,DELAY_MS*1000};=0A=
	struct itimerval get,set=3D{t,t};=0A=
=0A=
	// Start the timer=0A=
	setitimer(ITIMER_REAL,&set,&get);=0A=
=0A=
	clock_gettime(CLOCK_REALTIME,&start_t);=0A=
	for (int i=3D0;i<20;i++)=0A=
		{=0A=
=0A=
			select(0,NULL,NULL,NULL,NULL);=0A=
			clock_gettime(CLOCK_REALTIME,&stop_t);=0A=
			=0A=
			displayTimeDiff(start_t,stop_t);=0A=
			start_t=3Dstop_t;=0A=
		}=0A=
=0A=
	// Stop the timer=0A=
	setitimer(ITIMER_REAL,&get,&set);=0A=
}=0A=
=0A=
//----------------------------------------------------------------------/=
/=0A=
void sig_int(int signo)=0A=
{=0A=
	// Do nothing=0A=
}=0A=
=0A=
//----------------------------------------------------------------------/=
/=0A=
int main(int argc,char**argv)=0A=
{=0A=
	if(signal(SIGALRM, sig_int) =3D=3D SIG_ERR)=0A=
		{=0A=
			printf("listenForSignal - cannot catch SIGALRM\n");=0A=
		}=0A=
=0A=
	testSignalTimeout();=0A=
	return 0;=0A=
}=0A=

------=_NextPart_000_1B9A_01C4AD4B.2BD68CD0--