Subject: timing issue
To: None <netbsd-users@netbsd.org>
From: None <lists@badzong.com>
List: netbsd-users
Date: 11/18/2006 05:16:32
Hi all,

I just wrote a small test application using nanosleep, usleep & select
and compiled it on freebsd 6.1 and netbsd 3.0. While the timers on
freebsd were pretty accurate and stayed within an expected range,
netbsd's diverged massively:

The program sleeps 3 times for 1000 usec and measures how long it was
suspended.

// timing.c
-------------------------------------------------------------------------
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>

int main(void)
{
	struct timeval timer1, timer2, timeout = { 0, 1000 };
	struct timespec req = { 0, 1000000 };
	fd_set rset;

	// testing gettimeofday
	if(gettimeofday(&timer1, NULL)) _exit(-1);
	if(gettimeofday(&timer2, NULL)) _exit(-1);

	printf("gettimeofday:\t%6d usec\n",
		(timer2.tv_sec*1000000+timer2.tv_usec)-(timer1.tv_sec*1000000+timer1.tv_usec));

	// testing nanosleep
	if(gettimeofday(&timer1, NULL)) _exit(-1);
	nanosleep(&req, NULL);
	if(gettimeofday(&timer2, NULL)) _exit(-1);

	printf("nanosleep:\t%6d usec\n",
		(timer2.tv_sec*1000000+timer2.tv_usec)-(timer1.tv_sec*1000000+timer1.tv_usec));

	// testing usleep
	if(gettimeofday(&timer1, NULL)) _exit(-1);
	usleep(1000);
	if(gettimeofday(&timer2, NULL)) _exit(-1);

	printf("usleep:\t\t%6d usec\n",
		(timer2.tv_sec*1000000+timer2.tv_usec)-(timer1.tv_sec*1000000+timer1.tv_usec));

	// testing select on stdin
	FD_ZERO(&rset);
	FD_SET(0, &rset); //stdin

	if(gettimeofday(&timer1, NULL)) _exit(-1);
	if(select(1, &rset, NULL, NULL, &timeout) == -1) _exit(-1);
	if(gettimeofday(&timer2, NULL)) _exit(-1);

	printf("select:\t\t%6d usec\n",
		(timer2.tv_sec*1000000+timer2.tv_usec)-(timer1.tv_sec*1000000+timer1.tv_usec));

	return 0;
}
//------------------------------------------------------------------------------------

freebsd results stay always below 2000 usec:

gettimeofday:         2 usec
usleep:            1995 usec
nanosleep:         1996 usec
select:            1998 usec


netbsd's results range from 9000 to 20000 usec with an average of 14000
usec.

gettimeofday:         2 usec
usleep:           13096 usec
nanosleep:        12056 usec
select:           13476 usec

Why is netbsd so inaccurate and is there a more precise system call or a
workaround?

TIA, manuel