[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

get-internal-real-time bug



Executing this under KCL:

	(dotimes (i 1000)
	  (time (sleep 100)))

produces the output

	real time:   100.033
	real time:   100.400
	. . .
	real time:   -71482.770
	real time:   100.017
	real time:   100.000
	. . .
	real time:   -71482.750
	real time:   100.017
	real time:   100.000
	. . .

The problem is in unixtime.c:

Lget_internal_real_time()
{
#ifdef BSD
	struct timeb buf;

	check_arg(0);
	ftime(&buf);
	vs_push(make_fixnum(((buf.time-beginning.time)*1000+
			     (buf.millitm-beginning.millitm))*60/1000));
#endif

#ifdef ATT
	....
}

The number of seconds is effectively multiplied by 60000
in the expression.  This overflows a 32-bit integer
about every 9 hours.  The exact behavior on overflow,
of course, depends on the machine.  A simple fix is to do this:

	vs_push(make_fixnum((buf.time - beginning.time) * 60 +
			    (buf.millitm - beginning.millitm)*60/1000));

increasing the safe period to about 400 days (but with a slightly
different rounding behavior).

However, since the variable "beginning" is initialized when
raw_kcl starts, it's still possible to catch a 400-day-old
lisp image at a bad time, but I'll save that for another bug fix.