Bug in Process.times?

After repeatedly getting user+system times that are longer than real
time by a constant factor (on a single, non hyper-threading processor),
I thought I would inspect the code for Process.times at ruby-doc.org.

It shows:
#ifndef HZ

ifdef CLK_TCK

define HZ CLK_TCK

else

define HZ 60

endif

#endif /* HZ */

Unfortunately on several versions of Linux I have tried, including the
latest Fedora and Ubuntu, this seems to give a HZ value of 60 rather
than the correct 100, from “getconf CLK_TCK”. (I haven’t looked any
further into the Ruby source to examine other places the constants may
be set.)

If I correct for this, my benchmark times now make complete sense with
real time closely approximating user+system times on a lightly loaded
system.

Is this a bug or have I overlooked something?

Hi,

At Thu, 6 Jul 2006 08:59:02 +0900,
Robert Joseph Sheehan wrote in [ruby-talk:200293]:

Is this a bug or have I overlooked something?
Seems a bug.

Index: configure.in

RCS file: /cvs/ruby/src/ruby/configure.in,v
retrieving revision 1.304
diff -p -u -2 -r1.304 configure.in
— configure.in 1 Jul 2006 16:40:13 -0000 1.304
+++ configure.in 6 Jul 2006 02:26:37 -0000
@@ -511,5 +511,5 @@ AC_CHECK_FUNCS(fmod killpg wait4 waitpid
setrgid setegid setregid setresgid issetugid pause lchown
lchmod
getpgrp setpgrp getpgid setpgid initgroups getgroups setgroups\

  •     getpriority getrlimit setrlimit\
    
  •     getpriority getrlimit setrlimit sysconf\
        dlopen sigprocmask sigaction _setjmp vsnprintf snprintf\
        setsid telldir seekdir fchmod mktime timegm cosh sinh tanh log2\
    

@@ -729,4 +729,20 @@ if test $rb_cv_huge_st_ino = yes; then
fi

+if test “$ac_cv_func_sysconf” = yes; then

  • AC_DEFUN(RUBY_CHECK_SYSCONF, [dnl
  • AC_CACHE_CHECK([whether SC$1 is supported],
    rb_cv_have_sc_[]m4_tolower($1),
  • [AC_TRY_COMPILE([#include <unistd.h>
  •  ],
    
  •  [_SC_$1 >= 0],
    
  •  rb_cv_have_sc_[]m4_tolower($1)=yes,
    
  •  rb_cv_have_sc_[]m4_tolower($1)=no)
    
  • ])
  • if test “$rb_cv_have_sc_[]m4_tolower($1)” = yes; then
  • AC_DEFINE(HAVE__SC_$1)
  • fi
  • ])
  • RUBY_CHECK_SYSCONF(CLK_TCK)
    +fi

case “$target_cpu” in
m68*|i?86|ia64|sparc*|alpha*) rb_cv_stack_grow_dir=-1;;
Index: process.c

RCS file: /cvs/ruby/src/ruby/process.c,v
retrieving revision 1.145
diff -p -u -2 -r1.145 process.c
— process.c 15 Jun 2006 06:43:17 -0000 1.145
+++ process.c 6 Jul 2006 02:33:23 -0000
@@ -3517,4 +3517,8 @@ rb_proc_times(VALUE obj)
{
#if defined(HAVE_TIMES) && !defined(CHECKER)

  • const double hz =
    +#ifdef HAVE__SC_CLK_TCK
  • (double)sysconf(_SC_CLK_TCK);
    +#else
    #ifndef HZ

ifdef CLK_TCK

@@ -3524,4 +3528,6 @@ rb_proc_times(VALUE obj)

endif

#endif /* HZ */

  • HZ;
    +#endif
    struct tms buf;
    volatile VALUE utime, stime, cutime, sctime;
    @@ -3529,8 +3535,8 @@ rb_proc_times(VALUE obj)
    times(&buf);
    return rb_struct_new(S_Tms,
  •   	 utime = rb_float_new((double)buf.tms_utime / HZ),
    
  •   	 stime = rb_float_new((double)buf.tms_stime / HZ),
    
  •   	 cutime = rb_float_new((double)buf.tms_cutime / HZ),
    
  •   	 sctime = rb_float_new((double)buf.tms_cstime / HZ));
    
  •   	 utime = rb_float_new(buf.tms_utime / hz),
    
  •   	 stime = rb_float_new(buf.tms_stime / hz),
    
  •   	 cutime = rb_float_new(buf.tms_cutime / hz),
    
  •   	 sctime = rb_float_new(buf.tms_cstime / hz));
    

#else
rb_notimplement();

[email protected] wrote:

Index: configure.in

  •   getpriority getrlimit setrlimit sysconf\
    
  •  [_SC_$1 >= 0],
    

case “$target_cpu” in
#if defined(HAVE_TIMES) && !defined(CHECKER)
+#endif

  • 	 stime = rb_float_new(buf.tms_stime / hz),
    
  • 	 cutime = rb_float_new(buf.tms_cutime / hz),
    
  • 	 sctime = rb_float_new(buf.tms_cstime / hz));
    

#else
rb_notimplement();

Shouldn’t we try sysconf(CLOCKS_PER_SEC) if _SC_CLK_TCK isn’t defined
first?

  • Dan

Hi,

At Thu, 6 Jul 2006 12:17:30 +0900,
Daniel B. wrote in [ruby-talk:200298]:

Shouldn’t we try sysconf(CLOCKS_PER_SEC) if _SC_CLK_TCK isn’t defined first?

Shouldn’t. CLOCKS_PER_SEC isn’t concerned with CLK_TCK, and
you can’t use it as the argument to sysconf().

Hi,

In message “Re: bug in Process.times?”
on Thu, 6 Jul 2006 11:46:15 +0900, [email protected] writes:

|> Is this a bug or have I overlooked something?
|
|Seems a bug.

Can you commit the patch?

						matz.