From 4a1cf3587f93dd92a073c508ccda9c7e260d172a Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Fri, 13 Nov 2015 08:28:20 -0800 Subject: [PATCH] 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. --- sim_timer.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/sim_timer.c b/sim_timer.c index bff008b7..1e5afff7 100644 --- a/sim_timer.c +++ b/sim_timer.c @@ -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? */