MFC r268843 (by bapt):
Extend kqueue's EVFILT_TIMER by adding precision unit flags support.
This commit is contained in:
parent
3abf5d53d8
commit
9f63b4b4d8
@ -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 identified by
|
||||
.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 number of timers
|
||||
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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user