• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
PerfettoTracingSessionStartAsync(struct PerfettoTracingSessionImpl * session)48 void PerfettoTracingSessionStartAsync(
49     struct PerfettoTracingSessionImpl* session) {
50   auto* ts = reinterpret_cast<perfetto::TracingSession*>(session);
51   ts->Start();
52 }
53 
PerfettoTracingSessionStartBlocking(struct PerfettoTracingSessionImpl * session)54 void PerfettoTracingSessionStartBlocking(
55     struct PerfettoTracingSessionImpl* session) {
56   auto* ts = reinterpret_cast<perfetto::TracingSession*>(session);
57   ts->StartBlocking();
58 }
59 
PerfettoTracingSessionStopAsync(struct PerfettoTracingSessionImpl * session)60 void PerfettoTracingSessionStopAsync(
61     struct PerfettoTracingSessionImpl* session) {
62   auto* ts = reinterpret_cast<perfetto::TracingSession*>(session);
63   ts->Stop();
64 }
65 
PerfettoTracingSessionStopBlocking(struct PerfettoTracingSessionImpl * session)66 void PerfettoTracingSessionStopBlocking(
67     struct PerfettoTracingSessionImpl* session) {
68   auto* ts = reinterpret_cast<perfetto::TracingSession*>(session);
69   ts->StopBlocking();
70 }
71 
PerfettoTracingSessionReadTraceBlocking(struct PerfettoTracingSessionImpl * session,PerfettoTracingSessionReadCb callback,void * user_arg)72 void PerfettoTracingSessionReadTraceBlocking(
73     struct PerfettoTracingSessionImpl* session,
74     PerfettoTracingSessionReadCb callback,
75     void* user_arg) {
76   auto* ts = reinterpret_cast<perfetto::TracingSession*>(session);
77 
78   std::mutex mutex;
79   std::condition_variable cv;
80 
81   bool all_read = false;
82 
83   ts->ReadTrace([&mutex, &all_read, &cv, session, callback, user_arg](
84                     perfetto::TracingSession::ReadTraceCallbackArgs args) {
85     callback(session, static_cast<const void*>(args.data), args.size,
86              args.has_more, user_arg);
87     std::unique_lock<std::mutex> lock(mutex);
88     all_read = !args.has_more;
89     if (all_read)
90       cv.notify_one();
91   });
92 
93   {
94     std::unique_lock<std::mutex> lock(mutex);
95     cv.wait(lock, [&all_read] { return all_read; });
96   }
97 }
98 
PerfettoTracingSessionDestroy(struct PerfettoTracingSessionImpl * session)99 void PerfettoTracingSessionDestroy(struct PerfettoTracingSessionImpl* session) {
100   auto* ts = reinterpret_cast<perfetto::TracingSession*>(session);
101   delete ts;
102 }
103