Hello Wolfgang, please see comment below.
Am 17.01.2013 18:10, schrieb Wolfgang Mauerer:
For slow targets and fast hosts, the emulation may be faster than the actual hardware, which can be undesirable for various reasons. Add a run-time option to slow down the emulation by sleeping in the CPU emulation. Signed-off-by: Wolfgang Mauerer<wolfgang.maue...@siemens.com> --- cpus.c | 29 +++++++++++++++++++++++++++++ include/qemu-common.h | 2 ++ qemu-options.hx | 14 ++++++++++++++ vl.c | 10 ++++++++++ 4 files changed, 55 insertions(+), 0 deletions(-) diff --git a/cpus.c b/cpus.c index a4390c3..eae10f4 100644 --- a/cpus.c +++ b/cpus.c @@ -61,6 +61,7 @@ #endif /* CONFIG_LINUX */ static CPUArchState *next_cpu; +static bool use_slowdown = false;
"= false" is not needed. Explicit setting of static variables to their default value increases the image size and should be avoided.
static bool cpu_thread_is_idle(CPUArchState *env) { @@ -106,6 +107,8 @@ static QEMUTimer *icount_warp_timer; static int64_t vm_clock_warp_start; static int64_t qemu_icount; +static double slowdown_factor; + typedef struct TimersState { int64_t cpu_ticks_prev; int64_t cpu_ticks_offset; @@ -385,6 +388,20 @@ void configure_icount(const char *option) qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 10); } +void configure_slowdown(const char *option) +{ + if (!option) { + return; + } + + slowdown_factor = strtod(option, NULL)/100.0;
Missing blanks around "/".
+ /* We cannot provide speedups, obviously */ + if (slowdown_factor< 0) + slowdown_factor *= -1.0;
Missing {}.
+ + use_slowdown = true; +} + /***********************************************************/ void hw_error(const char *fmt, ...) { @@ -1094,6 +1111,8 @@ void vm_stop_force_state(RunState state) static int tcg_cpu_exec(CPUArchState *env) { int ret; + int64_t ss; + uint64_t slowdown_sleep; #ifdef CONFIG_PROFILER int64_t ti; #endif @@ -1114,7 +1133,17 @@ static int tcg_cpu_exec(CPUArchState *env) env->icount_decr.u16.low = decr; env->icount_extra = count; } + if (use_slowdown) { + ss = qemu_get_clock_ns(rt_clock); + } + ret = cpu_exec(env); + + if (use_slowdown) { + slowdown_sleep = qemu_get_clock_ns(rt_clock) - ss; + slowdown_sleep *= slowdown_factor; + g_usleep(slowdown_sleep/1024);
Missing blanks around "/".
+ } #ifdef CONFIG_PROFILER qemu_time += profile_getclock() - ti; #endif diff --git a/include/qemu-common.h b/include/qemu-common.h index ca464bb..652abb9 100644 --- a/include/qemu-common.h +++ b/include/qemu-common.h @@ -119,6 +119,8 @@ static inline char *realpath(const char *path, char *resolved_path) void configure_icount(const char *option); extern int use_icount; +void configure_slowdown(const char *option); + /* FIXME: Remove NEED_CPU_H. */ #ifndef NEED_CPU_H diff --git a/qemu-options.hx b/qemu-options.hx index 40cd683..d5eb5eb 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -2667,6 +2667,20 @@ order cores with complex cache hierarchies. The number of instructions executed often has little or no correlation with actual performance. ETEXI +DEF("slowdown", HAS_ARG, QEMU_OPTION_slowdown, \ + "-slowdown s \n" \
Remove blank before \n.
+ " Slow down the CPU emulation by (approximately) s percent\n", + QEMU_ARCH_ALL) +STEXI +@item -slowdown @var{s} +@findex -slowdown +Slow down the virtual CPU by approximately s percent (i.e., for c time +units of execution time, sleep for c*s/100 time units). This makes it +possible to align the emulated machine's performance roughly with +the performance of physical entities, but does not provide identical +performance profiles since the emulation is not cycle accurate. +ETEXI + DEF("watchdog", HAS_ARG, QEMU_OPTION_watchdog, \ "-watchdog i6300esb|ib700\n" \ " enable virtual hardware watchdog [default=none]\n", diff --git a/vl.c b/vl.c index 8ce2b10..9aa44e0 100644 --- a/vl.c +++ b/vl.c @@ -2713,6 +2713,7 @@ int main(int argc, char **argv, char **envp) int i; int snapshot, linux_boot; const char *icount_option = NULL; + const char *slowdown_option = NULL; const char *initrd_filename; const char *kernel_filename, *kernel_cmdline; char boot_devices[33] = ""; @@ -3607,6 +3608,9 @@ int main(int argc, char **argv, char **envp) case QEMU_OPTION_icount: icount_option = optarg; break; + case QEMU_OPTION_slowdown: + slowdown_option = optarg; + break; case QEMU_OPTION_incoming: incoming = optarg; runstate_set(RUN_STATE_INMIGRATE); @@ -3970,6 +3974,12 @@ int main(int argc, char **argv, char **envp) /* clean up network at qemu process termination */ atexit(&net_cleanup); + if (slowdown_option&& (kvm_enabled() || xen_enabled())) { + fprintf(stderr, "-slowdown is not allowed with kvm or xen\n"); + exit(1); + } + configure_slowdown(slowdown_option); + if (net_init_clients()< 0) { exit(1); }
Please test your patch using scripts/checkpatch.pl before sending it. Kind regards, Stefan Weil