kern/78787: sysconf(_SC_CLK_TCK) may return incorrect value

Anonymous swell.k at gmail.com
Thu Jan 6 13:00:25 UTC 2011


The following reply was made to PR kern/78787; it has been noted by GNATS.

From: Anonymous <swell.k at gmail.com>
To: Pete French <petefrench at ticketswitch.com>
Cc: bug-followup at FreeBSD.org
Subject: Re: kern/78787: sysconf(_SC_CLK_TCK) may return incorrect value
Date: Thu, 06 Jan 2011 15:52:08 +0300

 The patch below borrows code from NetBSD and partially solves the issue.
 It does not address all bde's concerns though
 
    http://docs.freebsd.org/cgi/mid.cgi?20020701142849.U6692-100000
 
 Also, on my amd64 box stathz != 128
 
   kern.clockrate: { hz = 1000, tick = 1000, profhz = 8126, stathz = 127 }
 
 --- a.diff begins here ---
 Index: include/time.h
 ===================================================================
 --- include/time.h	(revision 216514)
 +++ include/time.h	(working copy)
 @@ -50,8 +50,12 @@
   * Frequency of the clock ticks reported by times().  Deprecated - use
   * sysconf(_SC_CLK_TCK) instead.  (Removed in 1003.1-2001.)
   */
 -#define	CLK_TCK		128
 +#ifndef __lint
 +__weak_reference(sysconf, __sysconf);
 +long __sysconf(int);
  #endif
 +#define	CLK_TCK		(__sysconf(3))
 +#endif
  
  /* Frequency of the clock ticks reported by clock().  */
  #define	CLOCKS_PER_SEC	128
 Index: lib/libc/gen/sysconf.c
 ===================================================================
 --- lib/libc/gen/sysconf.c	(revision 216473)
 +++ lib/libc/gen/sysconf.c	(working copy)
 @@ -75,6 +75,8 @@ sysconf(name)
  	int mib[2], sverrno, value;
  	long lvalue, defaultresult;
  	const char *path;
 +	struct clockinfo tmpclock;
 +	static int clk_tck;
  
  	defaultresult = -1;
  
 @@ -94,7 +96,21 @@ sysconf(name)
  		}
  		return ((long)rl.rlim_cur);
  	case _SC_CLK_TCK:
 -		return (CLK_TCK);
 +		/*
 +		 * Has to be handled specially because it returns a
 +		 * struct clockinfo instead of an integer. Also, since
 +		 * this might be called often by some things that
 +		 * don't grok CLK_TCK can be a macro expanding to a
 +		 * function, cache the value.
 +		 */
 +		if (clk_tck == 0) {
 +			mib[0] = CTL_KERN;
 +			mib[1] = KERN_CLOCKRATE;
 +			len = sizeof(struct clockinfo);
 +			clk_tck = sysctl(mib, 2, &tmpclock, &len, NULL, 0)
 +			    == -1 ? -1 : tmpclock.stathz;
 +		}
 +		return(clk_tck);
  	case _SC_NGROUPS_MAX:
  		mib[0] = CTL_KERN;
  		mib[1] = KERN_NGROUPS;
 Index: usr.sbin/timed/timed/timed.c
 ===================================================================
 --- usr.sbin/timed/timed/timed.c	(revision 216514)
 +++ usr.sbin/timed/timed/timed.c	(working copy)
 @@ -759,7 +759,8 @@
  	int force;
  {
  # define NG_DELAY (30*60*CLK_TCK)	/* 30 minutes */
 -	static unsigned long last_update = -NG_DELAY;
 +	static unsigned long last_update;
 +	static int firsttime;
  	unsigned long new_update;
  	struct goodhost *ghp, **ghpp;
  #ifdef HAVENIS
 @@ -768,6 +769,10 @@
  #endif /* HAVENIS */
  	struct tms tm;
  
 +	if (firsttime == 0) {
 +		last_update = -NG_DELAY;
 +		firsttime++;
 +	}
  
  	/* if no netgroup, then we are finished */
  	if (goodgroup == 0 || !Mflag)
 --- a.diff ends here ---


More information about the freebsd-bugs mailing list