From: KONRAD Frederic <fred.kon...@greensocs.com>

This removes exit_request global and adds a variable in CPUState for this.
Only the flag for the first cpu is used for the moment as we are still with one
TCG thread.

Signed-off-by: KONRAD Frederic <fred.kon...@greensocs.com>
---
 cpu-exec.c | 15 ---------------
 cpus.c     | 17 ++++++++++++++---
 2 files changed, 14 insertions(+), 18 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 5d9b518..0644383 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -364,8 +364,6 @@ static void cpu_handle_debug_exception(CPUArchState *env)
 
 /* main execution loop */
 
-volatile sig_atomic_t exit_request;
-
 int cpu_exec(CPUArchState *env)
 {
     CPUState *cpu = ENV_GET_CPU(env);
@@ -394,20 +392,8 @@ int cpu_exec(CPUArchState *env)
 
     current_cpu = cpu;
 
-    /* As long as current_cpu is null, up to the assignment just above,
-     * requests by other threads to exit the execution loop are expected to
-     * be issued using the exit_request global. We must make sure that our
-     * evaluation of the global value is performed past the current_cpu
-     * value transition point, which requires a memory barrier as well as
-     * an instruction scheduling constraint on modern architectures.  */
-    smp_mb();
-
     rcu_read_lock();
 
-    if (unlikely(exit_request)) {
-        cpu->exit_request = 1;
-    }
-
     cc->cpu_exec_enter(cpu);
 
     /* Calculate difference between guest clock and host clock.
@@ -496,7 +482,6 @@ int cpu_exec(CPUArchState *env)
                     }
                 }
                 if (unlikely(cpu->exit_request)) {
-                    cpu->exit_request = 0;
                     cpu->exception_index = EXCP_INTERRUPT;
                     cpu_loop_exit(cpu);
                 }
diff --git a/cpus.c b/cpus.c
index 23c316c..2541c56 100644
--- a/cpus.c
+++ b/cpus.c
@@ -137,6 +137,8 @@ typedef struct TimersState {
 } TimersState;
 
 static TimersState timers_state;
+/* CPU associated to this thread. */
+static __thread CPUState *tcg_thread_cpu;
 
 int64_t cpu_get_icount_raw(void)
 {
@@ -661,12 +663,18 @@ static void cpu_handle_guest_debug(CPUState *cpu)
     cpu->stopped = true;
 }
 
+/**
+ * cpu_signal
+ * Signal handler when using TCG.
+ */
 static void cpu_signal(int sig)
 {
     if (current_cpu) {
         cpu_exit(current_cpu);
     }
-    exit_request = 1;
+
+    /* FIXME: We might want to check if the cpu is running? */
+    tcg_thread_cpu->exit_request = true;
 }
 
 #ifdef CONFIG_LINUX
@@ -1031,6 +1039,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
 {
     CPUState *cpu = arg;
 
+    tcg_thread_cpu = cpu;
     qemu_tcg_init_cpu_signals();
     qemu_thread_get_self(cpu->thread);
 
@@ -1393,7 +1402,8 @@ static void tcg_exec_all(void)
     if (next_cpu == NULL) {
         next_cpu = first_cpu;
     }
-    for (; next_cpu != NULL && !exit_request; next_cpu = CPU_NEXT(next_cpu)) {
+    for (; next_cpu != NULL && !first_cpu->exit_request;
+           next_cpu = CPU_NEXT(next_cpu)) {
         CPUState *cpu = next_cpu;
         CPUArchState *env = cpu->env_ptr;
 
@@ -1410,7 +1420,8 @@ static void tcg_exec_all(void)
             break;
         }
     }
-    exit_request = 0;
+
+    first_cpu->exit_request = 0;
 }
 
 void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
-- 
1.9.0


Reply via email to