mirror of https://github.com/xemu-project/xemu.git
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>
This commit is contained in:
parent
c265e976f4
commit
f186d64d8f
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
if (!replay_state.has_unread_data) {
|
||||||
replay_data_kind = replay_get_byte();
|
replay_state.data_kind = replay_get_byte();
|
||||||
if (replay_data_kind == EVENT_INSTRUCTION) {
|
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;
|
replay_state.has_unread_data = 1;
|
||||||
if (replay_data_kind >= EVENT_COUNT) {
|
if (replay_state.data_kind >= EVENT_COUNT) {
|
||||||
error_report("Replay: unknown event kind %d", replay_data_kind);
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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). */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue