Subject: kern/2496: wrong process times for long running processes
To: None <gnats-bugs@NetBSD.ORG>
From: Brian Baird <brb@exp.com>
List: netbsd-bugs
Date: 05/31/1996 19:55:55
>Number:         2496
>Category:       kern
>Synopsis:       wrong process times for long running processes
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri May 31 23:20:02 1996
>Last-Modified:
>Originator:     Brian Baird
>Organization:
Brian Baird				Exponential Technology, San Jose CA
brb@exp.com				+1 408 467 4418
>Release:        1.1
>Environment:
System: NetBSD tardis.exp.com 1.1 NetBSD 1.1 (EXP) #0: Wed Mar 27 11:46:50 PST 1996 brb@fs3:/usr/src/sys/arch/i386/compile/EXP i386

>Description:
	Some of our long running simulations cause an overflow in
	calcru() that causes the user and system time returned by
	wait3(2) to be incorrect.  In this particular case, a
	simulation had run for 110000 real time seconds (about 30
	hours) and had accumulated over 106000 user cpu seconds.
	/bin/time however, reported about 9000 seconds of user cpu
	time.  The problem is a 32 bit overflow in calcru() when
	calculating the process's total microseconds of run time.

	The same code still exists in NetBSD-current.

>How-To-Repeat:
	Run any program under /bin/time that takes more than about
	4295 seconds of real time.
>Fix:
	A one-line change to calcru() in /sys/kern/kern_resource.c:

$ diff -c kern_resource.c.11 kern_resource.c
*** kern_resource.c.11     Fri Oct 13 19:41:16 1995
--- kern_resource.c     Fri May 31 17:45:09 1996
***************
*** 365,371 ****
                sec += tv.tv_sec - runtime.tv_sec;
                usec += tv.tv_usec - runtime.tv_usec;
        }
!       u = sec * 1000000 + usec;
        st = (u * st) / tot;
        sp->tv_sec = st / 1000000;
        sp->tv_usec = st % 1000000;
--- 365,371 ----
                sec += tv.tv_sec - runtime.tv_sec;
                usec += tv.tv_usec - runtime.tv_usec;
        }
!       u = (u_quad_t)sec * 1000000 + usec;
        st = (u * st) / tot;
        sp->tv_sec = st / 1000000;
        sp->tv_usec = st % 1000000;
>Audit-Trail:
>Unformatted: