Sebastian Tanase <sebastian.tan...@openwide.fr> wrote: > The goal is to sleep qemu whenever the guest clock > is in advance compared to the host clock (we use > the monotonic clocks). The amount of time to sleep > is calculated in the execution loop in cpu_exec. > > Basically, using QEMU_CLOCK_REALTIME, we calculate > the real time duration of the execution (meaning > generating TBs and executing them) and using the > the fields icount_decr.u16.low and icount_extra > (from the CPUState structure) shifted by icount_time_shift > we calculate the theoretical virtual time elapsed. > Having these 2 values, we can determine if the > guest is in advance and sleep. > > Signed-off-by: Sebastian Tanase <sebastian.tan...@openwide.fr> > Tested-by: Camille Bégué <camille.be...@openwide.fr>
... > @@ -209,6 +210,26 @@ static void cpu_handle_debug_exception(CPUArchState *env) > } > } > > +/* Allow the guest to have a max 300us advance. > + * The difference between the 2 clocks could therefore > + * oscillate around 0. > + */ > +#define VM_CLOCK_ADVANCE 300000 > + > +static int64_t diff_clk; make this local to cpu_exec? > +static void delay_host(void) > +{ and static int64_t delay_host(int64_t diff_clk) > + static struct timespec sleep_delay, rem_delay; > + sleep_delay.tv_sec = diff_clk / 1000000000LL; > + sleep_delay.tv_nsec = diff_clk % 1000000000LL; > + if (nanosleep(&sleep_delay, &rem_delay) < 0) { > + diff_clk -= (sleep_delay.tv_sec - rem_delay.tv_sec) * 1000000000LL; > + diff_clk -= sleep_delay.tv_nsec - rem_delay.tv_nsec; > + } else { > + diff_clk = 0; > + } > +} > + > @@ -600,6 +633,11 @@ int cpu_exec(CPUArchState *env) > } > } > if (unlikely(cpu->exit_request)) { > + if (icount_align_option) { > + if (diff_clk > VM_CLOCK_ADVANCE) { > + delay_host(); > + } > + } > cpu->exit_request = 0; > cpu->exception_index = EXCP_INTERRUPT; > cpu_loop_exit(cpu); I would move the if (diff_clk > VM_CLOCK_ADVANCE) test inside delay_host(), but that is just personal style and taste. Later, Juan.