/* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "perfetto/public/abi/tracing_session_abi.h" #include #include #include "perfetto/tracing/tracing.h" #include "protos/perfetto/config/trace_config.gen.h" struct PerfettoTracingSessionImpl* PerfettoTracingSessionSystemCreate() { std::unique_ptr tracing_session = perfetto::Tracing::NewTrace(perfetto::kSystemBackend); return reinterpret_cast( tracing_session.release()); } struct PerfettoTracingSessionImpl* PerfettoTracingSessionInProcessCreate() { std::unique_ptr tracing_session = perfetto::Tracing::NewTrace(perfetto::kInProcessBackend); return reinterpret_cast( tracing_session.release()); } void PerfettoTracingSessionSetup(struct PerfettoTracingSessionImpl* session, void* cfg_begin, size_t cfg_len) { auto* ts = reinterpret_cast(session); perfetto::TraceConfig cfg; cfg.ParseFromArray(cfg_begin, cfg_len); ts->Setup(cfg); } void PerfettoTracingSessionSetStopCb(struct PerfettoTracingSessionImpl* session, PerfettoTracingSessionStopCb cb, void* user_arg) { auto* ts = reinterpret_cast(session); ts->SetOnStopCallback([session, cb, user_arg]() { cb(session, user_arg); }); } void PerfettoTracingSessionStartAsync( struct PerfettoTracingSessionImpl* session) { auto* ts = reinterpret_cast(session); ts->Start(); } void PerfettoTracingSessionStartBlocking( struct PerfettoTracingSessionImpl* session) { auto* ts = reinterpret_cast(session); ts->StartBlocking(); } void PerfettoTracingSessionFlushAsync( struct PerfettoTracingSessionImpl* session, uint32_t timeout_ms, PerfettoTracingSessionFlushCb cb, void* user_arg) { auto* ts = reinterpret_cast(session); std::function flush_cb = [](bool) {}; if (cb) { flush_cb = [cb, session, user_arg](bool success) { cb(session, success, user_arg); }; } ts->Flush(std::move(flush_cb), timeout_ms); } bool PerfettoTracingSessionFlushBlocking( struct PerfettoTracingSessionImpl* session, uint32_t timeout_ms) { auto* ts = reinterpret_cast(session); return ts->FlushBlocking(timeout_ms); } void PerfettoTracingSessionStopAsync( struct PerfettoTracingSessionImpl* session) { auto* ts = reinterpret_cast(session); ts->Stop(); } void PerfettoTracingSessionStopBlocking( struct PerfettoTracingSessionImpl* session) { auto* ts = reinterpret_cast(session); ts->StopBlocking(); } void PerfettoTracingSessionReadTraceBlocking( struct PerfettoTracingSessionImpl* session, PerfettoTracingSessionReadCb callback, void* user_arg) { auto* ts = reinterpret_cast(session); std::mutex mutex; std::condition_variable cv; bool all_read = false; ts->ReadTrace([&mutex, &all_read, &cv, session, callback, user_arg]( perfetto::TracingSession::ReadTraceCallbackArgs args) { callback(session, static_cast(args.data), args.size, args.has_more, user_arg); std::unique_lock lock(mutex); all_read = !args.has_more; if (all_read) cv.notify_one(); }); { std::unique_lock lock(mutex); cv.wait(lock, [&all_read] { return all_read; }); } } void PerfettoTracingSessionDestroy(struct PerfettoTracingSessionImpl* session) { auto* ts = reinterpret_cast(session); delete ts; }