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.