Skip to content

Commit

Permalink
replay: introduce icount event
Browse files Browse the repository at this point in the history
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 <[email protected]>

Signed-off-by: Pavel Dovgalyuk <[email protected]>
Message-Id: <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
  • Loading branch information
Dovgalyuk authored and bonzini committed Nov 5, 2015
1 parent c16861e commit 26bc60a
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 0 deletions.
7 changes: 7 additions & 0 deletions include/sysemu/replay.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
24 changes: 24 additions & 0 deletions replay/replay-internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
*/

#include "qemu-common.h"
#include "sysemu/replay.h"
#include "replay-internal.h"
#include "qemu/error-report.h"
#include "sysemu/sysemu.h"
Expand All @@ -36,6 +37,7 @@ void replay_put_byte(uint8_t byte)

void replay_put_event(uint8_t event)
{
assert(event < EVENT_COUNT);
replay_put_byte(event);
}

Expand Down Expand Up @@ -149,8 +151,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);
}
}
}
}
Expand Down Expand Up @@ -180,3 +189,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 (diff > 0) {
replay_put_event(EVENT_INSTRUCTION);
replay_put_dword(diff);
replay_state.current_step += diff;
}
replay_mutex_unlock();
}
}
21 changes: 21 additions & 0 deletions replay/replay-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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
33 changes: 33 additions & 0 deletions replay/replay.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,39 @@
*
*/

#include "qemu-common.h"
#include "sysemu/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) {
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();
}

0 comments on commit 26bc60a

Please sign in to comment.