xref: /aosp_15_r20/external/perfetto/src/tracing/tracing.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker /*
2*6dbdd20aSAndroid Build Coastguard Worker  * Copyright (C) 2019 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/tracing/tracing.h"
18*6dbdd20aSAndroid Build Coastguard Worker 
19*6dbdd20aSAndroid Build Coastguard Worker #include <atomic>
20*6dbdd20aSAndroid Build Coastguard Worker #include <condition_variable>
21*6dbdd20aSAndroid Build Coastguard Worker #include <mutex>
22*6dbdd20aSAndroid Build Coastguard Worker 
23*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/time.h"
24*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/no_destructor.h"
25*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/waitable_event.h"
26*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/tracing/internal/track_event_internal.h"
27*6dbdd20aSAndroid Build Coastguard Worker #include "src/tracing/internal/tracing_muxer_impl.h"
28*6dbdd20aSAndroid Build Coastguard Worker 
29*6dbdd20aSAndroid Build Coastguard Worker namespace perfetto {
30*6dbdd20aSAndroid Build Coastguard Worker namespace {
31*6dbdd20aSAndroid Build Coastguard Worker bool g_was_initialized = false;
32*6dbdd20aSAndroid Build Coastguard Worker 
33*6dbdd20aSAndroid Build Coastguard Worker // Wrapped in a function to avoid global constructor
InitializedMutex()34*6dbdd20aSAndroid Build Coastguard Worker std::mutex& InitializedMutex() {
35*6dbdd20aSAndroid Build Coastguard Worker   static base::NoDestructor<std::mutex> initialized_mutex;
36*6dbdd20aSAndroid Build Coastguard Worker   return initialized_mutex.ref();
37*6dbdd20aSAndroid Build Coastguard Worker }
38*6dbdd20aSAndroid Build Coastguard Worker }  // namespace
39*6dbdd20aSAndroid Build Coastguard Worker 
40*6dbdd20aSAndroid Build Coastguard Worker // static
InitializeInternal(const TracingInitArgs & args)41*6dbdd20aSAndroid Build Coastguard Worker void Tracing::InitializeInternal(const TracingInitArgs& args) {
42*6dbdd20aSAndroid Build Coastguard Worker   base::InitializeTime();
43*6dbdd20aSAndroid Build Coastguard Worker   std::unique_lock<std::mutex> lock(InitializedMutex());
44*6dbdd20aSAndroid Build Coastguard Worker   // If it's the first time Initialize is called, set some global params.
45*6dbdd20aSAndroid Build Coastguard Worker   if (!g_was_initialized) {
46*6dbdd20aSAndroid Build Coastguard Worker     // Make sure the headers and implementation files agree on the build config.
47*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_CHECK(args.dcheck_is_on_ == PERFETTO_DCHECK_IS_ON());
48*6dbdd20aSAndroid Build Coastguard Worker     if (args.log_message_callback) {
49*6dbdd20aSAndroid Build Coastguard Worker       base::SetLogMessageCallback(args.log_message_callback);
50*6dbdd20aSAndroid Build Coastguard Worker     }
51*6dbdd20aSAndroid Build Coastguard Worker 
52*6dbdd20aSAndroid Build Coastguard Worker     if (args.use_monotonic_clock) {
53*6dbdd20aSAndroid Build Coastguard Worker       PERFETTO_CHECK(!args.use_monotonic_raw_clock);
54*6dbdd20aSAndroid Build Coastguard Worker       internal::TrackEventInternal::SetClockId(
55*6dbdd20aSAndroid Build Coastguard Worker           protos::pbzero::BUILTIN_CLOCK_MONOTONIC);
56*6dbdd20aSAndroid Build Coastguard Worker     } else if (args.use_monotonic_raw_clock) {
57*6dbdd20aSAndroid Build Coastguard Worker       internal::TrackEventInternal::SetClockId(
58*6dbdd20aSAndroid Build Coastguard Worker           protos::pbzero::BUILTIN_CLOCK_MONOTONIC_RAW);
59*6dbdd20aSAndroid Build Coastguard Worker     }
60*6dbdd20aSAndroid Build Coastguard Worker 
61*6dbdd20aSAndroid Build Coastguard Worker     if (args.disallow_merging_with_system_tracks) {
62*6dbdd20aSAndroid Build Coastguard Worker       internal::TrackEventInternal::SetDisallowMergingWithSystemTracks(true);
63*6dbdd20aSAndroid Build Coastguard Worker     }
64*6dbdd20aSAndroid Build Coastguard Worker   }
65*6dbdd20aSAndroid Build Coastguard Worker 
66*6dbdd20aSAndroid Build Coastguard Worker   internal::TracingMuxerImpl::InitializeInstance(args);
67*6dbdd20aSAndroid Build Coastguard Worker   internal::TrackRegistry::InitializeInstance();
68*6dbdd20aSAndroid Build Coastguard Worker   g_was_initialized = true;
69*6dbdd20aSAndroid Build Coastguard Worker }
70*6dbdd20aSAndroid Build Coastguard Worker 
71*6dbdd20aSAndroid Build Coastguard Worker // static
IsInitialized()72*6dbdd20aSAndroid Build Coastguard Worker bool Tracing::IsInitialized() {
73*6dbdd20aSAndroid Build Coastguard Worker   std::unique_lock<std::mutex> lock(InitializedMutex());
74*6dbdd20aSAndroid Build Coastguard Worker   return g_was_initialized;
75*6dbdd20aSAndroid Build Coastguard Worker }
76*6dbdd20aSAndroid Build Coastguard Worker 
77*6dbdd20aSAndroid Build Coastguard Worker // static
Shutdown()78*6dbdd20aSAndroid Build Coastguard Worker void Tracing::Shutdown() {
79*6dbdd20aSAndroid Build Coastguard Worker   std::unique_lock<std::mutex> lock(InitializedMutex());
80*6dbdd20aSAndroid Build Coastguard Worker   if (!g_was_initialized)
81*6dbdd20aSAndroid Build Coastguard Worker     return;
82*6dbdd20aSAndroid Build Coastguard Worker   internal::TracingMuxerImpl::Shutdown();
83*6dbdd20aSAndroid Build Coastguard Worker   g_was_initialized = false;
84*6dbdd20aSAndroid Build Coastguard Worker }
85*6dbdd20aSAndroid Build Coastguard Worker 
86*6dbdd20aSAndroid Build Coastguard Worker // static
ResetForTesting()87*6dbdd20aSAndroid Build Coastguard Worker void Tracing::ResetForTesting() {
88*6dbdd20aSAndroid Build Coastguard Worker   std::unique_lock<std::mutex> lock(InitializedMutex());
89*6dbdd20aSAndroid Build Coastguard Worker   if (!g_was_initialized)
90*6dbdd20aSAndroid Build Coastguard Worker     return;
91*6dbdd20aSAndroid Build Coastguard Worker   base::SetLogMessageCallback(nullptr);
92*6dbdd20aSAndroid Build Coastguard Worker   internal::TracingMuxerImpl::ResetForTesting();
93*6dbdd20aSAndroid Build Coastguard Worker   internal::TrackRegistry::ResetForTesting();
94*6dbdd20aSAndroid Build Coastguard Worker   g_was_initialized = false;
95*6dbdd20aSAndroid Build Coastguard Worker }
96*6dbdd20aSAndroid Build Coastguard Worker 
97*6dbdd20aSAndroid Build Coastguard Worker //  static
NewTraceInternal(BackendType backend,TracingConsumerBackend * (* system_backend_factory)())98*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<TracingSession> Tracing::NewTraceInternal(
99*6dbdd20aSAndroid Build Coastguard Worker     BackendType backend,
100*6dbdd20aSAndroid Build Coastguard Worker     TracingConsumerBackend* (*system_backend_factory)()) {
101*6dbdd20aSAndroid Build Coastguard Worker   return static_cast<internal::TracingMuxerImpl*>(internal::TracingMuxer::Get())
102*6dbdd20aSAndroid Build Coastguard Worker       ->CreateTracingSession(backend, system_backend_factory);
103*6dbdd20aSAndroid Build Coastguard Worker }
104*6dbdd20aSAndroid Build Coastguard Worker 
105*6dbdd20aSAndroid Build Coastguard Worker //  static
SetupStartupTracing(const TraceConfig & config,Tracing::SetupStartupTracingOpts opts)106*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<StartupTracingSession> Tracing::SetupStartupTracing(
107*6dbdd20aSAndroid Build Coastguard Worker     const TraceConfig& config,
108*6dbdd20aSAndroid Build Coastguard Worker     Tracing::SetupStartupTracingOpts opts) {
109*6dbdd20aSAndroid Build Coastguard Worker   return static_cast<internal::TracingMuxerImpl*>(internal::TracingMuxer::Get())
110*6dbdd20aSAndroid Build Coastguard Worker       ->CreateStartupTracingSession(config, std::move(opts));
111*6dbdd20aSAndroid Build Coastguard Worker }
112*6dbdd20aSAndroid Build Coastguard Worker 
113*6dbdd20aSAndroid Build Coastguard Worker //  static
SetupStartupTracingBlocking(const TraceConfig & config,Tracing::SetupStartupTracingOpts opts)114*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<StartupTracingSession> Tracing::SetupStartupTracingBlocking(
115*6dbdd20aSAndroid Build Coastguard Worker     const TraceConfig& config,
116*6dbdd20aSAndroid Build Coastguard Worker     Tracing::SetupStartupTracingOpts opts) {
117*6dbdd20aSAndroid Build Coastguard Worker   return static_cast<internal::TracingMuxerImpl*>(internal::TracingMuxer::Get())
118*6dbdd20aSAndroid Build Coastguard Worker       ->CreateStartupTracingSessionBlocking(config, std::move(opts));
119*6dbdd20aSAndroid Build Coastguard Worker }
120*6dbdd20aSAndroid Build Coastguard Worker 
121*6dbdd20aSAndroid Build Coastguard Worker //  static
ActivateTriggers(const std::vector<std::string> & triggers,uint32_t ttl_ms)122*6dbdd20aSAndroid Build Coastguard Worker void Tracing::ActivateTriggers(const std::vector<std::string>& triggers,
123*6dbdd20aSAndroid Build Coastguard Worker                                uint32_t ttl_ms) {
124*6dbdd20aSAndroid Build Coastguard Worker   internal::TracingMuxer::Get()->ActivateTriggers(triggers, ttl_ms);
125*6dbdd20aSAndroid Build Coastguard Worker }
126*6dbdd20aSAndroid Build Coastguard Worker 
127*6dbdd20aSAndroid Build Coastguard Worker TracingSession::~TracingSession() = default;
128*6dbdd20aSAndroid Build Coastguard Worker 
CloneTrace(CloneTraceArgs,CloneTraceCallback)129*6dbdd20aSAndroid Build Coastguard Worker void TracingSession::CloneTrace(CloneTraceArgs, CloneTraceCallback) {}
130*6dbdd20aSAndroid Build Coastguard Worker 
131*6dbdd20aSAndroid Build Coastguard Worker // Can be called from any thread.
FlushBlocking(uint32_t timeout_ms)132*6dbdd20aSAndroid Build Coastguard Worker bool TracingSession::FlushBlocking(uint32_t timeout_ms) {
133*6dbdd20aSAndroid Build Coastguard Worker   std::atomic<bool> flush_result;
134*6dbdd20aSAndroid Build Coastguard Worker   base::WaitableEvent flush_ack;
135*6dbdd20aSAndroid Build Coastguard Worker 
136*6dbdd20aSAndroid Build Coastguard Worker   // The non blocking Flush() can be called on any thread. It does the PostTask
137*6dbdd20aSAndroid Build Coastguard Worker   // internally.
138*6dbdd20aSAndroid Build Coastguard Worker   Flush(
139*6dbdd20aSAndroid Build Coastguard Worker       [&flush_ack, &flush_result](bool res) {
140*6dbdd20aSAndroid Build Coastguard Worker         flush_result = res;
141*6dbdd20aSAndroid Build Coastguard Worker         flush_ack.Notify();
142*6dbdd20aSAndroid Build Coastguard Worker       },
143*6dbdd20aSAndroid Build Coastguard Worker       timeout_ms);
144*6dbdd20aSAndroid Build Coastguard Worker   flush_ack.Wait();
145*6dbdd20aSAndroid Build Coastguard Worker   return flush_result;
146*6dbdd20aSAndroid Build Coastguard Worker }
147*6dbdd20aSAndroid Build Coastguard Worker 
ReadTraceBlocking()148*6dbdd20aSAndroid Build Coastguard Worker std::vector<char> TracingSession::ReadTraceBlocking() {
149*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace;
150*6dbdd20aSAndroid Build Coastguard Worker   std::mutex mutex;
151*6dbdd20aSAndroid Build Coastguard Worker   std::condition_variable cv;
152*6dbdd20aSAndroid Build Coastguard Worker 
153*6dbdd20aSAndroid Build Coastguard Worker   bool all_read = false;
154*6dbdd20aSAndroid Build Coastguard Worker 
155*6dbdd20aSAndroid Build Coastguard Worker   ReadTrace([&mutex, &raw_trace, &all_read, &cv](ReadTraceCallbackArgs cb) {
156*6dbdd20aSAndroid Build Coastguard Worker     raw_trace.insert(raw_trace.end(), cb.data, cb.data + cb.size);
157*6dbdd20aSAndroid Build Coastguard Worker     std::unique_lock<std::mutex> lock(mutex);
158*6dbdd20aSAndroid Build Coastguard Worker     all_read = !cb.has_more;
159*6dbdd20aSAndroid Build Coastguard Worker     if (all_read)
160*6dbdd20aSAndroid Build Coastguard Worker       cv.notify_one();
161*6dbdd20aSAndroid Build Coastguard Worker   });
162*6dbdd20aSAndroid Build Coastguard Worker 
163*6dbdd20aSAndroid Build Coastguard Worker   {
164*6dbdd20aSAndroid Build Coastguard Worker     std::unique_lock<std::mutex> lock(mutex);
165*6dbdd20aSAndroid Build Coastguard Worker     cv.wait(lock, [&all_read] { return all_read; });
166*6dbdd20aSAndroid Build Coastguard Worker   }
167*6dbdd20aSAndroid Build Coastguard Worker   return raw_trace;
168*6dbdd20aSAndroid Build Coastguard Worker }
169*6dbdd20aSAndroid Build Coastguard Worker 
170*6dbdd20aSAndroid Build Coastguard Worker TracingSession::GetTraceStatsCallbackArgs
GetTraceStatsBlocking()171*6dbdd20aSAndroid Build Coastguard Worker TracingSession::GetTraceStatsBlocking() {
172*6dbdd20aSAndroid Build Coastguard Worker   std::mutex mutex;
173*6dbdd20aSAndroid Build Coastguard Worker   std::condition_variable cv;
174*6dbdd20aSAndroid Build Coastguard Worker   GetTraceStatsCallbackArgs result;
175*6dbdd20aSAndroid Build Coastguard Worker   bool stats_read = false;
176*6dbdd20aSAndroid Build Coastguard Worker 
177*6dbdd20aSAndroid Build Coastguard Worker   GetTraceStats(
178*6dbdd20aSAndroid Build Coastguard Worker       [&mutex, &result, &stats_read, &cv](GetTraceStatsCallbackArgs args) {
179*6dbdd20aSAndroid Build Coastguard Worker         result = std::move(args);
180*6dbdd20aSAndroid Build Coastguard Worker         std::unique_lock<std::mutex> lock(mutex);
181*6dbdd20aSAndroid Build Coastguard Worker         stats_read = true;
182*6dbdd20aSAndroid Build Coastguard Worker         cv.notify_one();
183*6dbdd20aSAndroid Build Coastguard Worker       });
184*6dbdd20aSAndroid Build Coastguard Worker 
185*6dbdd20aSAndroid Build Coastguard Worker   {
186*6dbdd20aSAndroid Build Coastguard Worker     std::unique_lock<std::mutex> lock(mutex);
187*6dbdd20aSAndroid Build Coastguard Worker     cv.wait(lock, [&stats_read] { return stats_read; });
188*6dbdd20aSAndroid Build Coastguard Worker   }
189*6dbdd20aSAndroid Build Coastguard Worker   return result;
190*6dbdd20aSAndroid Build Coastguard Worker }
191*6dbdd20aSAndroid Build Coastguard Worker 
192*6dbdd20aSAndroid Build Coastguard Worker TracingSession::QueryServiceStateCallbackArgs
QueryServiceStateBlocking()193*6dbdd20aSAndroid Build Coastguard Worker TracingSession::QueryServiceStateBlocking() {
194*6dbdd20aSAndroid Build Coastguard Worker   std::mutex mutex;
195*6dbdd20aSAndroid Build Coastguard Worker   std::condition_variable cv;
196*6dbdd20aSAndroid Build Coastguard Worker   QueryServiceStateCallbackArgs result;
197*6dbdd20aSAndroid Build Coastguard Worker   bool status_read = false;
198*6dbdd20aSAndroid Build Coastguard Worker 
199*6dbdd20aSAndroid Build Coastguard Worker   QueryServiceState(
200*6dbdd20aSAndroid Build Coastguard Worker       [&mutex, &result, &status_read, &cv](QueryServiceStateCallbackArgs args) {
201*6dbdd20aSAndroid Build Coastguard Worker         result = std::move(args);
202*6dbdd20aSAndroid Build Coastguard Worker         std::unique_lock<std::mutex> lock(mutex);
203*6dbdd20aSAndroid Build Coastguard Worker         status_read = true;
204*6dbdd20aSAndroid Build Coastguard Worker         cv.notify_one();
205*6dbdd20aSAndroid Build Coastguard Worker       });
206*6dbdd20aSAndroid Build Coastguard Worker 
207*6dbdd20aSAndroid Build Coastguard Worker   {
208*6dbdd20aSAndroid Build Coastguard Worker     std::unique_lock<std::mutex> lock(mutex);
209*6dbdd20aSAndroid Build Coastguard Worker     cv.wait(lock, [&status_read] { return status_read; });
210*6dbdd20aSAndroid Build Coastguard Worker   }
211*6dbdd20aSAndroid Build Coastguard Worker   return result;
212*6dbdd20aSAndroid Build Coastguard Worker }
213*6dbdd20aSAndroid Build Coastguard Worker 
214*6dbdd20aSAndroid Build Coastguard Worker StartupTracingSession::~StartupTracingSession() = default;
215*6dbdd20aSAndroid Build Coastguard Worker 
216*6dbdd20aSAndroid Build Coastguard Worker }  // namespace perfetto
217