diff options
author | jhb <jhb@FreeBSD.org> | 2012-07-13 13:24:33 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2012-07-13 13:24:33 +0000 |
commit | e4bb5cb3f00b47c0978dee1bcda1b3fe9075508e (patch) | |
tree | 34e348f0de41b94500eddd414c04c0cb471ff622 /sys/kern/kern_event.c | |
parent | 2b8d56f3cffc7d6d5e967273ea2edea9c19d44ac (diff) | |
download | FreeBSD-src-e4bb5cb3f00b47c0978dee1bcda1b3fe9075508e.zip FreeBSD-src-e4bb5cb3f00b47c0978dee1bcda1b3fe9075508e.tar.gz |
Make the interval timings for EVFILT_TIMER more accurate. tvtohz() always
adds an extra tick to account for the current partial clock tick. However,
that is not appropriate for a repeating timer when the exact tvtohz() value
should be used for subsequent intervals. Fix repeating callouts for
EVFILT_TIMER by subtracting 1 tick from the tvtohz() result similar to the
fix used in realitexpire() for interval timers.
While here, update a few comments to note that if the EVFILT_TIMER code
were to move out of kern_event.c, it should move to kern_time.c (where the
interval timer code it mimics lives) rather than kern_timeout.c.
MFC after: 1 month
Diffstat (limited to 'sys/kern/kern_event.c')
-rw-r--r-- | sys/kern/kern_event.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index b25c678..6a920ca 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -513,6 +513,10 @@ knote_fork(struct knlist *list, int pid) list->kl_unlock(list->kl_lockarg); } +/* + * XXX: EVFILT_TIMER should perhaps live in kern_time.c beside the + * interval timer support code. + */ static int timertoticks(intptr_t data) { @@ -526,7 +530,6 @@ timertoticks(intptr_t data) return tticks; } -/* XXX - move to kern_timeout.c? */ static void filt_timerexpire(void *knx) { @@ -536,9 +539,16 @@ filt_timerexpire(void *knx) kn->kn_data++; KNOTE_ACTIVATE(kn, 0); /* XXX - handle locking */ + /* + * timertoticks() uses tvtohz() which always adds 1 to allow + * for the time until the next clock interrupt being strictly + * less than 1 clock tick. We don't want that here since we + * want to appear to be in sync with the clock interrupt even + * when we're delayed. + */ if ((kn->kn_flags & EV_ONESHOT) != EV_ONESHOT) { calloutp = (struct callout *)kn->kn_hook; - callout_reset_curcpu(calloutp, timertoticks(kn->kn_sdata), + callout_reset_curcpu(calloutp, timertoticks(kn->kn_sdata) - 1, filt_timerexpire, kn); } } @@ -546,7 +556,6 @@ filt_timerexpire(void *knx) /* * data contains amount of time to sleep, in milliseconds */ -/* XXX - move to kern_timeout.c? */ static int filt_timerattach(struct knote *kn) { @@ -570,7 +579,6 @@ filt_timerattach(struct knote *kn) return (0); } -/* XXX - move to kern_timeout.c? */ static void filt_timerdetach(struct knote *kn) { @@ -583,7 +591,6 @@ filt_timerdetach(struct knote *kn) kn->kn_status |= KN_DETACHED; /* knlist_remove usually clears it */ } -/* XXX - move to kern_timeout.c? */ static int filt_timer(struct knote *kn, long hint) { |