summaryrefslogtreecommitdiff
path: root/retrace
diff options
context:
space:
mode:
authorCarl Worth <cworth@cworth.org>2013-03-21 13:50:29 -0700
committerJosé Fonseca <jfonseca@vmware.com>2013-04-12 10:51:51 +0100
commit448a82a8d4070b8911f6db667d55693d1dc8f99f (patch)
treeb60211790961951240e60a628542eaae62613cb2 /retrace
parent342e9725ecc44cf882ee13f87d5099f71f2700af (diff)
replay: Add a --loop option to repeatedly loop over the final frame
This can be useful for repeatedly exercising the driver with the operations of a single frame.
Diffstat (limited to 'retrace')
-rw-r--r--retrace/retrace_main.cpp39
1 files changed, 38 insertions, 1 deletions
diff --git a/retrace/retrace_main.cpp b/retrace/retrace_main.cpp
index de84e0e2..0c358e18 100644
--- a/retrace/retrace_main.cpp
+++ b/retrace/retrace_main.cpp
@@ -42,11 +42,13 @@
static bool waitOnFinish = false;
+static bool loopOnFinish = false;
static const char *comparePrefix = NULL;
static const char *snapshotPrefix = NULL;
static trace::CallSet snapshotFrequency;
static trace::CallSet compareFrequency;
+static trace::ParseBookmark lastFrameStart;
static unsigned dumpStateCallNo = ~0;
@@ -309,13 +311,34 @@ public:
*/
void
runLeg(trace::Call *call) {
+
/* Consume successive calls for this thread. */
do {
+ bool callEndsFrame = false;
+ static trace::ParseBookmark frameStart;
+
assert(call);
assert(call->thread_id == leg);
+
+ if (loopOnFinish && call->flags & trace::CALL_FLAG_END_FRAME) {
+ callEndsFrame = true;
+ parser.getBookmark(frameStart);
+ }
+
retraceCall(call);
delete call;
call = parser.parse_call();
+
+ /* Restart last frame if looping is requested. */
+ if (loopOnFinish) {
+ if (!call) {
+ parser.setBookmark(lastFrameStart);
+ call = parser.parse_call();
+ } else if (callEndsFrame) {
+ lastFrameStart = frameStart;
+ }
+ }
+
} while (call && call->thread_id == leg);
if (call) {
@@ -423,6 +446,14 @@ RelayRace::run(void) {
return;
}
+ /* If the user wants to loop we need to get a bookmark target. We
+ * usually get this after replaying a call that ends a frame, but
+ * for a trace that has only one frame we need to get it at the
+ * beginning. */
+ if (loopOnFinish) {
+ parser.getBookmark(lastFrameStart);
+ }
+
RelayRunner *foreRunner = getForeRunner();
if (call->thread_id == 0) {
/* We are the forerunner thread, so no need to pass baton */
@@ -540,6 +571,7 @@ usage(const char *argv0) {
" -v, --verbose increase output verbosity\n"
" -D, --dump-state=CALL dump state at specific call no\n"
" -w, --wait waitOnFinish on final frame\n"
+ " --loop continuously loop, replaying final frame.\n"
" --singlethread use a single thread to replay command stream\n";
}
@@ -553,7 +585,8 @@ enum {
PPD_OPT,
PMEM_OPT,
SB_OPT,
- SINGLETHREAD_OPT,
+ LOOP_OPT,
+ SINGLETHREAD_OPT
};
const static char *
@@ -579,6 +612,7 @@ longOptions[] = {
{"snapshot", required_argument, 0, 'S'},
{"verbose", no_argument, 0, 'v'},
{"wait", no_argument, 0, 'w'},
+ {"loop", no_argument, 0, LOOP_OPT},
{"singlethread", no_argument, 0, SINGLETHREAD_OPT},
{0, 0, 0, 0}
};
@@ -677,6 +711,9 @@ int main(int argc, char **argv)
case 'w':
waitOnFinish = true;
break;
+ case LOOP_OPT:
+ loopOnFinish = true;
+ break;
case PGPU_OPT:
retrace::debug = false;
retrace::profiling = true;