diff options
author | kib <kib@FreeBSD.org> | 2017-01-01 12:19:58 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2017-01-01 12:19:58 +0000 |
commit | febe125ddecfeb91b6abda7545ca45847ac6695a (patch) | |
tree | 007edef3f5d38e2fa5f9307489ece20a36470baf /sys/kern | |
parent | 0c98a5b576907cd0a526d05ecb291fd67359db12 (diff) | |
download | FreeBSD-src-febe125ddecfeb91b6abda7545ca45847ac6695a.zip FreeBSD-src-febe125ddecfeb91b6abda7545ca45847ac6695a.tar.gz |
MFC r310554:
Some optimizations for kqueue timers.
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_event.c | 52 |
1 files changed, 28 insertions, 24 deletions
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index 060fc5a..0983e95 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -611,23 +611,29 @@ timer2sbintime(intptr_t data, int flags) return (-1); } +struct kq_timer_cb_data { + struct callout c; + sbintime_t next; /* next timer event fires at */ + sbintime_t to; /* precalculated timer period */ +}; + static void filt_timerexpire(void *knx) { - struct callout *calloutp; struct knote *kn; + struct kq_timer_cb_data *kc; kn = knx; kn->kn_data++; KNOTE_ACTIVATE(kn, 0); /* XXX - handle locking */ - if ((kn->kn_flags & EV_ONESHOT) != EV_ONESHOT) { - calloutp = (struct callout *)kn->kn_hook; - *kn->kn_ptr.p_nexttime += timer2sbintime(kn->kn_sdata, - kn->kn_sfflags); - callout_reset_sbt_on(calloutp, *kn->kn_ptr.p_nexttime, 0, - filt_timerexpire, kn, PCPU_GET(cpuid), C_ABSOLUTE); - } + if ((kn->kn_flags & EV_ONESHOT) != 0) + return; + + kc = kn->kn_ptr.p_v; + kc->next += kc->to; + callout_reset_sbt_on(&kc->c, kc->next, 0, filt_timerexpire, kn, + PCPU_GET(cpuid), C_ABSOLUTE); } /* @@ -636,16 +642,16 @@ filt_timerexpire(void *knx) static int filt_timerattach(struct knote *kn) { - struct callout *calloutp; + struct kq_timer_cb_data *kc; sbintime_t to; unsigned int ncallouts; - if ((intptr_t)kn->kn_sdata < 0) + if (kn->kn_sdata < 0) return (EINVAL); - if ((intptr_t)kn->kn_sdata == 0 && (kn->kn_flags & EV_ONESHOT) == 0) + if (kn->kn_sdata == 0 && (kn->kn_flags & EV_ONESHOT) == 0) kn->kn_sdata = 1; /* Only precision unit are supported in flags so far */ - if (kn->kn_sfflags & ~NOTE_TIMER_PRECMASK) + if ((kn->kn_sfflags & ~NOTE_TIMER_PRECMASK) != 0) return (EINVAL); to = timer2sbintime(kn->kn_sdata, kn->kn_sfflags); @@ -660,13 +666,12 @@ filt_timerattach(struct knote *kn) kn->kn_flags |= EV_CLEAR; /* automatically set */ kn->kn_status &= ~KN_DETACHED; /* knlist_add clears it */ - kn->kn_ptr.p_nexttime = malloc(sizeof(sbintime_t), M_KQUEUE, M_WAITOK); - calloutp = malloc(sizeof(*calloutp), M_KQUEUE, M_WAITOK); - callout_init(calloutp, CALLOUT_MPSAFE); - kn->kn_hook = calloutp; - *kn->kn_ptr.p_nexttime = to + sbinuptime(); - callout_reset_sbt_on(calloutp, *kn->kn_ptr.p_nexttime, 0, - filt_timerexpire, kn, PCPU_GET(cpuid), C_ABSOLUTE); + kn->kn_ptr.p_v = kc = malloc(sizeof(*kc), M_KQUEUE, M_WAITOK); + callout_init(&kc->c, 1); + kc->next = to + sbinuptime(); + kc->to = to; + callout_reset_sbt_on(&kc->c, kc->next, 0, filt_timerexpire, kn, + PCPU_GET(cpuid), C_ABSOLUTE); return (0); } @@ -674,13 +679,12 @@ filt_timerattach(struct knote *kn) static void filt_timerdetach(struct knote *kn) { - struct callout *calloutp; + struct kq_timer_cb_data *kc; unsigned int old; - calloutp = (struct callout *)kn->kn_hook; - callout_drain(calloutp); - free(calloutp, M_KQUEUE); - free(kn->kn_ptr.p_nexttime, M_KQUEUE); + kc = kn->kn_ptr.p_v; + callout_drain(&kc->c); + free(kc, M_KQUEUE); old = atomic_fetchadd_int(&kq_ncallouts, -1); KASSERT(old > 0, ("Number of callouts cannot become negative")); kn->kn_status |= KN_DETACHED; /* knlist_remove sets it */ |