]> git.proxmox.com Git - qemu.git/blobdiff - cpus.c
nbd: Haiku has _IO() in its BSD compatibility layer
[qemu.git] / cpus.c
diff --git a/cpus.c b/cpus.c
index af87007d48ee9a6ecb0d843f799072cd322004d0..b09f5e3b508d2300f69a1c220eb495a06726c463 100644 (file)
--- a/cpus.c
+++ b/cpus.c
@@ -30,6 +30,7 @@
 #include "gdbstub.h"
 #include "dma.h"
 #include "kvm.h"
+#include "exec-all.h"
 
 #include "cpus.h"
 
@@ -39,7 +40,6 @@
 #define SIG_IPI SIGUSR1
 #endif
 
-static CPUState *cur_cpu;
 static CPUState *next_cpu;
 
 /***********************************************************/
@@ -91,6 +91,11 @@ void cpu_synchronize_all_post_init(void)
     }
 }
 
+int cpu_is_stopped(CPUState *env)
+{
+    return !vm_running || env->stopped;
+}
+
 static void do_vm_stop(int reason)
 {
     if (vm_running) {
@@ -126,7 +131,7 @@ static int cpu_has_work(CPUState *env)
     return 0;
 }
 
-static int tcg_has_work(void)
+static int any_cpu_has_work(void)
 {
     CPUState *env;
 
@@ -136,13 +141,20 @@ static int tcg_has_work(void)
     return 0;
 }
 
+static void cpu_debug_handler(CPUState *env)
+{
+    gdb_set_stop_cpu(env);
+    debug_requested = EXCP_DEBUG;
+    vm_stop(EXCP_DEBUG);
+}
+
 #ifndef _WIN32
 static int io_thread_fd = -1;
 
 static void qemu_event_increment(void)
 {
     /* Write 8 bytes to be compatible with eventfd.  */
-    static uint64_t val = 1;
+    static const uint64_t val = 1;
     ssize_t ret;
 
     if (io_thread_fd == -1)
@@ -231,6 +243,8 @@ static void qemu_event_increment(void)
 #ifndef CONFIG_IOTHREAD
 int qemu_init_main_loop(void)
 {
+    cpu_set_debug_excp_handler(cpu_debug_handler);
+
     return qemu_event_init();
 }
 
@@ -313,19 +327,22 @@ static QemuCond qemu_system_cond;
 static QemuCond qemu_pause_cond;
 static QemuCond qemu_work_cond;
 
-static void tcg_block_io_signals(void);
-static void kvm_block_io_signals(CPUState *env);
+static void tcg_init_ipi(void);
+static void kvm_init_ipi(CPUState *env);
 static void unblock_io_signals(void);
 
 int qemu_init_main_loop(void)
 {
     int ret;
 
+    cpu_set_debug_excp_handler(cpu_debug_handler);
+
     ret = qemu_event_init();
     if (ret)
         return ret;
 
     qemu_cond_init(&qemu_pause_cond);
+    qemu_cond_init(&qemu_system_cond);
     qemu_mutex_init(&qemu_fair_mutex);
     qemu_mutex_init(&qemu_global_mutex);
     qemu_mutex_lock(&qemu_global_mutex);
@@ -396,10 +413,12 @@ static void qemu_wait_io_event_common(CPUState *env)
     flush_queued_work(env);
 }
 
-static void qemu_wait_io_event(CPUState *env)
+static void qemu_tcg_wait_io_event(void)
 {
-    while (!tcg_has_work())
-        qemu_cond_timedwait(env->halt_cond, &qemu_global_mutex, 1000);
+    CPUState *env;
+
+    while (!any_cpu_has_work())
+        qemu_cond_timedwait(tcg_halt_cond, &qemu_global_mutex, 1000);
 
     qemu_mutex_unlock(&qemu_global_mutex);
 
@@ -412,7 +431,10 @@ static void qemu_wait_io_event(CPUState *env)
     qemu_mutex_unlock(&qemu_fair_mutex);
 
     qemu_mutex_lock(&qemu_global_mutex);
-    qemu_wait_io_event_common(env);
+
+    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+        qemu_wait_io_event_common(env);
+    }
 }
 
 static void qemu_kvm_eat_signal(CPUState *env, int timeout)
@@ -459,7 +481,7 @@ static void *kvm_cpu_thread_fn(void *arg)
     if (kvm_enabled())
         kvm_init_vcpu(env);
 
-    kvm_block_io_signals(env);
+    kvm_init_ipi(env);
 
     /* signal CPU creation */
     env->created = 1;
@@ -482,7 +504,7 @@ static void *tcg_cpu_thread_fn(void *arg)
 {
     CPUState *env = arg;
 
-    tcg_block_io_signals();
+    tcg_init_ipi();
     qemu_thread_self(env->thread);
 
     /* signal CPU creation */
@@ -496,8 +518,8 @@ static void *tcg_cpu_thread_fn(void *arg)
         qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);
 
     while (1) {
-        tcg_cpu_exec();
-        qemu_wait_io_event(cur_cpu);
+        cpu_exec_all();
+        qemu_tcg_wait_io_event();
     }
 
     return NULL;
@@ -527,52 +549,36 @@ static void cpu_signal(int sig)
     exit_request = 1;
 }
 
