Author: ian
Date: Sun Oct 26 18:46:03 2014
New Revision: 273705
URL: https://svnweb.freebsd.org/changeset/base/273705

Log:
  MFC r272528:  Make kevent(2) periodic timer events more reliably periodic.

Modified:
  stable/10/sys/kern/kern_event.c
  stable/10/sys/sys/event.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/kern/kern_event.c
==============================================================================
--- stable/10/sys/kern/kern_event.c     Sun Oct 26 18:41:01 2014        
(r273704)
+++ stable/10/sys/kern/kern_event.c     Sun Oct 26 18:46:03 2014        
(r273705)
@@ -541,9 +541,9 @@ filt_timerexpire(void *knx)
 
        if ((kn->kn_flags & EV_ONESHOT) != EV_ONESHOT) {
                calloutp = (struct callout *)kn->kn_hook;
-               callout_reset_sbt_on(calloutp,
-                   timer2sbintime(kn->kn_sdata), 0 /* 1ms? */,
-                   filt_timerexpire, kn, PCPU_GET(cpuid), 0);
+               *kn->kn_ptr.p_nexttime += timer2sbintime(kn->kn_sdata);
+               callout_reset_sbt_on(calloutp, *kn->kn_ptr.p_nexttime, 0,
+                   filt_timerexpire, kn, PCPU_GET(cpuid), C_ABSOLUTE);
        }
 }
 
@@ -575,11 +575,13 @@ 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;
-       callout_reset_sbt_on(calloutp, to, 0 /* 1ms? */,
-           filt_timerexpire, kn, PCPU_GET(cpuid), 0);
+       *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);
 
        return (0);
 }
@@ -593,6 +595,7 @@ filt_timerdetach(struct knote *kn)
        calloutp = (struct callout *)kn->kn_hook;
        callout_drain(calloutp);
        free(calloutp, M_KQUEUE);
+       free(kn->kn_ptr.p_nexttime, M_KQUEUE);
        old = atomic_fetch_sub_explicit(&kq_ncallouts, 1, memory_order_relaxed);
        KASSERT(old > 0, ("Number of callouts cannot become negative"));
        kn->kn_status |= KN_DETACHED;   /* knlist_remove sets it */

Modified: stable/10/sys/sys/event.h
==============================================================================
--- stable/10/sys/sys/event.h   Sun Oct 26 18:41:01 2014        (r273704)
+++ stable/10/sys/sys/event.h   Sun Oct 26 18:46:03 2014        (r273705)
@@ -214,6 +214,7 @@ struct knote {
                struct          proc *p_proc;   /* proc pointer */
                struct          aiocblist *p_aio;       /* AIO job pointer */
                struct          aioliojob *p_lio;       /* LIO job pointer */ 
+               sbintime_t      *p_nexttime;    /* next timer event fires at */
        } kn_ptr;
        struct                  filterops *kn_fop;
        void                    *kn_hook;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to