summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2014-12-18 11:30:51 +0000
committerkib <kib@FreeBSD.org>2014-12-18 11:30:51 +0000
commit9f63b4b4d88d2e073f6c78989f8168c996d76ba7 (patch)
tree3c19f68edb62437de79cf5213befc685e705b5fa /sys/kern
parent3abf5d53d81ee69ddbaeabfdfe7a6eb8a7c1d1d5 (diff)
downloadFreeBSD-src-9f63b4b4d88d2e073f6c78989f8168c996d76ba7.zip
FreeBSD-src-9f63b4b4d88d2e073f6c78989f8168c996d76ba7.tar.gz
MFC r268843 (by bapt):
Extend kqueue's EVFILT_TIMER by adding precision unit flags support.
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_event.c42
1 files changed, 35 insertions, 7 deletions
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index e70a9cf..9650965 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -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);
OpenPOWER on IntegriCloud