diff --git a/src/chrome_trace.hpp b/src/chrome_trace.hpp index 471725d..7c41079 100644 --- a/src/chrome_trace.hpp +++ b/src/chrome_trace.hpp @@ -18,12 +18,15 @@ #ifdef AEGIR_ENABLE_TRACE +#include +#include + #include #include #include #include #include -#include +#include namespace aegir::trace { @@ -64,10 +67,13 @@ inline long long now_us() { .count(); } +// Kernel thread ID (matches what perf/ps/top show) fits in 32 bits, so the +// JSON parser in ui.perfetto.dev sees distinct values — +// std::hash produces ~10^18 numbers that JavaScript's float64 +// collapses into one track. inline long long thread_id() { - static thread_local long long id = static_cast( - std::hash{}(std::this_thread::get_id()) & - 0x7fffffffffffffffLL); + static thread_local long long id = + static_cast(syscall(SYS_gettid)); return id; } @@ -94,6 +100,17 @@ inline void write_counter(char const* cat, char const* name, long long value) { thread_id(), value); } +inline void set_thread_name(std::string const& name) { + auto* f = file_handle(); + if (!f) return; + std::lock_guard lock(write_mutex()); + std::fprintf(f, + "%s{\"name\":\"thread_name\",\"ph\":\"M\"," + "\"pid\":1,\"tid\":%lld,\"args\":{\"name\":\"%s\"}}", + first_event().exchange(false) ? "" : ",\n", thread_id(), + name.c_str()); +} + class ScopedEvent { public: ScopedEvent(char const* cat, char const* name) @@ -119,10 +136,12 @@ class ScopedEvent { } #define AEGIR_TRACE_COUNTER(cat, name, value) \ ::aegir::trace::write_counter(cat, name, static_cast(value)) +#define AEGIR_TRACE_THREAD_NAME(name) ::aegir::trace::set_thread_name(name) #else // !AEGIR_ENABLE_TRACE #define AEGIR_TRACE_EVENT(cat, name) ((void)0) #define AEGIR_TRACE_COUNTER(cat, name, value) ((void)0) +#define AEGIR_TRACE_THREAD_NAME(name) ((void)0) #endif diff --git a/src/geant4_module.cpp b/src/geant4_module.cpp index 113ce87..9604b78 100644 --- a/src/geant4_module.cpp +++ b/src/geant4_module.cpp @@ -167,6 +167,7 @@ class Geant4Sim { master_thread_ = std::thread([this, &ready_promise] { try { + AEGIR_TRACE_THREAD_NAME("g4_master"); { AEGIR_TRACE_EVENT("g4", "init_master"); auto* rm = new G4MTRunManager(); @@ -214,6 +215,7 @@ class Geant4Sim { void init_worker() { AEGIR_TRACE_EVENT("g4", "init_worker"); int id = next_thread_id_.fetch_add(1); + AEGIR_TRACE_THREAD_NAME("g4_worker_" + std::to_string(id)); G4Threading::G4SetThreadId(id); G4WorkerThread::BuildGeometryAndPhysicsVector();