diff options
author | Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru> | 2015-09-17 19:24:44 +0300 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2015-11-06 10:16:03 +0100 |
commit | 8bd7f71d794b93ce027b856f5b79a98f4f82e44c (patch) | |
tree | 677dd815bbd08d96bc444396d80acff1a1997dc2 /replay | |
parent | efab87cf79077a9624f675fc5fc8f034eaedfe4d (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.h | 4 | ||||
-rw-r--r-- | replay/replay.c | 34 |
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; +} |