diff options
author | kib <kib@FreeBSD.org> | 2014-12-18 11:30:51 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2014-12-18 11:30:51 +0000 |
commit | 9f63b4b4d88d2e073f6c78989f8168c996d76ba7 (patch) | |
tree | 3c19f68edb62437de79cf5213befc685e705b5fa /sys/kern | |
parent | 3abf5d53d81ee69ddbaeabfdfe7a6eb8a7c1d1d5 (diff) | |
download | FreeBSD-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.c | 42 |
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); |