1*6dbdd20aSAndroid Build Coastguard Worker /*
2*6dbdd20aSAndroid Build Coastguard Worker * Copyright (C) 2022 The Android Open Source Project
3*6dbdd20aSAndroid Build Coastguard Worker *
4*6dbdd20aSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*6dbdd20aSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*6dbdd20aSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*6dbdd20aSAndroid Build Coastguard Worker *
8*6dbdd20aSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*6dbdd20aSAndroid Build Coastguard Worker *
10*6dbdd20aSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*6dbdd20aSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*6dbdd20aSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*6dbdd20aSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*6dbdd20aSAndroid Build Coastguard Worker * limitations under the License.
15*6dbdd20aSAndroid Build Coastguard Worker */
16*6dbdd20aSAndroid Build Coastguard Worker
17*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/public/abi/tracing_session_abi.h"
18*6dbdd20aSAndroid Build Coastguard Worker
19*6dbdd20aSAndroid Build Coastguard Worker #include <condition_variable>
20*6dbdd20aSAndroid Build Coastguard Worker #include <mutex>
21*6dbdd20aSAndroid Build Coastguard Worker
22*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/tracing/tracing.h"
23*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/config/trace_config.gen.h"
24*6dbdd20aSAndroid Build Coastguard Worker
PerfettoTracingSessionSystemCreate()25*6dbdd20aSAndroid Build Coastguard Worker struct PerfettoTracingSessionImpl* PerfettoTracingSessionSystemCreate() {
26*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<perfetto::TracingSession> tracing_session =
27*6dbdd20aSAndroid Build Coastguard Worker perfetto::Tracing::NewTrace(perfetto::kSystemBackend);
28*6dbdd20aSAndroid Build Coastguard Worker return reinterpret_cast<struct PerfettoTracingSessionImpl*>(
29*6dbdd20aSAndroid Build Coastguard Worker tracing_session.release());
30*6dbdd20aSAndroid Build Coastguard Worker }
31*6dbdd20aSAndroid Build Coastguard Worker
PerfettoTracingSessionInProcessCreate()32*6dbdd20aSAndroid Build Coastguard Worker struct PerfettoTracingSessionImpl* PerfettoTracingSessionInProcessCreate() {
33*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<perfetto::TracingSession> tracing_session =
34*6dbdd20aSAndroid Build Coastguard Worker perfetto::Tracing::NewTrace(perfetto::kInProcessBackend);
35*6dbdd20aSAndroid Build Coastguard Worker return reinterpret_cast<struct PerfettoTracingSessionImpl*>(
36*6dbdd20aSAndroid Build Coastguard Worker tracing_session.release());
37*6dbdd20aSAndroid Build Coastguard Worker }
38*6dbdd20aSAndroid Build Coastguard Worker
PerfettoTracingSessionSetup(struct PerfettoTracingSessionImpl * session,void * cfg_begin,size_t cfg_len)39*6dbdd20aSAndroid Build Coastguard Worker void PerfettoTracingSessionSetup(struct PerfettoTracingSessionImpl* session,
40*6dbdd20aSAndroid Build Coastguard Worker void* cfg_begin,
41*6dbdd20aSAndroid Build Coastguard Worker size_t cfg_len) {
42*6dbdd20aSAndroid Build Coastguard Worker auto* ts = reinterpret_cast<perfetto::TracingSession*>(session);
43*6dbdd20aSAndroid Build Coastguard Worker perfetto::TraceConfig cfg;
44*6dbdd20aSAndroid Build Coastguard Worker cfg.ParseFromArray(cfg_begin, cfg_len);
45*6dbdd20aSAndroid Build Coastguard Worker ts->Setup(cfg);
46*6dbdd20aSAndroid Build Coastguard Worker }
47*6dbdd20aSAndroid Build Coastguard Worker
PerfettoTracingSessionSetStopCb(struct PerfettoTracingSessionImpl * session,PerfettoTracingSessionStopCb cb,void * user_arg)48*6dbdd20aSAndroid Build Coastguard Worker void PerfettoTracingSessionSetStopCb(struct PerfettoTracingSessionImpl* session,
49*6dbdd20aSAndroid Build Coastguard Worker PerfettoTracingSessionStopCb cb,
50*6dbdd20aSAndroid Build Coastguard Worker void* user_arg) {
51*6dbdd20aSAndroid Build Coastguard Worker auto* ts = reinterpret_cast<perfetto::TracingSession*>(session);
52*6dbdd20aSAndroid Build Coastguard Worker ts->SetOnStopCallback([session, cb, user_arg]() { cb(session, user_arg); });
53*6dbdd20aSAndroid Build Coastguard Worker }
54*6dbdd20aSAndroid Build Coastguard Worker
PerfettoTracingSessionStartAsync(struct PerfettoTracingSessionImpl * session)55*6dbdd20aSAndroid Build Coastguard Worker void PerfettoTracingSessionStartAsync(
56*6dbdd20aSAndroid Build Coastguard Worker struct PerfettoTracingSessionImpl* session) {
57*6dbdd20aSAndroid Build Coastguard Worker auto* ts = reinterpret_cast<perfetto::TracingSession*>(session);
58*6dbdd20aSAndroid Build Coastguard Worker ts->Start();
59*6dbdd20aSAndroid Build Coastguard Worker }
60*6dbdd20aSAndroid Build Coastguard Worker
PerfettoTracingSessionStartBlocking(struct PerfettoTracingSessionImpl * session)61*6dbdd20aSAndroid Build Coastguard Worker void PerfettoTracingSessionStartBlocking(
62*6dbdd20aSAndroid Build Coastguard Worker struct PerfettoTracingSessionImpl* session) {
63*6dbdd20aSAndroid Build Coastguard Worker auto* ts = reinterpret_cast<perfetto::TracingSession*>(session);
64*6dbdd20aSAndroid Build Coastguard Worker ts->StartBlocking();
65*6dbdd20aSAndroid Build Coastguard Worker }
66*6dbdd20aSAndroid Build Coastguard Worker
PerfettoTracingSessionFlushAsync(struct PerfettoTracingSessionImpl * session,uint32_t timeout_ms,PerfettoTracingSessionFlushCb cb,void * user_arg)67*6dbdd20aSAndroid Build Coastguard Worker void PerfettoTracingSessionFlushAsync(
68*6dbdd20aSAndroid Build Coastguard Worker struct PerfettoTracingSessionImpl* session,
69*6dbdd20aSAndroid Build Coastguard Worker uint32_t timeout_ms,
70*6dbdd20aSAndroid Build Coastguard Worker PerfettoTracingSessionFlushCb cb,
71*6dbdd20aSAndroid Build Coastguard Worker void* user_arg) {
72*6dbdd20aSAndroid Build Coastguard Worker auto* ts = reinterpret_cast<perfetto::TracingSession*>(session);
73*6dbdd20aSAndroid Build Coastguard Worker std::function<void(bool)> flush_cb = [](bool) {};
74*6dbdd20aSAndroid Build Coastguard Worker if (cb) {
75*6dbdd20aSAndroid Build Coastguard Worker flush_cb = [cb, session, user_arg](bool success) {
76*6dbdd20aSAndroid Build Coastguard Worker cb(session, success, user_arg);
77*6dbdd20aSAndroid Build Coastguard Worker };
78*6dbdd20aSAndroid Build Coastguard Worker }
79*6dbdd20aSAndroid Build Coastguard Worker ts->Flush(std::move(flush_cb), timeout_ms);
80*6dbdd20aSAndroid Build Coastguard Worker }
81*6dbdd20aSAndroid Build Coastguard Worker
PerfettoTracingSessionFlushBlocking(struct PerfettoTracingSessionImpl * session,uint32_t timeout_ms)82*6dbdd20aSAndroid Build Coastguard Worker bool PerfettoTracingSessionFlushBlocking(
83*6dbdd20aSAndroid Build Coastguard Worker struct PerfettoTracingSessionImpl* session,
84*6dbdd20aSAndroid Build Coastguard Worker uint32_t timeout_ms) {
85*6dbdd20aSAndroid Build Coastguard Worker auto* ts = reinterpret_cast<perfetto::TracingSession*>(session);
86*6dbdd20aSAndroid Build Coastguard Worker return ts->FlushBlocking(timeout_ms);
87*6dbdd20aSAndroid Build Coastguard Worker }
88*6dbdd20aSAndroid Build Coastguard Worker
PerfettoTracingSessionStopAsync(struct PerfettoTracingSessionImpl * session)89*6dbdd20aSAndroid Build Coastguard Worker void PerfettoTracingSessionStopAsync(
90*6dbdd20aSAndroid Build Coastguard Worker struct PerfettoTracingSessionImpl* session) {
91*6dbdd20aSAndroid Build Coastguard Worker auto* ts = reinterpret_cast<perfetto::TracingSession*>(session);
92*6dbdd20aSAndroid Build Coastguard Worker ts->Stop();
93*6dbdd20aSAndroid Build Coastguard Worker }
94*6dbdd20aSAndroid Build Coastguard Worker
PerfettoTracingSessionStopBlocking(struct PerfettoTracingSessionImpl * session)95*6dbdd20aSAndroid Build Coastguard Worker void PerfettoTracingSessionStopBlocking(
96*6dbdd20aSAndroid Build Coastguard Worker struct PerfettoTracingSessionImpl* session) {
97*6dbdd20aSAndroid Build Coastguard Worker auto* ts = reinterpret_cast<perfetto::TracingSession*>(session);
98*6dbdd20aSAndroid Build Coastguard Worker ts->StopBlocking();
99*6dbdd20aSAndroid Build Coastguard Worker }
100*6dbdd20aSAndroid Build Coastguard Worker
PerfettoTracingSessionReadTraceBlocking(struct PerfettoTracingSessionImpl * session,PerfettoTracingSessionReadCb callback,void * user_arg)101*6dbdd20aSAndroid Build Coastguard Worker void PerfettoTracingSessionReadTraceBlocking(
102*6dbdd20aSAndroid Build Coastguard Worker struct PerfettoTracingSessionImpl* session,
103*6dbdd20aSAndroid Build Coastguard Worker PerfettoTracingSessionReadCb callback,
104*6dbdd20aSAndroid Build Coastguard Worker void* user_arg) {
105*6dbdd20aSAndroid Build Coastguard Worker auto* ts = reinterpret_cast<perfetto::TracingSession*>(session);
106*6dbdd20aSAndroid Build Coastguard Worker
107*6dbdd20aSAndroid Build Coastguard Worker std::mutex mutex;
108*6dbdd20aSAndroid Build Coastguard Worker std::condition_variable cv;
109*6dbdd20aSAndroid Build Coastguard Worker
110*6dbdd20aSAndroid Build Coastguard Worker bool all_read = false;
111*6dbdd20aSAndroid Build Coastguard Worker
112*6dbdd20aSAndroid Build Coastguard Worker ts->ReadTrace([&mutex, &all_read, &cv, session, callback, user_arg](
113*6dbdd20aSAndroid Build Coastguard Worker perfetto::TracingSession::ReadTraceCallbackArgs args) {
114*6dbdd20aSAndroid Build Coastguard Worker callback(session, static_cast<const void*>(args.data), args.size,
115*6dbdd20aSAndroid Build Coastguard Worker args.has_more, user_arg);
116*6dbdd20aSAndroid Build Coastguard Worker std::unique_lock<std::mutex> lock(mutex);
117*6dbdd20aSAndroid Build Coastguard Worker all_read = !args.has_more;
118*6dbdd20aSAndroid Build Coastguard Worker if (all_read)
119*6dbdd20aSAndroid Build Coastguard Worker cv.notify_one();
120*6dbdd20aSAndroid Build Coastguard Worker });
121*6dbdd20aSAndroid Build Coastguard Worker
122*6dbdd20aSAndroid Build Coastguard Worker {
123*6dbdd20aSAndroid Build Coastguard Worker std::unique_lock<std::mutex> lock(mutex);
124*6dbdd20aSAndroid Build Coastguard Worker cv.wait(lock, [&all_read] { return all_read; });
125*6dbdd20aSAndroid Build Coastguard Worker }
126*6dbdd20aSAndroid Build Coastguard Worker }
127*6dbdd20aSAndroid Build Coastguard Worker
PerfettoTracingSessionDestroy(struct PerfettoTracingSessionImpl * session)128*6dbdd20aSAndroid Build Coastguard Worker void PerfettoTracingSessionDestroy(struct PerfettoTracingSessionImpl* session) {
129*6dbdd20aSAndroid Build Coastguard Worker auto* ts = reinterpret_cast<perfetto::TracingSession*>(session);
130*6dbdd20aSAndroid Build Coastguard Worker delete ts;
131*6dbdd20aSAndroid Build Coastguard Worker }
132