Author: kib
Date: Thu Dec 18 11:30:51 2014
New Revision: 275899
URL: https://svnweb.freebsd.org/changeset/base/275899

Log:
  MFC r268843 (by bapt):
  Extend kqueue's EVFILT_TIMER by adding precision unit flags support.

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

Modified: stable/10/lib/libc/sys/kqueue.2
==============================================================================
--- stable/10/lib/libc/sys/kqueue.2     Thu Dec 18 11:10:15 2014        
(r275898)
+++ stable/10/lib/libc/sys/kqueue.2     Thu Dec 18 11:30:51 2014        
(r275899)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd January 21, 2013
+.Dd July 18, 2014
 .Dt KQUEUE 2
 .Os
 .Sh NAME
@@ -436,7 +436,7 @@ Establishes an arbitrary timer identifie
 .Va ident .
 When adding a timer,
 .Va data
-specifies the timeout period in milliseconds.
+specifies the timeout period.
 The timer will be periodic unless EV_ONESHOT is specified.
 On return,
 .Va data
@@ -447,8 +447,25 @@ There is a system wide limit on the numb
 which is controlled by the
 .Va kern.kq_calloutmax
 sysctl.
+.Bl -tag -width XXNOTE_USECONDS
+.It Dv NOTE_SECONDS
+.Va data
+is in seconds.
+.It Dv NOTE_MSECONDS
+.Va data
+is in milliseconds.
+.It Dv NOTE_USECONDS
+.Va data
+is in microseconds.
+.It Dv NOTE_NSECONDS
+.Va data
+is in nanoseconds.
+.It
+.El
 .Pp
-On return,
+If
+.Va fflags
+is not set, the default is milliseconds. On return,
 .Va fflags
 contains the events which triggered the filter.
 .It Dv EVFILT_USER

Modified: stable/10/sys/kern/kern_event.c
==============================================================================
--- stable/10/sys/kern/kern_event.c     Thu Dec 18 11:10:15 2014        
(r275898)
+++ stable/10/sys/kern/kern_event.c     Thu Dec 18 11:30:51 2014        
(r275899)
@@ -522,15 +522,38 @@ knote_fork(struct knlist *list, int pid)
  * XXX: EVFILT_TIMER should perhaps live in kern_time.c beside the
  * interval timer support code.
  */
+
+#define NOTE_TIMER_PRECMASK    (NOTE_SECONDS|NOTE_MSECONDS|NOTE_USECONDS| \
+                               NOTE_NSECONDS)
+
 static __inline sbintime_t
-timer2sbintime(intptr_t data)
+timer2sbintime(intptr_t data, int flags)
 {
+       sbintime_t modifier;
+
+       switch (flags & NOTE_TIMER_PRECMASK) {
+       case NOTE_SECONDS:
+               modifier = SBT_1S;
+               break;
+       case NOTE_MSECONDS: /* FALLTHROUGH */
+       case 0:
+               modifier = SBT_1MS;
+               break;
+       case NOTE_USECONDS:
+               modifier = SBT_1US;
+               break;
+       case NOTE_NSECONDS:
+               modifier = SBT_1NS;
+               break;
+       default:
+               return (-1);
+       }
 
 #ifdef __LP64__
-       if (data > INT64_MAX / SBT_1MS)
-               return INT64_MAX;
+       if (data > SBT_MAX / modifier)
+               return (SBT_MAX);
 #endif
-       return (SBT_1MS * data);
+       return (modifier * data);
 }
 
 static void
@@ -545,14 +568,15 @@ filt_timerexpire(void *knx)
 
        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_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);
        }
 }
 
 /*
- * data contains amount of time to sleep, in milliseconds
+ * data contains amount of time to sleep
  */
 static int
 filt_timerattach(struct knote *kn)
@@ -565,7 +589,11 @@ filt_timerattach(struct knote *kn)
                return (EINVAL);
        if ((intptr_t)kn->kn_sdata == 0 && (kn->kn_flags & EV_ONESHOT) == 0)
                kn->kn_sdata = 1;
-       to = timer2sbintime(kn->kn_sdata);
+       /* Only precision unit are supported in flags so far */
+       if (kn->kn_sfflags & ~NOTE_TIMER_PRECMASK)
+               return (EINVAL);
+
+       to = timer2sbintime(kn->kn_sdata, kn->kn_sfflags);
        if (to < 0)
                return (EINVAL);
 

Modified: stable/10/sys/sys/event.h
==============================================================================
--- stable/10/sys/sys/event.h   Thu Dec 18 11:10:15 2014        (r275898)
+++ stable/10/sys/sys/event.h   Thu Dec 18 11:30:51 2014        (r275899)
@@ -132,6 +132,12 @@ struct kevent {
 #define        NOTE_TRACKERR   0x00000002              /* could not track 
child */
 #define        NOTE_CHILD      0x00000004              /* am a child process */
 
+/* additional flags for EVFILE_TIMER */
+#define NOTE_SECONDS           0x00000001      /* data is seconds */
+#define NOTE_MSECONDS          0x00000002      /* data is milliseconds */
+#define NOTE_USECONDS          0x00000004      /* data is microseconds */
+#define NOTE_NSECONDS          0x00000008      /* data is nanoseconds */
+
 struct knote;
 SLIST_HEAD(klist, knote);
 struct kqueue;
_______________________________________________
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