Author: kib
Date: Sun Jan  1 11:19:17 2017
New Revision: 311007
URL: https://svnweb.freebsd.org/changeset/base/311007

Log:
  MFC r310554:
  Some optimizations for kqueue timers.

Modified:
  stable/11/sys/kern/kern_event.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/kern/kern_event.c
==============================================================================
--- stable/11/sys/kern/kern_event.c     Sun Jan  1 11:09:51 2017        
(r311006)
+++ stable/11/sys/kern/kern_event.c     Sun Jan  1 11:19:17 2017        
(r311007)
@@ -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 */
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to