blob: 313a88d1ca1372de39f66e2b3a51eb3c3e64d202 [file] [log] [blame]
/*
* 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 <condition_variable>
#include <mutex>
#include "perfetto/tracing/backend_type.h"
#include "perfetto/tracing/tracing.h"
#include "protos/perfetto/config/trace_config.gen.h"
struct PerfettoTracingSessionImpl* PerfettoTracingSessionCreate(
PerfettoBackendTypes backend) {
uint32_t backend_type = 0;
if (backend & PERFETTO_BACKEND_IN_PROCESS) {
backend_type |= perfetto::kInProcessBackend;
}
if (backend & PERFETTO_BACKEND_SYSTEM) {
backend_type |= perfetto::kSystemBackend;
}
std::unique_ptr<perfetto::TracingSession> tracing_session =
perfetto::Tracing::NewTrace(
static_cast<perfetto::BackendType>(backend_type));
return reinterpret_cast<struct PerfettoTracingSessionImpl*>(
tracing_session.release());
}
void PerfettoTracingSessionSetup(struct PerfettoTracingSessionImpl* session,
void* cfg_begin,
size_t cfg_len) {
auto* ts = reinterpret_cast<perfetto::TracingSession*>(session);
perfetto::TraceConfig cfg;
cfg.ParseFromArray(cfg_begin, cfg_len);
ts->Setup(cfg);
}
void PerfettoTracingSessionStartAsync(
struct PerfettoTracingSessionImpl* session) {
auto* ts = reinterpret_cast<perfetto::TracingSession*>(session);
ts->Start();
}
void PerfettoTracingSessionStartBlocking(
struct PerfettoTracingSessionImpl* session) {
auto* ts = reinterpret_cast<perfetto::TracingSession*>(session);
ts->StartBlocking();
}
void PerfettoTracingSessionStopAsync(
struct PerfettoTracingSessionImpl* session) {
auto* ts = reinterpret_cast<perfetto::TracingSession*>(session);
ts->Stop();
}
void PerfettoTracingSessionStopBlocking(
struct PerfettoTracingSessionImpl* session) {
auto* ts = reinterpret_cast<perfetto::TracingSession*>(session);
ts->StopBlocking();
}
void PerfettoTracingSessionReadTraceBlocking(
struct PerfettoTracingSessionImpl* session,
PerfettoTracingSessionReadCb callback,
void* user_arg) {
auto* ts = reinterpret_cast<perfetto::TracingSession*>(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<const void*>(args.data), args.size,
args.has_more, user_arg);
std::unique_lock<std::mutex> lock(mutex);
all_read = !args.has_more;
if (all_read)
cv.notify_one();
});
{
std::unique_lock<std::mutex> lock(mutex);
cv.wait(lock, [&all_read] { return all_read; });
}
}
void PerfettoTracingSessionDestroy(struct PerfettoTracingSessionImpl* session) {
auto* ts = reinterpret_cast<perfetto::TracingSession*>(session);
delete ts;
}