/* * Bridge for Perfetto C->C++ * * written by gback@vt.edu for CS3214 Spring 2024 */ #include "perfetto.h" #include "perfetto-bridge.h" #include PERFETTO_DEFINE_CATEGORIES( perfetto::Category(LOCKING_CATEGORY).SetDescription("Lock Simulation"), ); PERFETTO_TRACK_EVENT_STATIC_STORAGE(); // as per https://github.com/google/perfetto/blob/master/examples/sdk/example.cc // and // https://cs.android.com/android/platform/superproject/main/+/main:external/perfetto/src/tracing/test/api_integrationtest.cc;l=2241-2242;drc=d8fd1b45a91e019b1e98a3971155c7b0c579faf2 std::unique_ptr StartTracing() { // The trace config defines which types of data sources are enabled for // recording. In this example we just need the "track_event" data source, // which corresponds to the TRACE_EVENT trace points. perfetto::TraceConfig cfg; cfg.add_buffers()->set_size_kb(1024); auto* ds_cfg = cfg.add_data_sources()->mutable_config(); ds_cfg->set_name("track_event"); auto tracing_session = perfetto::Tracing::NewTrace(); tracing_session->Setup(cfg); tracing_session->StartBlocking(); return tracing_session; } void StopTracing(std::unique_ptr tracing_session, char *output_file_name) { // Make sure the last event is closed for this example. perfetto::TrackEvent::Flush(); // Stop tracing and read the trace data. tracing_session->StopBlocking(); std::vector trace_data(tracing_session->ReadTraceBlocking()); std::ofstream output; output.open(output_file_name, std::ios::out | std::ios::binary); output.write(&trace_data[0], std::streamsize(trace_data.size())); output.close(); PERFETTO_LOG("Trace written to %s file.", output_file_name); } /* * Emit a start event labeled `event` */ void perfetto_trace_event_begin(const char *event, uint64_t timestamp) { TRACE_EVENT_BEGIN(LOCKING_CATEGORY, event, timestamp); } /* * End the previously started event */ void perfetto_trace_event_end(uint64_t timestamp) { TRACE_EVENT_END(LOCKING_CATEGORY, timestamp); } void perfetto_init(void) { perfetto::TracingInitArgs args; args.backends |= perfetto::kInProcessBackend; perfetto::Tracing::Initialize(args); perfetto::TrackEvent::Register(); } void perfetto_trace(void (*work)(void), char *tracefile) { auto tracing_session = StartTracing(); perfetto::ProcessTrack process_track = perfetto::ProcessTrack::Current(); perfetto::protos::gen::TrackDescriptor desc = process_track.Serialize(); desc.mutable_process()->set_process_name("Process"); perfetto::TrackEvent::SetTrackDescriptor(process_track, desc); work(); StopTracing(std::move(tracing_session), tracefile); }