On 12/04/2017 11:51, [email protected] wrote:
> + int current_irq_coalesced = s->irq_coalesced;
> +
> + s->irq_coalesced = (current_irq_coalesced * s->period) / period;
> +
> + /*
> + * calculate the lost clock after it is scaled which should be
> + * compensated in the next interrupt.
> + */
> + lost_clock += current_irq_coalesced * s->period -
> + s->irq_coalesced * period;
This is:
lost_clock = current_irq_coalesced * s->period -
(current_irq_coalesced * s->period) / period * period;
i.e.
/* When switching from a shorter to a longer period, scale down the
* missing ticks since we expect the OS handler to treat the delayed
* ticks as longer. Any leftovers are put back into next_irq_clock.
*
* When switching to a shorter period, scale up the missing ticks
* since we expect the OS handler to treat the delayed ticks as
* shorter.
*/
lost_clock = (s->irq_coalesced * s->period) % period;
s->irq_coalesced = (s->irq_coalesced * s->period) / period;
Is this correct?
Paolo
> + DPRINTF_C("cmos: coalesced irqs scaled from %d to %d, %ld clocks
> "
> + "are compensated.\n",
> + current_irq_coalesced, s->irq_coalesced, lost_clock);
> }
> s->period = period;
> #endif
> @@ -170,7 +193,7 @@ static void periodic_timer_update(RTCState *s, int64_t
> current_time)
> cur_clock =
> muldiv64(current_time, RTC_CLOCK_RATE, NANOSECONDS_PER_SECOND);
>
> - next_irq_clock = (cur_clock & ~(period - 1)) + period;
> + next_irq_clock = cur_clock + period - lost_clock;
> s->next_periodic_time = muldiv64(next_irq_clock,
> NANOSECONDS_PER_SECOND,
> RTC_CLOCK_RATE) + 1;
> timer_mod(s->periodic_timer, s->next_periodic_time);
> --