Browse Source

replay: move internal data to the structure

This patch moves replay static variables into the structure
to allow saving and loading them with savevm/loadvm.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>

Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
Message-Id: <20160926080804.6992.87687.stgit@PASHA-ISP>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Pavel Dovgalyuk 9 năm trước cách đây
mục cha
commit
f186d64d8f

+ 1 - 1
replay/replay-events.c

@@ -279,7 +279,7 @@ static Event *replay_read_event(int checkpoint)
 /* Called with replay mutex locked */
 /* Called with replay mutex locked */
 void replay_read_events(int checkpoint)
 void replay_read_events(int checkpoint)
 {
 {
-    while (replay_data_kind == EVENT_ASYNC) {
+    while (replay_state.data_kind == EVENT_ASYNC) {
         Event *event = replay_read_event(checkpoint);
         Event *event = replay_read_event(checkpoint);
         if (!event) {
         if (!event) {
             break;
             break;

+ 9 - 11
replay/replay-internal.c

@@ -16,11 +16,8 @@
 #include "qemu/error-report.h"
 #include "qemu/error-report.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/sysemu.h"
 
 
-unsigned int replay_data_kind = -1;
-static unsigned int replay_has_unread_data;
-
 /* Mutex to protect reading and writing events to the log.
 /* Mutex to protect reading and writing events to the log.
-   replay_data_kind and replay_has_unread_data are also protected
+   data_kind and has_unread_data are also protected
    by this mutex.
    by this mutex.
    It also protects replay events queue which stores events to be
    It also protects replay events queue which stores events to be
    written or read to the log. */
    written or read to the log. */
@@ -150,15 +147,16 @@ void replay_check_error(void)
 void replay_fetch_data_kind(void)
 void replay_fetch_data_kind(void)
 {
 {
     if (replay_file) {
     if (replay_file) {
-        if (!replay_has_unread_data) {
-            replay_data_kind = replay_get_byte();
-            if (replay_data_kind == EVENT_INSTRUCTION) {
+        if (!replay_state.has_unread_data) {
+            replay_state.data_kind = replay_get_byte();
+            if (replay_state.data_kind == EVENT_INSTRUCTION) {
                 replay_state.instructions_count = replay_get_dword();
                 replay_state.instructions_count = replay_get_dword();
             }
             }
             replay_check_error();
             replay_check_error();
-            replay_has_unread_data = 1;
-            if (replay_data_kind >= EVENT_COUNT) {
-                error_report("Replay: unknown event kind %d", replay_data_kind);
+            replay_state.has_unread_data = 1;
+            if (replay_state.data_kind >= EVENT_COUNT) {
+                error_report("Replay: unknown event kind %d",
+                             replay_state.data_kind);
                 exit(1);
                 exit(1);
             }
             }
         }
         }
@@ -167,7 +165,7 @@ void replay_fetch_data_kind(void)
 
 
 void replay_finish_event(void)
 void replay_finish_event(void)
 {
 {
-    replay_has_unread_data = 0;
+    replay_state.has_unread_data = 0;
     replay_fetch_data_kind();
     replay_fetch_data_kind();
 }
 }
 
 

+ 5 - 3
replay/replay-internal.h

@@ -62,11 +62,13 @@ typedef struct ReplayState {
     uint64_t current_step;
     uint64_t current_step;
     /*! Number of instructions to be executed before other events happen. */
     /*! Number of instructions to be executed before other events happen. */
     int instructions_count;
     int instructions_count;
+    /*! Type of the currently executed event. */
+    unsigned int data_kind;
+    /*! Flag which indicates that event is not processed yet. */
+    unsigned int has_unread_data;
 } ReplayState;
 } ReplayState;
 extern ReplayState replay_state;
 extern ReplayState replay_state;
 
 
-extern unsigned int replay_data_kind;
-
 /* File for replay writing */
 /* File for replay writing */
 extern FILE *replay_file;
 extern FILE *replay_file;
 
 
@@ -98,7 +100,7 @@ void replay_check_error(void);
     the next event from the log. */
     the next event from the log. */
 void replay_finish_event(void);
 void replay_finish_event(void);
 /*! Reads data type from the file and stores it in the
 /*! Reads data type from the file and stores it in the
-    replay_data_kind variable. */
+    data_kind variable. */
 void replay_fetch_data_kind(void);
 void replay_fetch_data_kind(void);
 
 
 /*! Saves queued events (like instructions and sound). */
 /*! Saves queued events (like instructions and sound). */

+ 1 - 1
replay/replay-time.c

@@ -31,7 +31,7 @@ int64_t replay_save_clock(ReplayClockKind kind, int64_t clock)
 
 
 void replay_read_next_clock(ReplayClockKind kind)
 void replay_read_next_clock(ReplayClockKind kind)
 {
 {
-    unsigned int read_kind = replay_data_kind - EVENT_CLOCK;
+    unsigned int read_kind = replay_state.data_kind - EVENT_CLOCK;
 
 
     assert(read_kind == kind);
     assert(read_kind == kind);
 
 

+ 8 - 7
replay/replay.c

@@ -38,15 +38,15 @@ bool replay_next_event_is(int event)
 
 
     /* nothing to skip - not all instructions used */
     /* nothing to skip - not all instructions used */
     if (replay_state.instructions_count != 0) {
     if (replay_state.instructions_count != 0) {
-        assert(replay_data_kind == EVENT_INSTRUCTION);
+        assert(replay_state.data_kind == EVENT_INSTRUCTION);
         return event == EVENT_INSTRUCTION;
         return event == EVENT_INSTRUCTION;
     }
     }
 
 
     while (true) {
     while (true) {
-        if (event == replay_data_kind) {
+        if (event == replay_state.data_kind) {
             res = true;
             res = true;
         }
         }
-        switch (replay_data_kind) {
+        switch (replay_state.data_kind) {
         case EVENT_SHUTDOWN:
         case EVENT_SHUTDOWN:
             replay_finish_event();
             replay_finish_event();
             qemu_system_shutdown_request();
             qemu_system_shutdown_request();
@@ -85,7 +85,7 @@ void replay_account_executed_instructions(void)
             replay_state.instructions_count -= count;
             replay_state.instructions_count -= count;
             replay_state.current_step += count;
             replay_state.current_step += count;
             if (replay_state.instructions_count == 0) {
             if (replay_state.instructions_count == 0) {
-                assert(replay_data_kind == EVENT_INSTRUCTION);
+                assert(replay_state.data_kind == EVENT_INSTRUCTION);
                 replay_finish_event();
                 replay_finish_event();
                 /* Wake up iothread. This is required because
                 /* Wake up iothread. This is required because
                    timers will not expire until clock counters
                    timers will not expire until clock counters
@@ -188,7 +188,7 @@ bool replay_checkpoint(ReplayCheckpoint checkpoint)
     if (replay_mode == REPLAY_MODE_PLAY) {
     if (replay_mode == REPLAY_MODE_PLAY) {
         if (replay_next_event_is(EVENT_CHECKPOINT + checkpoint)) {
         if (replay_next_event_is(EVENT_CHECKPOINT + checkpoint)) {
             replay_finish_event();
             replay_finish_event();
-        } else if (replay_data_kind != EVENT_ASYNC) {
+        } else if (replay_state.data_kind != EVENT_ASYNC) {
             res = false;
             res = false;
             goto out;
             goto out;
         }
         }
@@ -196,7 +196,7 @@ bool replay_checkpoint(ReplayCheckpoint checkpoint)
         /* replay_read_events may leave some unread events.
         /* replay_read_events may leave some unread events.
            Return false if not all of the events associated with
            Return false if not all of the events associated with
            checkpoint were processed */
            checkpoint were processed */
-        res = replay_data_kind != EVENT_ASYNC;
+        res = replay_state.data_kind != EVENT_ASYNC;
     } else if (replay_mode == REPLAY_MODE_RECORD) {
     } else if (replay_mode == REPLAY_MODE_RECORD) {
         replay_put_event(EVENT_CHECKPOINT + checkpoint);
         replay_put_event(EVENT_CHECKPOINT + checkpoint);
         replay_save_events(checkpoint);
         replay_save_events(checkpoint);
@@ -237,9 +237,10 @@ static void replay_enable(const char *fname, int mode)
     replay_filename = g_strdup(fname);
     replay_filename = g_strdup(fname);
 
 
     replay_mode = mode;
     replay_mode = mode;
-    replay_data_kind = -1;
+    replay_state.data_kind = -1;
     replay_state.instructions_count = 0;
     replay_state.instructions_count = 0;
     replay_state.current_step = 0;
     replay_state.current_step = 0;
+    replay_state.has_unread_data = 0;
 
 
     /* skip file header for RECORD and check it for PLAY */
     /* skip file header for RECORD and check it for PLAY */
     if (replay_mode == REPLAY_MODE_RECORD) {
     if (replay_mode == REPLAY_MODE_RECORD) {