From b71c9c12c4a9b72159e755beb45dafebf58bdff1 Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Thu, 6 May 2021 20:47:03 -0400 Subject: [PATCH 1/4] map {tid,pid} from catapult into a virtual tid --- import-chrome/src/import-chrome.cpp | 33 +++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/import-chrome/src/import-chrome.cpp b/import-chrome/src/import-chrome.cpp index 74656cba..9c909b38 100644 --- a/import-chrome/src/import-chrome.cpp +++ b/import-chrome/src/import-chrome.cpp @@ -133,11 +133,30 @@ int main( int argc, char** argv ) printf( "\33[2KParsing...\r" ); fflush( stdout ); + struct PidTid { + uint64_t tid; + uint64_t pid; + uint64_t both; // fake thread id, unique within Tracy + }; + + std::vector tids; std::vector timeline; std::vector messages; std::vector plots; std::unordered_map threadNames; + const auto getTid = [&](uint64_t pid, uint64_t tid) -> uint64_t { + for ( auto &pair : tids ) { + if ( pair.pid == pid && pair.tid == tid ) { + return pair.both; + } + } + + const auto result = tids.size(); + tids.emplace_back(PidTid {.tid=tid, .pid=pid, .both=result}); + return result; + }; + if( j.is_object() && j.contains( "traceEvents" ) ) { j = j["traceEvents"]; @@ -162,10 +181,15 @@ int main( int argc, char** argv ) } } + uint64_t pid = 0; + if ( v.contains( "pid" ) ) { + pid = v["pid"].get(); + } + if( type == "B" ) { timeline.emplace_back( tracy::Worker::ImportEventTimeline { - v["tid"].get(), + getTid(pid, v["tid"].get()), uint64_t( v["ts"].get() * 1000. ), v["name"].get(), std::move(zoneText), @@ -175,7 +199,7 @@ int main( int argc, char** argv ) else if( type == "E" ) { timeline.emplace_back( tracy::Worker::ImportEventTimeline { - v["tid"].get(), + getTid(pid, v["tid"].get()), uint64_t( v["ts"].get() * 1000. ), "", std::move(zoneText), @@ -194,7 +218,7 @@ int main( int argc, char** argv ) else if( type == "i" || type == "I" ) { messages.emplace_back( tracy::Worker::ImportEventMessages { - v["tid"].get(), + getTid(pid, v["tid"].get()), uint64_t( v["ts"].get() * 1000. ), v["name"].get() } ); @@ -241,7 +265,8 @@ int main( int argc, char** argv ) { if (v.contains("name") && v["name"] == "thread_name" && v.contains("args") && v["args"].is_object() && v["args"].contains("name")) { - threadNames[v["tid"].get()] = v["args"]["name"].get(); + const auto tid = getTid(pid, v["tid"].get()); + threadNames[tid] = v["args"]["name"].get(); } } } From 7e694d452ab6a0453b62d50a30e71d9890222be1 Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Mon, 10 May 2021 10:59:03 -0400 Subject: [PATCH 2/4] improve chrome importer to better display string arguments --- import-chrome/src/import-chrome.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/import-chrome/src/import-chrome.cpp b/import-chrome/src/import-chrome.cpp index 9c909b38..58314994 100644 --- a/import-chrome/src/import-chrome.cpp +++ b/import-chrome/src/import-chrome.cpp @@ -177,7 +177,11 @@ int main( int argc, char** argv ) { for ( auto& kv : v["args"].items() ) { - zoneText += kv.key() + ": " + kv.value().dump() + "\n"; + const auto val = kv.value(); + const std::string s = + val.is_string() ? + val.get() : val.dump(); + zoneText += kv.key() + ": " + s + "\n"; } } @@ -208,7 +212,7 @@ int main( int argc, char** argv ) } else if( type == "X" ) { - const auto tid = v["tid"].get(); + const auto tid = getTid(pid, v["tid"].get()); const auto ts0 = uint64_t( v["ts"].get() * 1000. ); const auto ts1 = ts0 + uint64_t( v["dur"].get() * 1000. ); const auto name = v["name"].get(); From d38f579ec392ac386b0eb1eab0aca797bcc0ab9a Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Mon, 10 May 2021 11:20:39 -0400 Subject: [PATCH 3/4] refactor after review --- import-chrome/src/import-chrome.cpp | 44 ++++++++++++++++------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/import-chrome/src/import-chrome.cpp b/import-chrome/src/import-chrome.cpp index 58314994..29d7406e 100644 --- a/import-chrome/src/import-chrome.cpp +++ b/import-chrome/src/import-chrome.cpp @@ -133,28 +133,37 @@ int main( int argc, char** argv ) printf( "\33[2KParsing...\r" ); fflush( stdout ); - struct PidTid { + // encode a pair of "real pid, real tid" from a trace into a + // pseudo thread ID living in the single namespace of Tracy threads. + struct PidTidEncoder { uint64_t tid; uint64_t pid; - uint64_t both; // fake thread id, unique within Tracy + uint64_t pseudo_tid; // fake thread id, unique within Tracy }; - std::vector tids; + std::vector tid_encoders; std::vector timeline; std::vector messages; std::vector plots; std::unordered_map threadNames; - const auto getTid = [&](uint64_t pid, uint64_t tid) -> uint64_t { - for ( auto &pair : tids ) { - if ( pair.pid == pid && pair.tid == tid ) { - return pair.both; + const auto getPseudoTid = [&](json& val) -> uint64_t { + uint64_t pid = 0; + if ( val.contains( "pid" ) ) { + pid = val["pid"].get(); + } + + const auto real_tid = val["tid"].get(); + + for ( auto &pair : tid_encoders) { + if ( pair.pid == pid && pair.tid == real_tid ) { + return pair.pseudo_tid; } } - const auto result = tids.size(); - tids.emplace_back(PidTid {.tid=tid, .pid=pid, .both=result}); - return result; + const auto pseudo_tid = tid_encoders.size(); + tid_encoders.emplace_back(PidTidEncoder {real_tid, pid, pseudo_tid}); + return pseudo_tid; }; if( j.is_object() && j.contains( "traceEvents" ) ) @@ -185,15 +194,10 @@ int main( int argc, char** argv ) } } - uint64_t pid = 0; - if ( v.contains( "pid" ) ) { - pid = v["pid"].get(); - } - if( type == "B" ) { timeline.emplace_back( tracy::Worker::ImportEventTimeline { - getTid(pid, v["tid"].get()), + getPseudoTid(v), uint64_t( v["ts"].get() * 1000. ), v["name"].get(), std::move(zoneText), @@ -203,7 +207,7 @@ int main( int argc, char** argv ) else if( type == "E" ) { timeline.emplace_back( tracy::Worker::ImportEventTimeline { - getTid(pid, v["tid"].get()), + getPseudoTid(v), uint64_t( v["ts"].get() * 1000. ), "", std::move(zoneText), @@ -212,7 +216,7 @@ int main( int argc, char** argv ) } else if( type == "X" ) { - const auto tid = getTid(pid, v["tid"].get()); + const auto tid = getPseudoTid(v); const auto ts0 = uint64_t( v["ts"].get() * 1000. ); const auto ts1 = ts0 + uint64_t( v["dur"].get() * 1000. ); const auto name = v["name"].get(); @@ -222,7 +226,7 @@ int main( int argc, char** argv ) else if( type == "i" || type == "I" ) { messages.emplace_back( tracy::Worker::ImportEventMessages { - getTid(pid, v["tid"].get()), + getPseudoTid(v), uint64_t( v["ts"].get() * 1000. ), v["name"].get() } ); @@ -269,7 +273,7 @@ int main( int argc, char** argv ) { if (v.contains("name") && v["name"] == "thread_name" && v.contains("args") && v["args"].is_object() && v["args"].contains("name")) { - const auto tid = getTid(pid, v["tid"].get()); + const auto tid = getPseudoTid(v); threadNames[tid] = v["args"]["name"].get(); } } From b512ce3fa822cf88d16313c694c7873a995290c3 Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Mon, 10 May 2021 11:49:07 -0400 Subject: [PATCH 4/4] do not mangle tid if there is no pid --- import-chrome/src/import-chrome.cpp | 31 +++++++++++++++++------------ 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/import-chrome/src/import-chrome.cpp b/import-chrome/src/import-chrome.cpp index 29d7406e..126e3797 100644 --- a/import-chrome/src/import-chrome.cpp +++ b/import-chrome/src/import-chrome.cpp @@ -148,22 +148,27 @@ int main( int argc, char** argv ) std::unordered_map threadNames; const auto getPseudoTid = [&](json& val) -> uint64_t { - uint64_t pid = 0; - if ( val.contains( "pid" ) ) { - pid = val["pid"].get(); - } - const auto real_tid = val["tid"].get(); - for ( auto &pair : tid_encoders) { - if ( pair.pid == pid && pair.tid == real_tid ) { - return pair.pseudo_tid; - } - } + if ( val.contains( "pid" ) ) { + // there might be multiple processes so we allocate a pseudo-tid + // for each pair (pid, real_tid) + const auto pid = val["pid"].get(); - const auto pseudo_tid = tid_encoders.size(); - tid_encoders.emplace_back(PidTidEncoder {real_tid, pid, pseudo_tid}); - return pseudo_tid; + for ( auto &pair : tid_encoders) { + if ( pair.pid == pid && pair.tid == real_tid ) { + return pair.pseudo_tid; + } + } + + const auto pseudo_tid = tid_encoders.size(); + tid_encoders.emplace_back(PidTidEncoder {real_tid, pid, pseudo_tid}); + return pseudo_tid; + } + else + { + return real_tid; + } }; if( j.is_object() && j.contains( "traceEvents" ) )