Subject: POSIX timer_settime() dosn't set timer in some cases (lost accuracy)
To: None <tech-kern@netbsd.org>
From: Ian Zagorskih <ianzag@megasignal.com>
List: tech-kern
Date: 08/31/2004 23:44:45
NetBSD IANZAG 2.0G NetBSD 2.0G (IANZAG) #1: Thu Aug 26 02:11:03 NOVST 2004
ianzag@IANZAG:/usr/src/sys/arch/i386/compile/IANZAG i386
According to POSIX docs at
http://www.opengroup.org/onlinepubs/009695399/functions/timer_getoverrun.html
---cut---
The timer_gettime() function shall store the amount of time until the
specified timer, timerid, expires and the reload value of the timer into the
space pointed to by the value argument. The it_value member of this structure
shall contain the amount of time before the timer expires, or zero if the
timer is disarmed.
---cut---
Same as NetBSD man pages says:
---cut---
The timer_settime() sets the next expiration time of the timer with id timerid
to the it_value specified in the tim argument. If the value is 0, the timer
is disarmed.
---cut---
So, the code below
struct itimerspec its;
its.it_value.tv_sec = 0;
its.it_value.tv_nsec = 1;
its.it_interval.tv_sec = 1;
its.it_interval.tv_nsec = 0;
timer_settime(timerid, 0, &its, 0);
..must work course it_value field isn't zero. Even more, in the past according
to the POSIX specs i'v got used to "start interval timer as far as possibly
without initial delay" just setting it_value as shown above (sec = 0, nsec =
1).
On the other hand, sys_timer_settime() in kern/kern_time.c converts itimerspec
structure into internal itimerval struture with macro TIMESPEC_TO_TIMEVAL as:
#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
(tv)->tv_sec = (ts)->tv_sec; \
(tv)->tv_usec = (ts)->tv_nsec / 1000; \
}
Obviously, doing this way we'r lossing nanosecond part and 1 ns becomes 0 us
-> timer isn't armed. From my point of view this violates POSIX way :)
Any ideas/comments ?
ps: Just porting some own old code and found that timer isn't armed while it's
expected to..
// wbr