time bug

Stephen Weeks MLton@sourcelight.com
Mon, 26 Mar 2001 12:40:40 -0800 (PST)


> I think I've squashed the Time bug.  Turns out there were really three
> different bugs that were all contributing to the exceptions.
> 
> 1. src/runtime/gc.c 
> 
> I don't know if this is really a bug, but currentTime() now uses times()
> instead of getrusage(). 

Here's what Henry said earlier.

> I looked at the code in the kernel, and the getruasage() system call and
> the times() system call read the same variables.

So, I doubt that was the problem.  But I like it better that we use times()
everywhere.  I rewrote currentTime slightly to use CLK_TCK.

/* return time as number of milliseconds */
static uint currentTime() {
	struct tms tms;
	uint result;

	times(&tms);
	result = tms.tms_utime + tms.tms_stime + tms.tms_cutime + tms.tms_cstime;
	result = result * 1000 / CLK_TCK;
	return result;
}


> 2. src/lib/mlton/basic/times.{sig,sml}
>    src/mlton/control/control.sml
...
> I updated /src/lib/mlton/basic/times.{sig,fun} with timesPre and
> timesPost, and bound times to timesPre for compatibility.

Makes sense.  Another solution would be to have a single routine that returns
times, like:

   val MLton.ProcEnv.times: unit -> {elapsed: Time.time,
				     cstime: Time.time,
				     cutime: Time.time,
				     gc: Time.time,
				     stime: Time.time,
				     utime: Time.time}

> 3. src/basis-library/posix/proc-env.sml
>    src/basis-library/mlton/gc.sml
> 
> There are rounding differences in converting from the C function times() 
> values to Time.time values for the Posix.ProcEnv.times call and the
> MLton.GC.time call: 
...
> 
> I modified Posix.ProcEnv.times to use Time.fromMilliseconds rather
> than Time.fromReal. 

Makes sense.

> It seems to me that the
> modification I made might still lead to discrepencies, but I haven't
> seen any; whereas, with the alterative modification, I see them a lot.

I changed Posix.ProcEnv.times in the same way as I did currentTime so that it
uses CLK_TCK.

	 val ticksPerSecond: LargeInt.int =
	    SysWord.toLargeInt (sysconf "CLK_TCK")

	 val millisecondsPerSecond: LargeInt.int = 1000
	    
	 fun cvt (ticks: int): Time.time =
	    Time.fromMilliseconds
	    (LargeInt.div
	     (LargeInt.fromInt ticks * millisecondsPerSecond,
	      ticksPerSecond))

Given this fix, I don't think there can be any rounding error (and hence
discrepancies) as long as the number of ticks per millisecond is an integer.

Thanks for all the bug fixes.