From 448a82a8d4070b8911f6db667d55693d1dc8f99f Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Thu, 21 Mar 2013 13:50:29 -0700 Subject: [PATCH] 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. --- retrace/retrace_main.cpp | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/retrace/retrace_main.cpp b/retrace/retrace_main.cpp index de84e0e..0c358e1 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; -- 2.43.0