Index: sys/sys/event.h =================================================================== --- sys/sys/event.h (revision 268627) +++ sys/sys/event.h (working copy) @@ -133,6 +133,13 @@ #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 */ +#define NOTE_PRECISION_MASK 0x0000000F /* mask for the precision flags */ + struct knote; SLIST_HEAD(klist, knote); struct kqueue; Index: sys/kern/kern_event.c =================================================================== --- sys/kern/kern_event.c (revision 268627) +++ sys/kern/kern_event.c (working copy) @@ -524,14 +524,33 @@ * interval timer support code. */ static __inline sbintime_t -timer2sbintime(intptr_t data) +timer2sbintime(intptr_t data, int flags) { + sbintime_t modifier; + switch (flags & NOTE_PRECISION_MASK) { + 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 +566,13 @@ 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 +585,11 @@ 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_PRECISION_MASK) + return (EINVAL); + + to = timer2sbintime(kn->kn_sdata, kn->kn_sfflags); if (to < 0) return (EINVAL); @@ -583,7 +606,7 @@ 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);