qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH v14 06/21] replay: introduce icount event


From: Pavel Dovgalyuk
Subject: [Qemu-devel] [PATCH v14 06/21] replay: introduce icount event
Date: Mon, 25 May 2015 15:07:50 +0300
User-agent: StGit/0.16

This patch adds icount event to the replay subsystem. This event corresponds
to execution of several instructions and used to synchronize input events
in the replay phase.

Reviewed-by: Paolo Bonzini <address@hidden>

Signed-off-by: Pavel Dovgalyuk <address@hidden>
---
 replay/replay-internal.c |   24 ++++++++++++++++++++++++
 replay/replay-internal.h |   21 +++++++++++++++++++++
 replay/replay.c          |   34 ++++++++++++++++++++++++++++++++++
 replay/replay.h          |    7 +++++++
 4 files changed, 86 insertions(+), 0 deletions(-)

diff --git a/replay/replay-internal.c b/replay/replay-internal.c
index f7c03bc..064ddf9 100755
--- a/replay/replay-internal.c
+++ b/replay/replay-internal.c
@@ -10,6 +10,7 @@
  */
 
 #include "qemu-common.h"
+#include "replay.h"
 #include "replay-internal.h"
 
 unsigned int replay_data_kind = -1;
@@ -34,6 +35,7 @@ void replay_put_byte(uint8_t byte)
 
 void replay_put_event(uint8_t event)
 {
+    assert(event < EVENT_COUNT);
     replay_put_byte(event);
 }
 
@@ -143,8 +145,15 @@ void replay_fetch_data_kind(void)
     if (replay_file) {
         if (!replay_has_unread_data) {
             replay_data_kind = replay_get_byte();
+            if (replay_data_kind == EVENT_INSTRUCTION) {
+                replay_state.instructions_count = replay_get_dword();
+            }
             replay_check_error();
             replay_has_unread_data = 1;
+            if (replay_data_kind >= EVENT_COUNT) {
+                error_report("Replay: unknown event kind %d", 
replay_data_kind);
+                exit(1);
+            }
         }
     }
 }
@@ -174,3 +183,18 @@ void replay_mutex_unlock(void)
 {
     qemu_mutex_unlock(&lock);
 }
+
+/*! Saves cached instructions. */
+void replay_save_instructions(void)
+{
+    if (replay_file && replay_mode == REPLAY_MODE_RECORD) {
+        replay_mutex_lock();
+        int diff = (int)(replay_get_current_step() - 
replay_state.current_step);
+        if (first_cpu != NULL && diff > 0) {
+            replay_put_event(EVENT_INSTRUCTION);
+            replay_put_dword(diff);
+            replay_state.current_step += diff;
+        }
+        replay_mutex_unlock();
+    }
+}
diff --git a/replay/replay-internal.h b/replay/replay-internal.h
index 8a0de0d..acae7ac 100755
--- a/replay/replay-internal.h
+++ b/replay/replay-internal.h
@@ -14,6 +14,20 @@
 
 #include <stdio.h>
 
+enum ReplayEvents {
+    /* for instruction event */
+    EVENT_INSTRUCTION,
+    EVENT_COUNT
+};
+
+typedef struct ReplayState {
+    /*! Current step - number of processed instructions and timer events. */
+    uint64_t current_step;
+    /*! Number of instructions to be executed before other events happen. */
+    int instructions_count;
+} ReplayState;
+extern ReplayState replay_state;
+
 extern unsigned int replay_data_kind;
 
 /* File for replay writing */
@@ -50,4 +64,11 @@ void replay_finish_event(void);
     replay_data_kind variable. */
 void replay_fetch_data_kind(void);
 
+/*! Saves queued events (like instructions and sound). */
+void replay_save_instructions(void);
+
+/*! Skips async events until some sync event will be found. 
+    \return true, if event was found */
+bool replay_next_event_is(int event);
+
 #endif
diff --git a/replay/replay.c b/replay/replay.c
index 5ce066f..43798e1 100755
--- a/replay/replay.c
+++ b/replay/replay.c
@@ -9,6 +9,40 @@
  *
  */
 
+#include "qemu-common.h"
 #include "replay.h"
+#include "replay-internal.h"
+#include "qemu/timer.h"
 
 ReplayMode replay_mode = REPLAY_MODE_NONE;
+
+ReplayState replay_state;
+
+bool replay_next_event_is(int event)
+{
+    bool res = false;
+
+    /* nothing to skip - not all instructions used */
+    if (replay_state.instructions_count != 0) {
+        assert(replay_data_kind == EVENT_INSTRUCTION);
+        return event == EVENT_INSTRUCTION;
+    }
+
+    while (true) {
+        replay_fetch_data_kind();
+        if (event == replay_data_kind) {
+            res = true;
+        }
+        switch (replay_data_kind) {
+        default:
+            /* clock, time_t, checkpoint and other events */
+            return res;
+        }
+    }
+    return res;
+}
+
+uint64_t replay_get_current_step(void)
+{
+    return cpu_get_icount_raw();
+}
diff --git a/replay/replay.h b/replay/replay.h
index d6b73c3..a03c748 100755
--- a/replay/replay.h
+++ b/replay/replay.h
@@ -12,8 +12,15 @@
  *
  */
 
+#include <stdbool.h>
+#include <stdint.h>
 #include "qapi-types.h"
 
 extern ReplayMode replay_mode;
 
+/* Processing the instructions */
+
+/*! Returns number of executed instructions. */
+uint64_t replay_get_current_step(void);
+
 #endif




reply via email to

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