aboutsummaryrefslogtreecommitdiff
path: root/replay
diff options
context:
space:
mode:
authorPavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>2015-09-17 19:24:44 +0300
committerPaolo Bonzini <pbonzini@redhat.com>2015-11-06 10:16:03 +0100
commit8bd7f71d794b93ce027b856f5b79a98f4f82e44c (patch)
tree677dd815bbd08d96bc444396d80acff1a1997dc2 /replay
parentefab87cf79077a9624f675fc5fc8f034eaedfe4d (diff)
replay: checkpoints
This patch introduces checkpoints that synchronize cpu thread and iothread. When checkpoint is met in the code all asynchronous events from the queue are executed. Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru> Message-Id: <20150917162444.8676.52916.stgit@PASHA-ISP.def.inno> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
Diffstat (limited to 'replay')
-rw-r--r--replay/replay-internal.h4
-rw-r--r--replay/replay.c34
2 files changed, 38 insertions, 0 deletions
diff --git a/replay/replay-internal.h b/replay/replay-internal.h
index 4414695017..bf64be54d7 100644
--- a/replay/replay-internal.h
+++ b/replay/replay-internal.h
@@ -29,6 +29,10 @@ enum ReplayEvents {
/* some of greater codes are reserved for clocks */
EVENT_CLOCK,
EVENT_CLOCK_LAST = EVENT_CLOCK + REPLAY_CLOCK_COUNT - 1,
+ /* for checkpoint event */
+ /* some of greater codes are reserved for checkpoints */
+ EVENT_CHECKPOINT,
+ EVENT_CHECKPOINT_LAST = EVENT_CHECKPOINT + CHECKPOINT_COUNT - 1,
EVENT_COUNT
};
diff --git a/replay/replay.c b/replay/replay.c
index 65dca7f534..44fbed9d4c 100644
--- a/replay/replay.c
+++ b/replay/replay.c
@@ -160,3 +160,37 @@ void replay_shutdown_request(void)
replay_mutex_unlock();
}
}
+
+bool replay_checkpoint(ReplayCheckpoint checkpoint)
+{
+ bool res = false;
+ assert(EVENT_CHECKPOINT + checkpoint <= EVENT_CHECKPOINT_LAST);
+ replay_save_instructions();
+
+ if (!replay_file) {
+ return true;
+ }
+
+ replay_mutex_lock();
+
+ if (replay_mode == REPLAY_MODE_PLAY) {
+ if (replay_next_event_is(EVENT_CHECKPOINT + checkpoint)) {
+ replay_finish_event();
+ } else if (replay_data_kind != EVENT_ASYNC) {
+ res = false;
+ goto out;
+ }
+ replay_read_events(checkpoint);
+ /* replay_read_events may leave some unread events.
+ Return false if not all of the events associated with
+ checkpoint were processed */
+ res = replay_data_kind != EVENT_ASYNC;
+ } else if (replay_mode == REPLAY_MODE_RECORD) {
+ replay_put_event(EVENT_CHECKPOINT + checkpoint);
+ replay_save_events(checkpoint);
+ res = true;
+ }
+out:
+ replay_mutex_unlock();
+ return res;
+}