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