From owner-svn-src-all@FreeBSD.ORG Fri Jul 18 14:27:05 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id ADF563EE; Fri, 18 Jul 2014 14:27:05 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 8EB4B2A1D; Fri, 18 Jul 2014 14:27:05 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s6IER5uG096793; Fri, 18 Jul 2014 14:27:05 GMT (envelope-from bapt@svn.freebsd.org) Received: (from bapt@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s6IER4dE096790; Fri, 18 Jul 2014 14:27:04 GMT (envelope-from bapt@svn.freebsd.org) Message-Id: <201407181427.s6IER4dE096790@svn.freebsd.org> From: Baptiste Daroussin Date: Fri, 18 Jul 2014 14:27:04 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r268843 - in head: lib/libc/sys sys/kern sys/sys X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 18 Jul 2014 14:27:05 -0000 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;