From owner-svn-src-stable-10@freebsd.org Fri Dec 16 23:42:50 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 91E31C838A9; Fri, 16 Dec 2016 23:42:50 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::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 472D5C82; Fri, 16 Dec 2016 23:42:50 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id uBGNgnTa055952; Fri, 16 Dec 2016 23:42:49 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id uBGNgnYK055951; Fri, 16 Dec 2016 23:42:49 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201612162342.uBGNgnYK055951@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Fri, 16 Dec 2016 23:42:49 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r310183 - stable/10/sys/kern X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 16 Dec 2016 23:42:50 -0000 Author: kib Date: Fri Dec 16 23:42:49 2016 New Revision: 310183 URL: https://svnweb.freebsd.org/changeset/base/310183 Log: MFC r296775 (by gibbs): Provide high precision conversion from ns,us,ms -> sbintime in kevent. Tested by: ian Modified: stable/10/sys/kern/kern_event.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/kern/kern_event.c ============================================================================== --- stable/10/sys/kern/kern_event.c Fri Dec 16 23:33:37 2016 (r310182) +++ stable/10/sys/kern/kern_event.c Fri Dec 16 23:42:49 2016 (r310183) @@ -556,34 +556,59 @@ knote_fork(struct knlist *list, int pid) #define NOTE_TIMER_PRECMASK (NOTE_SECONDS|NOTE_MSECONDS|NOTE_USECONDS| \ NOTE_NSECONDS) -static __inline sbintime_t +static sbintime_t timer2sbintime(intptr_t data, int flags) { - sbintime_t modifier; + /* + * Macros for converting to the fractional second portion of an + * sbintime_t using 64bit multiplication to improve precision. + */ +#define NS_TO_SBT(ns) (((ns) * (((uint64_t)1 << 63) / 500000000)) >> 32) +#define US_TO_SBT(us) (((us) * (((uint64_t)1 << 63) / 500000)) >> 32) +#define MS_TO_SBT(ms) (((ms) * (((uint64_t)1 << 63) / 500)) >> 32) switch (flags & NOTE_TIMER_PRECMASK) { case NOTE_SECONDS: - modifier = SBT_1S; - break; +#ifdef __LP64__ + if (data > (SBT_MAX / SBT_1S)) + return SBT_MAX; +#endif + return ((sbintime_t)data << 32); case NOTE_MSECONDS: /* FALLTHROUGH */ case 0: - modifier = SBT_1MS; - break; + if (data >= 1000) { + int64_t secs = data / 1000; +#ifdef __LP64__ + if (secs > (SBT_MAX / SBT_1S)) + return SBT_MAX; +#endif + return (secs << 32 | MS_TO_SBT(data % 1000)); + } + return MS_TO_SBT(data); case NOTE_USECONDS: - modifier = SBT_1US; - break; + if (data >= 1000000) { + int64_t secs = data / 1000000; +#ifdef __LP64__ + if (secs > (SBT_MAX / SBT_1S)) + return SBT_MAX; +#endif + return (secs << 32 | US_TO_SBT(data % 1000000)); + } + return US_TO_SBT(data); case NOTE_NSECONDS: - modifier = SBT_1NS; - break; - default: - return (-1); - } - + if (data >= 1000000000) { + int64_t secs = data / 1000000000; #ifdef __LP64__ - if (data > SBT_MAX / modifier) - return (SBT_MAX); + if (secs > (SBT_MAX / SBT_1S)) + return SBT_MAX; #endif - return (modifier * data); + return (secs << 32 | US_TO_SBT(data % 1000000000)); + } + return NS_TO_SBT(data); + default: + break; + } + return (-1); } static void