svn commit: r268843 - in head: lib/libc/sys sys/kern sys/sys

Baptiste Daroussin bapt at FreeBSD.org
Fri Jul 18 14:27:05 UTC 2014


Author: bapt
Date: Fri Jul 18 14:27:04 2014
New Revision: 268843
URL: http://svnweb.freebsd.org/changeset/base/268843

Log:
  Extend kqueue's EVFILT_TIMER by adding precision unit flags support
  
  Define the precision macros as bits sets to conform with XNU equivalent.
  Test fflags passed for EVFILT_TIMER and return EINVAL in case an invalid flag
  is passed.
  
  Phabric:	https://phabric.freebsd.org/D421
  Reviewed by:	kib

Modified:
  head/lib/libc/sys/kqueue.2
  head/sys/kern/kern_event.c
  head/sys/sys/event.h

Modified: head/lib/libc/sys/kqueue.2
==============================================================================
--- head/lib/libc/sys/kqueue.2	Fri Jul 18 12:51:35 2014	(r268842)
+++ head/lib/libc/sys/kqueue.2	Fri Jul 18 14:27:04 2014	(r268843)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd April 7, 2014
+.Dd July 18, 2014
 .Dt KQUEUE 2
 .Os
 .Sh NAME
@@ -454,7 +454,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
@@ -465,8 +465,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: head/sys/kern/kern_event.c
==============================================================================
--- head/sys/kern/kern_event.c	Fri Jul 18 12:51:35 2014	(r268842)
+++ head/sys/kern/kern_event.c	Fri Jul 18 14:27:04 2014	(r268843)
@@ -523,15 +523,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 > SBT_MAX / SBT_1MS)
+	if (data > SBT_MAX / modifier)
 		return (SBT_MAX);
 #endif
-	return (SBT_1MS * data);
+	return (modifier * data);
 }
 
 static void
@@ -547,13 +570,13 @@ 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? */,
+		    timer2sbintime(kn->kn_sdata, kn->kn_sfflags), 0,
 		    filt_timerexpire, kn, PCPU_GET(cpuid), 0);
 	}
 }
 
 /*
- * data contains amount of time to sleep, in milliseconds
+ * data contains amount of time to sleep
  */
 static int
 filt_timerattach(struct knote *kn)
@@ -566,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);
 
@@ -583,7 +610,7 @@ filt_timerattach(struct knote *kn)
 	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? */,
+	callout_reset_sbt_on(calloutp, to, 0,
 	    filt_timerexpire, kn, PCPU_GET(cpuid), 0);
 
 	return (0);

Modified: head/sys/sys/event.h
==============================================================================
--- head/sys/sys/event.h	Fri Jul 18 12:51:35 2014	(r268842)
+++ head/sys/sys/event.h	Fri Jul 18 14:27:04 2014	(r268843)
@@ -133,6 +133,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;


More information about the svn-src-head mailing list