summaryrefslogtreecommitdiff
path: root/exec.c
diff options
context:
space:
mode:
authoraurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162>2009-03-07 21:28:24 +0000
committeraurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162>2009-03-07 21:28:24 +0000
commit3098dba01c7daab60762b6f6624ea88c0d6cb65a (patch)
treea77ed1b45c1228d3fa7486de9f3d64885682c0d7 /exec.c
parent9e995645b54de7aa77c0b56c9507a2153e81f92f (diff)
downloadqemu-3098dba01c7daab60762b6f6624ea88c0d6cb65a.tar.gz
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.c56
1 files changed, 32 insertions, 24 deletions
diff --git a/exec.c b/exec.c
index 01a5265df8..c6490ff074 100644
--- a/exec.c
+++ b/exec.c
@@ -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" },