-static void tcg_block_io_signals(void)
+static void tcg_init_ipi(void)
 {
     sigset_t set;
     struct sigaction sigact;
 
-    sigemptyset(&set);
-    sigaddset(&set, SIGUSR2);
-    sigaddset(&set, SIGIO);
-    sigaddset(&set, SIGALRM);
-    sigaddset(&set, SIGCHLD);
-    pthread_sigmask(SIG_BLOCK, &set, NULL);
+    memset(&sigact, 0, sizeof(sigact));
+    sigact.sa_handler = cpu_signal;
+    sigaction(SIG_IPI, &sigact, NULL);
 
     sigemptyset(&set);
     sigaddset(&set, SIG_IPI);
     pthread_sigmask(SIG_UNBLOCK, &set, NULL);
-
-    memset(&sigact, 0, sizeof(sigact));
-    sigact.sa_handler = cpu_signal;
-    sigaction(SIG_IPI, &sigact, NULL);
 }
 
 static void dummy_signal(int sig)
 {
 }
 
-static void kvm_block_io_signals(CPUState *env)
+static void kvm_init_ipi(CPUState *env)
 {
     int r;
     sigset_t set;
     struct sigaction sigact;
 
-    sigemptyset(&set);
-    sigaddset(&set, SIGUSR2);
-    sigaddset(&set, SIGIO);
-    sigaddset(&set, SIGALRM);
-    sigaddset(&set, SIGCHLD);
-    sigaddset(&set, SIG_IPI);
-    pthread_sigmask(SIG_BLOCK, &set, NULL);
-
-    pthread_sigmask(SIG_BLOCK, NULL, &set);
-    sigdelset(&set, SIG_IPI);
-
     memset(&sigact, 0, sizeof(sigact));
     sigact.sa_handler = dummy_signal;
     sigaction(SIG_IPI, &sigact, NULL);
 
+    pthread_sigmask(SIG_BLOCK, NULL, &set);
+    sigdelset(&set, SIG_IPI);
     r = kvm_set_signal_mask(env, &set);
     if (r) {
         fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(r));
@@ -773,32 +779,28 @@ static int qemu_cpu_exec(CPUState *env)
     return ret;
 }
 
-bool tcg_cpu_exec(void)
+bool cpu_exec_all(void)
 {
-    int ret = 0;
-
     if (next_cpu == NULL)
         next_cpu = first_cpu;
-    for (; next_cpu != NULL; next_cpu = next_cpu->next_cpu) {
-        CPUState *env = cur_cpu = next_cpu;
+    for (; next_cpu != NULL && !exit_request; next_cpu = next_cpu->next_cpu) {
+        CPUState *env = next_cpu;
 
         qemu_clock_enable(vm_clock,
-                          (cur_cpu->singlestep_enabled & SSTEP_NOTIMER) == 0);
+                          (env->singlestep_enabled & SSTEP_NOTIMER) == 0);
 
         if (qemu_alarm_pending())
             break;
-        if (cpu_can_run(env))
-            ret = qemu_cpu_exec(env);
-        else if (env->stop)
-            break;
-
-        if (ret == EXCP_DEBUG) {
-            gdb_set_stop_cpu(env);
-            debug_requested = EXCP_DEBUG;
+        if (cpu_can_run(env)) {
+            if (qemu_cpu_exec(env) == EXCP_DEBUG) {
+                break;
+            }
+        } else if (env->stop) {
             break;
         }
     }
-    return tcg_has_work();
+    exit_request = 0;
+    return any_cpu_has_work();
 }
 
 void set_numa_modes(void)