]> git.proxmox.com Git - qemu.git/commitdiff
Use a dedicated function to request exit from execution loop
authoraurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162>
Sat, 7 Mar 2009 21:28:24 +0000 (21:28 +0000)
committeraurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162>
Sat, 7 Mar 2009 21:28:24 +0000 (21:28 +0000)
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6762 c046a42c-6fe2-441c-8c8c-71466251a162

cpu-all.h
darwin-user/signal.c
exec.c
gdbstub.c
hw/dma.c
hw/mac_dbdma.c
linux-user/main.c
linux-user/signal.c
vl.c

index e0c3efd5571f800b7ad8961c03214aebf0aa0240..366f47e5bb61ce192c9555cea141f3c9c4a8db4d 100644 (file)
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -760,7 +760,6 @@ extern CPUState *cpu_single_env;
 extern int64_t qemu_icount;
 extern int use_icount;
 
-#define CPU_INTERRUPT_EXIT   0x01 /* wants exit from main loop */
 #define CPU_INTERRUPT_HARD   0x02 /* hardware interrupt pending */
 #define CPU_INTERRUPT_EXITTB 0x04 /* exit the current TB (use for x86 a20 case) */
 #define CPU_INTERRUPT_TIMER  0x08 /* internal timer exception pending */
@@ -774,6 +773,8 @@ extern int use_icount;
 void cpu_interrupt(CPUState *s, int mask);
 void cpu_reset_interrupt(CPUState *env, int mask);
 
+void cpu_exit(CPUState *s);
+
 /* Breakpoint/watchpoint flags */
 #define BP_MEM_READ           0x01
 #define BP_MEM_WRITE          0x02
index ba41c2e61a9806eee041622df9b15e515c3a9530..851e85b60f5f69fb5c64d55e0c2cad6f6fb091d3 100644 (file)
@@ -215,7 +215,7 @@ static void host_signal_handler(int host_signum, siginfo_t *info,
 #endif
     if (queue_signal(sig, &tinfo) == 1) {
         /* interrupt the virtual CPU as soon as possible */
-        cpu_interrupt(global_env, CPU_INTERRUPT_EXIT);
+        cpu_exit(global_env);
     }
 }
 
diff --git a/exec.c b/exec.c
index 01a5265df832b69d352d241e24d612f7ea661023..c6490ff0747162eca49ae50994a5bd116c98e26e 100644 (file)
--- 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" },
index d54976612f95505bf4a563e515fd937a628a9bbb..addff2ee7a2ba453a2b756e18399c1d7f2438209 100644 (file)
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2012,7 +2012,7 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
 #ifdef CONFIG_USER_ONLY
     gdb_handlesig(s->c_cpu, 0);
 #else
-    cpu_interrupt(s->c_cpu, CPU_INTERRUPT_EXIT);
+    cpu_exit(s->c_cpu);
 #endif
 }
 
index e58ab6dd2382d72fb4b98f4b94f3bf8edf13e971..971c8d466fd62e0dd81513f8be5f8eaa5eff7c40 100644 (file)
--- a/hw/dma.c
+++ b/hw/dma.c
@@ -449,7 +449,7 @@ void DMA_schedule(int nchan)
 {
     CPUState *env = cpu_single_env;
     if (env)
-        cpu_interrupt(env, CPU_INTERRUPT_EXIT);
+        cpu_exit(env);
 }
 
 static void dma_reset(void *opaque)
index 8e82a2356cb109127d1b57ec98f67b35c65699c3..b8e4b128d420fa73221bd8a51ed332bc80f5ae94 100644 (file)
@@ -653,7 +653,7 @@ void DBDMA_schedule(void)
 {
     CPUState *env = cpu_single_env;
     if (env)
-        cpu_interrupt(env, CPU_INTERRUPT_EXIT);
+        cpu_exit(env);
 }
 
 static void
index 2c1e4df6e5b8197e07c9b822d3ee6fe6e0ddfc0b..feb30361705355e6356ea41a19ec84c3de1be681 100644 (file)
@@ -200,7 +200,7 @@ static inline void start_exclusive(void)
     for (other = first_cpu; other; other = other->next_cpu) {
         if (other->running) {
             pending_cpus++;
-            cpu_interrupt(other, CPU_INTERRUPT_EXIT);
+            cpu_exit(other);
         }
     }
     if (pending_cpus > 1) {
index 48640ec835af256c55cf5458b504f327d27ba79d..fc37dc11ffd58494ad9bc1291998b33e1dea3ab4 100644 (file)
@@ -460,7 +460,7 @@ static void host_signal_handler(int host_signum, siginfo_t *info,
     host_to_target_siginfo_noswap(&tinfo, info);
     if (queue_signal(thread_env, sig, &tinfo) == 1) {
         /* interrupt the virtual CPU as soon as possible */
-        cpu_interrupt(thread_env, CPU_INTERRUPT_EXIT);
+        cpu_exit(thread_env);
     }
 }
 
diff --git a/vl.c b/vl.c
index 62a9194614a6ea6766d4ae30fec36140dd30cd06..39423bb4d69dc1e8c6b54bb068aeb8b07bf1948d 100644 (file)
--- a/vl.c
+++ b/vl.c
@@ -1181,7 +1181,7 @@ void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
         }
         /* Interrupt execution to force deadline recalculation.  */
         if (use_icount && cpu_single_env) {
-            cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
+            cpu_exit(cpu_single_env);
         }
     }
 }
@@ -1348,7 +1348,7 @@ static void host_alarm_handler(int host_signum)
 
         if (env) {
             /* stop the currently executing cpu because a timer occured */
-            cpu_interrupt(env, CPU_INTERRUPT_EXIT);
+            cpu_exit(env);
 #ifdef USE_KQEMU
             if (env->kqemu_enabled) {
                 kqemu_cpu_interrupt(env);
@@ -3326,7 +3326,7 @@ void qemu_service_io(void)
 {
     CPUState *env = cpu_single_env;
     if (env) {
-        cpu_interrupt(env, CPU_INTERRUPT_EXIT);
+        cpu_exit(env);
 #ifdef USE_KQEMU
         if (env->kqemu_enabled) {
             kqemu_cpu_interrupt(env);
@@ -3407,7 +3407,7 @@ void qemu_bh_schedule(QEMUBH *bh)
     bh->idle = 0;
     /* stop the currently executing CPU to execute the BH ASAP */
     if (env) {
-        cpu_interrupt(env, CPU_INTERRUPT_EXIT);
+        cpu_exit(env);
     }
 }
 
@@ -3618,21 +3618,21 @@ void qemu_system_reset_request(void)
         reset_requested = 1;
     }
     if (cpu_single_env)
-        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
+        cpu_exit(cpu_single_env);
 }
 
 void qemu_system_shutdown_request(void)
 {
     shutdown_requested = 1;
     if (cpu_single_env)
-        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
+        cpu_exit(cpu_single_env);
 }
 
 void qemu_system_powerdown_request(void)
 {
     powerdown_requested = 1;
     if (cpu_single_env)
-        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
+        cpu_exit(cpu_single_env);
 }
 
 #ifdef _WIN32