qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [RFC PATCH v3 29/30] replay: improve replay performance


From: Pavel Dovgalyuk
Subject: [Qemu-devel] [RFC PATCH v3 29/30] replay: improve replay performance
Date: Thu, 11 Jan 2018 11:27:38 +0300
User-agent: StGit/0.17.1-dirty

This patch skips cpu_exec when there is no CPU code to execute in replay mode.

Signed-off-by: Pavel Dovgalyuk <address@hidden>
Signed-off-by: Maria Klimushenkova <address@hidden>
---
 cpus.c                  |   50 +++++++++++++++++++++++++----------------------
 include/sysemu/replay.h |    3 +++
 replay/replay.c         |   13 ++++++++++++
 3 files changed, 43 insertions(+), 23 deletions(-)

diff --git a/cpus.c b/cpus.c
index bafedfc..ef4c5b9 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1449,39 +1449,43 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg)
             cpu = first_cpu;
         }
 
-        while (cpu && !cpu->queued_work_first && !cpu->exit_request) {
+        if (!replay_has_checkpoint()) {
+            while (cpu && !cpu->queued_work_first && !cpu->exit_request) {
 
-            atomic_mb_set(&tcg_current_rr_cpu, cpu);
-            current_cpu = cpu;
+                atomic_mb_set(&tcg_current_rr_cpu, cpu);
+                current_cpu = cpu;
 
-            qemu_clock_enable(QEMU_CLOCK_VIRTUAL,
-                              (cpu->singlestep_enabled & SSTEP_NOTIMER) == 0);
+                qemu_clock_enable(QEMU_CLOCK_VIRTUAL,
+                                  (cpu->singlestep_enabled & SSTEP_NOTIMER) == 
0);
 
-            if (cpu_can_run(cpu)) {
-                int r;
+                if (cpu_can_run(cpu)) {
+                    int r;
 
-                prepare_icount_for_run(cpu);
+                    prepare_icount_for_run(cpu);
 
-                r = tcg_cpu_exec(cpu);
+                    r = tcg_cpu_exec(cpu);
 
-                process_icount_data(cpu);
+                    process_icount_data(cpu);
 
-                if (r == EXCP_DEBUG) {
-                    cpu_handle_guest_debug(cpu);
-                    break;
-                } else if (r == EXCP_ATOMIC) {
-                    cpu_exec_step_atomic(cpu);
+                    if (r == EXCP_DEBUG) {
+                        cpu_handle_guest_debug(cpu);
+                        break;
+                    } else if (r == EXCP_ATOMIC) {
+                        cpu_exec_step_atomic(cpu);
+                        break;
+                    }
+                } else if (cpu->stop) {
+                    if (cpu->unplug) {
+                        cpu = CPU_NEXT(cpu);
+                    }
                     break;
                 }
-            } else if (cpu->stop) {
-                if (cpu->unplug) {
-                    cpu = CPU_NEXT(cpu);
-                }
-                break;
-            }
 
-            cpu = CPU_NEXT(cpu);
-        } /* while (cpu && !cpu->exit_request).. */
+                cpu = CPU_NEXT(cpu);
+            } /* while (cpu && !cpu->exit_request).. */
+        } else {
+            qemu_notify_event();
+        }
 
         /* Does not need atomic_mb_set because a spurious wakeup is okay.  */
         atomic_set(&tcg_current_rr_cpu, NULL);
diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h
index d026b28..44c1ff7 100644
--- a/include/sysemu/replay.h
+++ b/include/sysemu/replay.h
@@ -122,6 +122,9 @@ void replay_shutdown_request(ShutdownCause cause);
     Returns 0 in PLAY mode if checkpoint was not found.
     Returns 1 in all other cases. */
 bool replay_checkpoint(ReplayCheckpoint checkpoint);
+/*! Used to determine that checkpoint is pending.
+    Does not proceed to the next event in the log. */
+bool replay_has_checkpoint(void);
 
 /* Asynchronous events queue */
 
diff --git a/replay/replay.c b/replay/replay.c
index c9fd984..b9c496a 100644
--- a/replay/replay.c
+++ b/replay/replay.c
@@ -219,6 +219,19 @@ out:
     return res;
 }
 
+bool replay_has_checkpoint(void)
+{
+    bool res = false;
+    if (replay_mode == REPLAY_MODE_PLAY) {
+        replay_mutex_lock();
+        replay_account_executed_instructions();
+        res = EVENT_CHECKPOINT <= replay_state.data_kind
+            && replay_state.data_kind <= EVENT_CHECKPOINT_LAST;
+        replay_mutex_unlock();
+    }
+    return res;
+}
+
 void replay_init_locks(void)
 {
     replay_mutex_init();




reply via email to

[Prev in Thread] Current Thread [Next in Thread]