Interval timers firing early
John Baldwin
jhb at freebsd.org
Wed Feb 11 14:16:19 PST 2009
On Wednesday 31 December 2008 9:42:28 pm Peter Jeremy wrote:
> I have some code that uses setitimer() to generate one-shot timers of
> ~60s (the intent is to fire ~10msec before the minute boundary).
>
> On my amd64 laptop running 7.0-stable from mid-March the SIGALRM
> arrives at the expected time. On a system running a recent amd64
> -current, the SIGALRM arrives about 10msec late (which I'm not too
> fussed about).
>
> On two i386 systems running 7.1-PRE (from mid-Oct) and a fresh 7.1-RC2
> install, the SIGALRM arrives early - ~11msec for the 7.1-PRE system and
> ~5msec for the 7.1-RC2 system.
>
> All systems are running HZ=1000. Two of the systems (the one running
> 7.1-PRE and the one running -current) are running BOINC. All systems
> are otherwise unloaded. I've looked at the timer code and can't
> quickly see anything that would explain this. Does anyone have any
> ideas?
>
> The relevant code looks like the following:
> while (1) {
> struct timeval now;
> struct itimerval it;
> int usecs;
>
> if (gettimeofday(&now, NULL) < 0) {
> syslog(LOG_ERR, "gettimeofday: %m");
> exit(1);
> }
> /* Set timer for just before next minute */
> it.it_interval.tv_sec = 0;
> it.it_interval.tv_usec = 0;
> usecs = 59990000 - ((now.tv_sec % 60) * 1000000 + now.tv_usec);
> if (usecs < 10000) /* allow 10msec slop */
> usecs += 60000000;
> it.it_value.tv_sec = usecs / 1000000;
> it.it_value.tv_usec = usecs % 1000000;
> if (setitimer(ITIMER_REAL, &it, NULL) < 0) {
> syslog(LOG_ERR, "setitimer: %m");
> exit(1);
> }
> printf("%d.%06ld %2d.%06ld %d\n", now.tv_sec, now.tv_usec,
> it.it_value.tv_sec, it.it_value.tv_usec, usecs);
> /* do stuff here which is interrupted by SIGALRM */
> }
>
> On the 7.1-PRE system, I get output like:
> 1230776939.991464 59.998536 59998536
> 1230776999.978991 0.011009 11009
> 1230776999.991996 59.998004 59998004
> 1230777059.979532 0.010468 10468
> 1230777059.991538 59.998462 59998462
> 1230777119.979058 0.010942 10942
> 1230777119.991065 59.998935 59998935
> 1230777179.978597 0.011403 11403
> 1230777179.991610 59.998390 59998390
> 1230777239.979139 0.010861 10861
> 1230777239.991142 59.998858 59998858
On a whim, hack kern_tc.c to only use 2 or 3 timehands structures instead of
64.
--
John Baldwin
More information about the freebsd-stable
mailing list