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