mirror of https://github.com/xqemu/xqemu.git
cpu-exec: remove outermost infinite loop
Reorganize the sigsetjmp so that the restart case falls through to cpu_handle_exception and the execution loop. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
a42cf3f3f2
commit
4515e58d60
58
cpu-exec.c
58
cpu-exec.c
|
@ -624,41 +624,37 @@ int cpu_exec(CPUState *cpu)
|
||||||
*/
|
*/
|
||||||
init_delay_params(&sc, cpu);
|
init_delay_params(&sc, cpu);
|
||||||
|
|
||||||
for(;;) {
|
/* prepare setjmp context for exception handling */
|
||||||
/* prepare setjmp context for exception handling */
|
if (sigsetjmp(cpu->jmp_env, 0) != 0) {
|
||||||
if (sigsetjmp(cpu->jmp_env, 0) == 0) {
|
|
||||||
/* if an exception is pending, we execute it here */
|
|
||||||
while (!cpu_handle_exception(cpu, &ret)) {
|
|
||||||
TranslationBlock *last_tb = NULL;
|
|
||||||
int tb_exit = 0;
|
|
||||||
|
|
||||||
while (!cpu_handle_interrupt(cpu, &last_tb)) {
|
|
||||||
TranslationBlock *tb = tb_find(cpu, last_tb, tb_exit);
|
|
||||||
cpu_loop_exec_tb(cpu, tb, &last_tb, &tb_exit, &sc);
|
|
||||||
/* Try to align the host and virtual clocks
|
|
||||||
if the guest is in advance */
|
|
||||||
align_clocks(&sc, cpu);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
#if defined(__clang__) || !QEMU_GNUC_PREREQ(4, 6)
|
#if defined(__clang__) || !QEMU_GNUC_PREREQ(4, 6)
|
||||||
/* Some compilers wrongly smash all local variables after
|
/* Some compilers wrongly smash all local variables after
|
||||||
* siglongjmp. There were bug reports for gcc 4.5.0 and clang.
|
* siglongjmp. There were bug reports for gcc 4.5.0 and clang.
|
||||||
* Reload essential local variables here for those compilers.
|
* Reload essential local variables here for those compilers.
|
||||||
* Newer versions of gcc would complain about this code (-Wclobbered). */
|
* Newer versions of gcc would complain about this code (-Wclobbered). */
|
||||||
cpu = current_cpu;
|
cpu = current_cpu;
|
||||||
cc = CPU_GET_CLASS(cpu);
|
cc = CPU_GET_CLASS(cpu);
|
||||||
#else /* buggy compiler */
|
#else /* buggy compiler */
|
||||||
/* Assert that the compiler does not smash local variables. */
|
/* Assert that the compiler does not smash local variables. */
|
||||||
g_assert(cpu == current_cpu);
|
g_assert(cpu == current_cpu);
|
||||||
g_assert(cc == CPU_GET_CLASS(cpu));
|
g_assert(cc == CPU_GET_CLASS(cpu));
|
||||||
#endif /* buggy compiler */
|
#endif /* buggy compiler */
|
||||||
cpu->can_do_io = 1;
|
cpu->can_do_io = 1;
|
||||||
tb_lock_reset();
|
tb_lock_reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if an exception is pending, we execute it here */
|
||||||
|
while (!cpu_handle_exception(cpu, &ret)) {
|
||||||
|
TranslationBlock *last_tb = NULL;
|
||||||
|
int tb_exit = 0;
|
||||||
|
|
||||||
|
while (!cpu_handle_interrupt(cpu, &last_tb)) {
|
||||||
|
TranslationBlock *tb = tb_find(cpu, last_tb, tb_exit);
|
||||||
|
cpu_loop_exec_tb(cpu, tb, &last_tb, &tb_exit, &sc);
|
||||||
|
/* Try to align the host and virtual clocks
|
||||||
|
if the guest is in advance */
|
||||||
|
align_clocks(&sc, cpu);
|
||||||
}
|
}
|
||||||
} /* for(;;) */
|
}
|
||||||
|
|
||||||
cc->cpu_exec_exit(cpu);
|
cc->cpu_exec_exit(cpu);
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
Loading…
Reference in New Issue