aboutsummaryrefslogtreecommitdiff
path: root/replay
diff options
context:
space:
mode:
Diffstat (limited to 'replay')
-rw-r--r--replay/Makefile.objs1
-rw-r--r--replay/replay-internal.h11
-rw-r--r--replay/replay-time.c64
3 files changed, 76 insertions, 0 deletions
diff --git a/replay/Makefile.objs b/replay/Makefile.objs
index 6b439c2c23..56328ac53b 100644
--- a/replay/Makefile.objs
+++ b/replay/Makefile.objs
@@ -1,3 +1,4 @@
common-obj-y += replay.o
common-obj-y += replay-internal.o
common-obj-y += replay-events.o
+common-obj-y += replay-time.o
diff --git a/replay/replay-internal.h b/replay/replay-internal.h
index 23807ca413..f042c46e70 100644
--- a/replay/replay-internal.h
+++ b/replay/replay-internal.h
@@ -23,6 +23,10 @@ enum ReplayEvents {
EVENT_EXCEPTION,
/* for async events */
EVENT_ASYNC,
+ /* for clock read/writes */
+ /* some of greater codes are reserved for clocks */
+ EVENT_CLOCK,
+ EVENT_CLOCK_LAST = EVENT_CLOCK + REPLAY_CLOCK_COUNT - 1,
EVENT_COUNT
};
@@ -35,6 +39,8 @@ enum ReplayAsyncEventKind {
typedef enum ReplayAsyncEventKind ReplayAsyncEventKind;
typedef struct ReplayState {
+ /*! Cached clock values. */
+ int64_t cached_clock[REPLAY_CLOCK_COUNT];
/*! Current step - number of processed instructions and timer events. */
uint64_t current_step;
/*! Number of instructions to be executed before other events happen. */
@@ -85,6 +91,11 @@ void replay_save_instructions(void);
\return true, if event was found */
bool replay_next_event_is(int event);
+/*! Reads next clock value from the file.
+ If clock kind read from the file is different from the parameter,
+ the value is not used. */
+void replay_read_next_clock(unsigned int kind);
+
/* Asynchronous events queue */
/*! Initializes events' processing internals */
diff --git a/replay/replay-time.c b/replay/replay-time.c
new file mode 100644
index 0000000000..6d06951f5e
--- /dev/null
+++ b/replay/replay-time.c
@@ -0,0 +1,64 @@
+/*
+ * replay-time.c
+ *
+ * Copyright (c) 2010-2015 Institute for System Programming
+ * of the Russian Academy of Sciences.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu-common.h"
+#include "sysemu/replay.h"
+#include "replay-internal.h"
+#include "qemu/error-report.h"
+
+int64_t replay_save_clock(ReplayClockKind kind, int64_t clock)
+{
+ replay_save_instructions();
+
+ if (replay_file) {
+ replay_mutex_lock();
+ replay_put_event(EVENT_CLOCK + kind);
+ replay_put_qword(clock);
+ replay_mutex_unlock();
+ }
+
+ return clock;
+}
+
+void replay_read_next_clock(ReplayClockKind kind)
+{
+ unsigned int read_kind = replay_data_kind - EVENT_CLOCK;
+
+ assert(read_kind == kind);
+
+ int64_t clock = replay_get_qword();
+
+ replay_check_error();
+ replay_finish_event();
+
+ replay_state.cached_clock[read_kind] = clock;
+}
+
+/*! Reads next clock event from the input. */
+int64_t replay_read_clock(ReplayClockKind kind)
+{
+ replay_account_executed_instructions();
+
+ if (replay_file) {
+ int64_t ret;
+ replay_mutex_lock();
+ if (replay_next_event_is(EVENT_CLOCK + kind)) {
+ replay_read_next_clock(kind);
+ }
+ ret = replay_state.cached_clock[kind];
+ replay_mutex_unlock();
+
+ return ret;
+ }
+
+ error_report("REPLAY INTERNAL ERROR %d", __LINE__);
+ exit(1);
+}