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:
parent
636b8c9dec
commit
4a1cf3587f
1 changed files with 8 additions and 3 deletions
11
sim_timer.c
11
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? */
|
||||
|
|
Loading…
Add table
Reference in a new issue