aboutsummaryrefslogtreecommitdiff
path: root/replay
diff options
context:
space:
mode:
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;
+}