diff options
author | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2009-03-07 21:28:24 +0000 |
---|---|---|
committer | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2009-03-07 21:28:24 +0000 |
commit | 3098dba01c7daab60762b6f6624ea88c0d6cb65a (patch) | |
tree | a77ed1b45c1228d3fa7486de9f3d64885682c0d7 /exec.c | |
parent | 9e995645b54de7aa77c0b56c9507a2153e81f92f (diff) |
Use a dedicated function to request exit from execution loop
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6762 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'exec.c')
-rw-r--r-- | exec.c | 56 |
1 files changed, 32 insertions, 24 deletions
@@ -523,7 +523,9 @@ static int cpu_common_load(QEMUFile *f, void *opaque, int version_id) qemu_get_be32s(f, &env->halted); qemu_get_be32s(f, &env->interrupt_request); - env->interrupt_request &= ~CPU_INTERRUPT_EXIT; + /* 0x01 was CPU_INTERRUPT_EXIT. This line can be removed when the + version_id is increased. */ + env->interrupt_request &= ~0x01; tlb_flush(env, 1); return 0; @@ -1499,28 +1501,36 @@ void cpu_set_log_filename(const char *filename) cpu_set_log(loglevel); } -/* mask must never be zero, except for A20 change call */ -void cpu_interrupt(CPUState *env, int mask) +static void cpu_unlink_tb(CPUState *env) { -#if !defined(USE_NPTL) +#if defined(USE_NPTL) + /* FIXME: TB unchaining isn't SMP safe. For now just ignore the + problem and hope the cpu will stop of its own accord. For userspace + emulation this often isn't actually as bad as it sounds. Often + signals are used primarily to interrupt blocking syscalls. */ +#else TranslationBlock *tb; static spinlock_t interrupt_lock = SPIN_LOCK_UNLOCKED; -#endif - int old_mask; - if (mask & CPU_INTERRUPT_EXIT) { - env->exit_request = 1; - mask &= ~CPU_INTERRUPT_EXIT; + tb = env->current_tb; + /* if the cpu is currently executing code, we must unlink it and + all the potentially executing TB */ + if (tb && !testandset(&interrupt_lock)) { + env->current_tb = NULL; + tb_reset_jump_recursive(tb); + resetlock(&interrupt_lock); } +#endif +} + +/* mask must never be zero, except for A20 change call */ +void cpu_interrupt(CPUState *env, int mask) +{ + int old_mask; old_mask = env->interrupt_request; env->interrupt_request |= mask; -#if defined(USE_NPTL) - /* FIXME: TB unchaining isn't SMP safe. For now just ignore the - problem and hope the cpu will stop of its own accord. For userspace - emulation this often isn't actually as bad as it sounds. Often - signals are used primarily to interrupt blocking syscalls. */ -#else + if (use_icount) { env->icount_decr.u16.high = 0xffff; #ifndef CONFIG_USER_ONLY @@ -1530,16 +1540,8 @@ void cpu_interrupt(CPUState *env, int mask) } #endif } else { - tb = env->current_tb; - /* if the cpu is currently executing code, we must unlink it and - all the potentially executing TB */ - if (tb && !testandset(&interrupt_lock)) { - env->current_tb = NULL; - tb_reset_jump_recursive(tb); - resetlock(&interrupt_lock); - } + cpu_unlink_tb(env); } -#endif } void cpu_reset_interrupt(CPUState *env, int mask) @@ -1547,6 +1549,12 @@ void cpu_reset_interrupt(CPUState *env, int mask) env->interrupt_request &= ~mask; } +void cpu_exit(CPUState *env) +{ + env->exit_request = 1; + cpu_unlink_tb(env); +} + const CPULogItem cpu_log_items[] = { { CPU_LOG_TB_OUT_ASM, "out_asm", "show generated host assembly code for each compiled TB" }, |