1
0
mirror of https://github.com/simh/simh.git synced 2026-05-20 11:12:40 +00:00

TIMER: Fix various inconsistent timing behaviors

- Support for arbitrary long wait intervals in sim_activate_after with
   precisely correct delays aligned with the calibrated clock once
   per second.
- Proper handling of calls to sim_cancel for calibrated timer units
- Properly allow stopping of calibrated clock by calling sim_rtcn_calb
   with a ticksper == 0
- Only schedule asynchronous timer activities for delays longer than
   the minimal OS sleep time
- Only wake asynchronous timer thread to queue new timer events
   that are shorter than the currently shortest scheduled event
This commit is contained in:
Mark Pizzolato
2016-12-26 12:42:25 -08:00
parent 257738a4e0
commit aa82b57d10
4 changed files with 151 additions and 67 deletions

22
scp.c
View File

@@ -4722,7 +4722,7 @@ else {
}
else
fprintf (st, " Unknown");
tim = sim_fmt_secs((accum + uptr->time)/sim_timer_inst_per_sec ());
tim = sim_fmt_secs(((accum + uptr->time) / sim_timer_inst_per_sec ()) + (uptr->usecs_remaining / 1000000.0));
fprintf (st, " at %d%s%s%s%s\n", accum + uptr->time,
(*tim) ? " (" : "", tim, (*tim) ? ")" : "",
(uptr->flags & UNIT_IDLE) ? " (Idle capable)" : "");
@@ -8914,10 +8914,14 @@ do {
sim_interval = noqueue_time = NOQUEUE_WAIT;
sim_debug (SIM_DBG_EVENT, sim_dflt_dev, "Processing Event for %s\n", sim_uname (uptr));
AIO_EVENT_BEGIN(uptr);
if (uptr->action != NULL)
reason = uptr->action (uptr);
else
reason = SCPE_OK;
if (uptr->usecs_remaining)
reason = sim_timer_activate_after_d (uptr, uptr->usecs_remaining);
else {
if (uptr->action != NULL)
reason = uptr->action (uptr);
else
reason = SCPE_OK;
}
AIO_EVENT_COMPLETE(uptr, reason);
} while ((reason == SCPE_OK) &&
(sim_interval <= 0) &&
@@ -9078,6 +9082,8 @@ UNIT *cptr, *nptr;
AIO_VALIDATE;
if ((uptr->cancel) && uptr->cancel (uptr))
return SCPE_OK;
if (uptr->dynflags & UNIT_TMR_UNIT)
sim_timer_cancel (uptr);
AIO_CANCEL(uptr);
AIO_UPDATE_QUEUE;
if (sim_clock_queue == QUEUE_LIST_END)
@@ -9146,9 +9152,9 @@ UNIT *cptr;
int32 accum;
AIO_VALIDATE;
accum = sim_timer_activate_time (uptr); \
if (accum >= 0) \
return accum; \
accum = sim_timer_activate_time (uptr);
if (accum >= 0)
return accum;
accum = 0;
for (cptr = sim_clock_queue; cptr != QUEUE_LIST_END; cptr = cptr->next) {
if (cptr == sim_clock_queue) {