Subject: kern/2788: if tick is not integral, corrections can be disruptive
To: None <gnats-bugs@gnats.netbsd.org>
From: None <dennis@jnx.com>
List: netbsd-bugs
Date: 09/28/1996 18:55:57
>Number:         2788
>Category:       kern
>Synopsis:       if tick is not integral, corrections can be disruptive
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sat Sep 28 19:05:00 1996
>Last-Modified:
>Originator:     Dennis Ferguson
>Organization:
	Juniper Networks, Inc.
>Release:        1.2_ALPHA
>Environment:
	Any machine where 1000000/hz is non-integral
System: NetBSD skank.jnx.com 1.2_ALPHA NetBSD 1.2_ALPHA (SKANKLIKE) #5: Sat Sep 28 14:34:02 PDT 1996 dennis@skank.jnx.com:/usr/src/sys/arch/i386/compile/SKANKLIKE i386


>Description:
	In kern/kern_clock.c the code which adjusts time to account for
	1000000/hz being non-integral looks like the following:

        if (tickfix) {
                tickfixcnt++;
                if (tickfixcnt >= tickfixinterval) { 
                        delta += tickfix;
                        tickfixcnt = 0; 
                }
	}

	On an alpha for example, where hz == 1024, tickfix ends up being
	9 and tickfixinterval ends up being 16, so the end result of the
	above is that the time gets adjusted forward by 9 microseconds
	on every 16th clock interrupt.

	This is not incorrect, but it causes detectable bumps in time if
	you are trying to use the machine to do fine timing, and is
	unnecessary since it costs very little more to limit increments
	to 1 per clock interrupt.

>How-To-Repeat:
	Try to make precise time measurements on a machine with hz == 1024,
	or hz==60.  Note that some times are 10 microseconds larger than
	others for no good reason.
>Fix:
	The following patch changes how tick fixes are applied, limiting
	adjustments to 1 microsecond per clock interrupt.  It does add
	the constraint that tickfix must be greater than zero, though
	this should have no practical consequence.

*** kern_clock.c	1996/09/29 01:08:58	1.2
--- kern_clock.c	1996/09/29 01:23:18
***************
*** 283,289 ****
  int	psratio;			/* ratio: prof / stat */
  int	tickfix, tickfixinterval;	/* used if tick not really integral */
  #ifndef NTP
! static int tickfixcnt;			/* number of ticks since last fix */
  #else
  int	fixtick;			/* used by NTP for same */
  int	shifthz;
--- 283,289 ----
  int	psratio;			/* ratio: prof / stat */
  int	tickfix, tickfixinterval;	/* used if tick not really integral */
  #ifndef NTP
! static int tickfixcnt;			/* accumulated fractional error */
  #else
  int	fixtick;			/* used by NTP for same */
  int	shifthz;
***************
*** 410,419 ****
  
  #ifndef NTP
  	if (tickfix) {
! 		tickfixcnt++;
  		if (tickfixcnt >= tickfixinterval) {
! 			delta += tickfix;
! 			tickfixcnt = 0;
  		}
  	}
  #endif /* !NTP */
--- 410,419 ----
  
  #ifndef NTP
  	if (tickfix) {
! 		tickfixcnt += tickfix;
  		if (tickfixcnt >= tickfixinterval) {
! 			delta++;
! 			tickfixcnt -= tickfixinterval;
  		}
  	}
  #endif /* !NTP */
>Audit-Trail:
>Unformatted: