Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-06-05 08:45:31

0001 // Copyright 2026, Jefferson Science Associates, LLC.
0002 // Subject to the terms in the LICENSE file found in the top-level directory.
0003 
0004 #include <JANA/Services/JPerfettoService.h>
0005 
0006 #if JANA2_HAVE_PERFETTO
0007 
0008 #include <fstream>
0009 #include <sstream>
0010 
0011 // Allocate static storage for the categories (must be in exactly one .cc file).
0012 PERFETTO_TRACK_EVENT_STATIC_STORAGE();
0013 
0014 void JPerfettoService::Init() {
0015     auto params = GetApplication()->GetJParameterManager();
0016     params->SetDefaultParameter("jana:perfetto_output", m_output_file,
0017         "Output file path for the Perfetto trace (written on exit).");
0018     params->SetDefaultParameter("jana:perfetto_enabled", m_enabled,
0019         "Enable Perfetto tracing.");
0020 
0021     if (!m_enabled) return;
0022 
0023     perfetto::TracingInitArgs args;
0024     args.backends |= perfetto::kInProcessBackend;
0025     perfetto::Tracing::Initialize(args);
0026     perfetto::TrackEvent::Register();
0027 
0028     perfetto::TraceConfig cfg;
0029     cfg.add_buffers()->set_size_kb(1024 * 256); // 256 MB ring buffer
0030     auto* ds_cfg = cfg.add_data_sources()->mutable_config();
0031     ds_cfg->set_name("track_event");
0032 
0033     m_tracing_session = perfetto::Tracing::NewTrace();
0034     m_tracing_session->Setup(cfg);
0035     m_tracing_session->StartBlocking();
0036 
0037     LOG_INFO(GetLogger()) << "Perfetto tracing started. Output will be written to: " << m_output_file << LOG_END;
0038 }
0039 
0040 JPerfettoService::~JPerfettoService() {
0041     if (!m_enabled || !m_tracing_session) return;
0042 
0043     perfetto::TrackEvent::Flush();
0044     m_tracing_session->StopBlocking();
0045 
0046     std::vector<char> trace_data(m_tracing_session->ReadTraceBlocking());
0047     std::ofstream output(m_output_file, std::ios::out | std::ios::binary);
0048     if (!output) {
0049         std::cerr << "JPerfettoService: Failed to open Perfetto output file: " << m_output_file << "\n";
0050         return;
0051     }
0052     output.write(trace_data.data(), static_cast<std::streamsize>(trace_data.size()));
0053     std::cout << "JPerfettoService: Perfetto trace written to: " << m_output_file
0054               << " (" << trace_data.size() / 1024 << " kB)\n";
0055     std::cout << "JPerfettoService: Open the trace at https://ui.perfetto.dev\n";
0056 }
0057 
0058 void JPerfettoService::RegisterCurrentThread(int worker_id) {
0059     std::ostringstream name;
0060     name << "Worker " << worker_id;
0061     perfetto::ThreadTrack track = perfetto::ThreadTrack::Current();
0062     perfetto::protos::gen::TrackDescriptor desc = track.Serialize();
0063     desc.set_name(name.str());
0064     perfetto::TrackEvent::SetTrackDescriptor(track, desc);
0065 }
0066 
0067 #else // JANA2_HAVE_PERFETTO
0068 
0069 void JPerfettoService::Init() {
0070     std::cerr << "JPerfettoService: JANA2 was not built with Perfetto support (USE_PERFETTO=OFF).\n";
0071 }
0072 
0073 JPerfettoService::~JPerfettoService() {}
0074 
0075 void JPerfettoService::RegisterCurrentThread(int /*worker_id*/) {}
0076 
0077 #endif // JANA2_HAVE_PERFETTO