[PATCH] retrace: add single thread option

j.glisse at gmail.com j.glisse at gmail.com
Mon Feb 18 09:22:11 PST 2013


From: Jerome Glisse <jglisse at redhat.com>

Allow to replay trace using only one thread, helpfull when debugging
driver.

Signed-off-by: Jerome Glisse <jglisse at redhat.com>
---
 retrace/retrace_main.cpp |   38 +++++++++++++++++++++++++++++++++-----
 1 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/retrace/retrace_main.cpp b/retrace/retrace_main.cpp
index ca03745..09363c1 100644
--- a/retrace/retrace_main.cpp
+++ b/retrace/retrace_main.cpp
@@ -73,6 +73,7 @@ bool profilingGpuTimes = false;
 bool profilingCpuTimes = false;
 bool profilingPixelsDrawn = false;
 bool useCallNos = true;
+bool singleThread = false;
 
 unsigned frameNo = 0;
 unsigned callNo = 0;
@@ -200,6 +201,7 @@ private:
      * trace).
      */
     std::vector<RelayRunner*> runners;
+    RelayRunner *cur;
 
 public:
     RelayRace();
@@ -265,7 +267,7 @@ public:
         baton(0)
     {
         /* The fore runner does not need a new thread */
-        if (leg) {
+        if (leg && !singleThread) {
             thread = os::thread(runnerThread, this);
         }
     }
@@ -300,6 +302,14 @@ public:
         }
     }
 
+    void
+    runRaceSingle(void) {
+        assert(baton);
+        trace::Call *call = baton;
+        baton = 0;
+        runLeg(call);
+    }
+
     /**
      * Interpret successive calls.
      */
@@ -343,7 +353,9 @@ public:
         baton = call;
         mutex.unlock();
 
-        wake_cond.signal();
+        if (!singleThread) {
+            wake_cond.signal();
+        }
     }
 
     /**
@@ -357,7 +369,9 @@ public:
         finished = true;
         mutex.unlock();
 
-        wake_cond.signal();
+        if (!singleThread) {
+            wake_cond.signal();
+        }
     }
 };
 
@@ -423,12 +437,19 @@ RelayRace::run(void) {
     if (call->thread_id == 0) {
         /* We are the forerunner thread, so no need to pass baton */
         foreRunner->baton = call;
+        cur = foreRunner;
     } else {
         passBaton(call);
     }
 
     /* Start the forerunner thread */
-    foreRunner->runRace();
+    if (!singleThread) {
+        foreRunner->runRace();
+    } else {
+        do {
+            cur->runRaceSingle();
+        } while (!foreRunner->finished && cur);
+    }
 }
 
 
@@ -439,6 +460,7 @@ void
 RelayRace::passBaton(trace::Call *call) {
     if (0) std::cerr << "switching to thread " << call->thread_id << "\n";
     RelayRunner *runner = getRunner(call->thread_id);
+    cur = runner;
     runner->receiveBaton(call);
 }
 
@@ -525,7 +547,8 @@ usage(const char *argv0) {
         "  -S, --snapshot=CALLSET  calls to snapshot (default is every frame)\n"
         "  -v, --verbose           increase output verbosity\n"
         "  -D, --dump-state=CALL   dump state at specific call no\n"
-        "  -w, --wait              waitOnFinish on final frame\n";
+        "  -w, --wait              waitOnFinish on final frame\n"
+        "      --singlethread      use a single thread to replay command stream\n";
 }
 
 enum {
@@ -537,6 +560,7 @@ enum {
     PGPU_OPT,
     PPD_OPT,
     SB_OPT,
+    SINGLETHREAD_OPT,
 };
 
 const static char *
@@ -561,6 +585,7 @@ longOptions[] = {
     {"snapshot", required_argument, 0, 'S'},
     {"verbose", no_argument, 0, 'v'},
     {"wait", no_argument, 0, 'w'},
+    {"singlethread", no_argument, 0, SINGLETHREAD_OPT},
     {0, 0, 0, 0}
 };
 
@@ -633,6 +658,9 @@ int main(int argc, char **argv)
         case SB_OPT:
             retrace::doubleBuffer = false;
             break;
+        case SINGLETHREAD_OPT:
+            retrace::singleThread = true;
+            break;
         case 's':
             snapshotPrefix = optarg;
             if (snapshotFrequency.empty()) {
-- 
1.7.7.6



More information about the apitrace mailing list