[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [RFC PATCH 3/4] cpu_exec: Add sleeping algorithm
From: |
Juan Quintela |
Subject: |
Re: [Qemu-devel] [RFC PATCH 3/4] cpu_exec: Add sleeping algorithm |
Date: |
Wed, 28 May 2014 11:35:25 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) |
Sebastian Tanase <address@hidden> 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 <address@hidden>
> Tested-by: Camille Bégué <address@hidden>
...
> @@ -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.
[Qemu-devel] [RFC PATCH 4/4] cpu_exec: Print to console if the guest is late, Sebastian Tanase, 2014/05/27
[Qemu-devel] [RFC PATCH 1/4] icount: Add 'align' and 'icount' options, Sebastian Tanase, 2014/05/27