[PATCH 1/4] sim: Allow an overdue event to be descheduled
Sebastian Huber <[email protected]>
| Newsgroups | gmane.comp.gdb.patches |
|---|---|
| Message-ID | <[email protected]> |
sim_events_deschedule() asserted that a non-empty event queue implies a non-negative time from event. That is not an invariant. sim_events_slip() decrements the time from event unconditionally, so the time can pass an event which is still queued. update_time_from_event() then computes a negative time from event for the head of the queue, which is overdue rather than pending. The next tick raises the pending work flag and sim_events_process() consumes it, so nothing is lost. An event handler which deschedules another overdue event triggers the assertion. The MIPS jmr3904 board reaches this with two timers running: they queue events for the same time, a branch delay slot slips the time past both, and the handler of the first deschedules the second. Assert only the direction which holds: an empty queue gives a negative time from event. Signed-off-by: Sebastian Huber <[email protected]> --- sim/common/sim-events.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sim/common/sim-events.c b/sim/common/sim-events.c index f87f133efc3..e908c40f764 100644 --- a/sim/common/sim-events.c +++ b/sim/common/sim-events.c @@ -852,7 +852,11 @@ sim_events_deschedule (SIM_DESC sd, (dead->trace != NULL) ? dead->trace : "")); sim_events_free (sd, dead); update_time_from_event (sd); - SIM_ASSERT ((events->time_from_event >= 0) == (events->queue != NULL)); + /* sim_events_slip() advances the time past an event + which is still queued. The head of the queue is then + overdue rather than pending. */ + SIM_ASSERT (events->queue != NULL + || events->time_from_event < 0); return; } } -- 2.51.0