TIMER: Fix sim_timer_activate_after to avoid overflow

The conversion of time to instructions can overflow an int32 when the
current instructions per second is high and the delay interval is high.

We limit the instruction delay to the maximum value available in an int32,
which for essentially all cases won't matter since the resulting delay is used
for a drop dead timeout and doesn't need to be precise or it will be
canceled before it ever fires anyway.
This commit is contained in:
Mark Pizzolato 2015-11-13 08:28:20 -08:00
parent 636b8c9dec
commit 4a1cf3587f

View file

@ -1452,14 +1452,19 @@ return inst_per_sec;
t_stat sim_timer_activate_after (UNIT *uptr, int32 usec_delay)
{
int32 inst_delay;
double inst_per_sec;
int inst_delay;
double inst_delay_d, inst_per_sec;
AIO_VALIDATE;
if (sim_is_active (uptr)) /* already active? */
return SCPE_OK;
inst_per_sec = sim_timer_inst_per_sec ();
inst_delay = (int32)((inst_per_sec*usec_delay)/1000000.0);
inst_delay_d = ((inst_per_sec*usec_delay)/1000000.0);
/* Bound delay to avoid overflow. */
/* Long delays are usually canceled before they expire */
if (inst_delay_d > (double)0x7fffffff)
inst_delay_d = (double)0x7fffffff;
inst_delay = (int32)inst_delay_d;
#if defined(SIM_ASYNCH_IO) && defined(SIM_ASYNCH_CLOCKS)
if ((sim_calb_tmr == -1) || /* if No timer initialized */
(inst_delay < rtc_currd[sim_calb_tmr]) || /* or sooner than next clock tick? */