Some optimizations for kqueue timers.
There is no need to do two allocations per kqueue timer. Gather all data needed by the timer callout into the structure and allocate it at once. Use the structure to preserve the result of timer2sbintime(), to not perform repeated 64bit calculations in callout. Remove tautological casts. Remove now unused p_nexttime [1]. Noted by: markj [1] Reviewed by: markj (previous version) Sponsored by: The FreeBSD Foundation MFC after: 1 week X-MFC note: do not remove p_nexttime Differential revision: https://reviews.freebsd.org/D8901
This commit is contained in:
parent
bc7c5848fe
commit
5da38b3b08
@ -631,23 +631,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);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -656,16 +662,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);
|
||||
@ -680,13 +686,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, 1);
|
||||
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);
|
||||
}
|
||||
@ -694,13 +699,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 */
|
||||
|
@ -231,7 +231,6 @@ struct knote {
|
||||
struct proc *p_proc; /* proc pointer */
|
||||
struct kaiocb *p_aio; /* AIO job pointer */
|
||||
struct aioliojob *p_lio; /* LIO job pointer */
|
||||
sbintime_t *p_nexttime; /* next timer event fires at */
|
||||
void *p_v; /* generic other pointer */
|
||||
} kn_ptr;
|
||||
struct filterops *kn_fop;
|
||||
|
Loading…
Reference in New Issue
Block a user