diff options
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; +} |