From nobody@FreeBSD.org  Mon Aug 19 08:29:20 2002
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 9EF9137B400
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 19 Aug 2002 08:29:20 -0700 (PDT)
Received: from www.freebsd.org (www.FreeBSD.org [216.136.204.117])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 6140E43E6A
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 19 Aug 2002 08:29:20 -0700 (PDT)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.12.4/8.12.4) with ESMTP id g7JFTKOT066377
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 19 Aug 2002 08:29:20 -0700 (PDT)
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.12.4/8.12.4/Submit) id g7JFTKSe066376;
	Mon, 19 Aug 2002 08:29:20 -0700 (PDT)
Message-Id: <200208191529.g7JFTKSe066376@www.freebsd.org>
Date: Mon, 19 Aug 2002 08:29:20 -0700 (PDT)
From: Kevin Martin <sigma@pair.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: clock_getres returns tv_nsec=0 when TSC is 1Ghz or faster
X-Send-Pr-Version: www-1.0

>Number:         41781
>Category:       kern
>Synopsis:       clock_getres returns tv_nsec=0 when TSC is 1Ghz or faster
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Aug 19 08:30:02 PDT 2002
>Closed-Date:    Tue Oct 01 01:02:04 PDT 2002
>Last-Modified:  Tue Oct 01 01:02:04 PDT 2002
>Originator:     Kevin Martin
>Release:        4.6-STABLE
>Organization:
pair Networks, Inc
>Environment:
FreeBSD vondu.pair.com 4.6-STABLE FreeBSD 4.6-STABLE #12: Mon Aug 19 10:08:01 GMT 2002     sigma@vondu.pair.com:/usr/src/sys/compile/PAIRa  i386

>Description:
When the the TSC timer is 1Ghz or faster:
Timecounter "TSC"  frequency 1002275326 Hz
kern/kern_time.c handles clock_getres by dividing this value into
1000000000L.  The integer result is unfortunately zero.  Programs
which expect a useful result are disappointed.  For example, PGP uses
this value and divides by it, promptly dumping core.
>How-To-Repeat:
#include <sys/time.h>
#include <stdio.h>

main()
{
  struct timespec res;

  clock_getres(CLOCK_REALTIME, &res);
  printf("%u\n",(unsigned)res.tv_nsec);
}


gcc -o test test.c
./test

>Fix:
I believe the best solution is to return a minimum value of one
nanosecond, since the worst you've done is tell the calling program
that the timer is less precise than it is.  Does POSIX have anything
to say?  I don't know.

>Release-Note:
>Audit-Trail:

From: Bruce Evans <bde@zeta.org.au>
To: Kevin Martin <sigma@pair.com>
Cc: freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: kern/41781: clock_getres returns tv_nsec=0 when TSC is 1Ghz or
 faster
Date: Tue, 20 Aug 2002 09:41:31 +1000 (EST)

 On Mon, 19 Aug 2002, Kevin Martin wrote:
 
 > >Description:
 > When the the TSC timer is 1Ghz or faster:
 > Timecounter "TSC"  frequency 1002275326 Hz
 > kern/kern_time.c handles clock_getres by dividing this value into
 > 1000000000L.  The integer result is unfortunately zero.  Programs
 > which expect a useful result are disappointed.  For example, PGP uses
 > this value and divides by it, promptly dumping core.
 
 I just wrote the following untested fix for this.
 
 %%%
 Index: kern_time.c
 ===================================================================
 RCS file: /home/ncvs/src/sys/kern/kern_time.c,v
 retrieving revision 1.84
 diff -u -2 -r1.84 kern_time.c
 --- kern_time.c	18 Aug 2002 21:24:22 -0000	1.84
 +++ kern_time.c	19 Aug 2002 20:45:17 -0000
 @@ -215,5 +209,10 @@
  	if (SCARG(uap, tp)) {
  		ts.tv_sec = 0;
 -		ts.tv_nsec = 1000000000 / tc_getfrequency();
 +		/*
 +		 * Round up the result of the division cheaply by adding 1.
 +		 * Rounding up is especially important if rounding down
 +		 * would give 0.  Perfect rounding is unimportant.
 +		 */
 +		ts.tv_nsec = 1000000000 / tc_getfrequency() + 1;
  		error = copyout(&ts, SCARG(uap, tp), sizeof(ts));
  	}
 %%%
 
 > >Fix:
 > I believe the best solution is to return a minimum value of one
 > nanosecond, since the worst you've done is tell the calling program
 > that the timer is less precise than it is.  Does POSIX have anything
 > to say?  I don't know.
 
 It doesn't say anything relevant, at least in POSIX.1-200x-draft7.  It
 says that clock_getres() gives the actual resolution, but this is
 clearly unimplementable if the actual resolution is less than one
 nanosecond or even if it is not an integral number of nanoseconds.
 
 Bruce
 
State-Changed-From-To: open->closed 
State-Changed-By: bde 
State-Changed-When: Tue Oct 1 01:01:02 PDT 2002 
State-Changed-Why:  
Fixed in kern_time.c revs 1.85 (-current) and 1.68.2.1 (RELENG_4). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=41781 
>Unformatted:
