xref: /aosp_15_r20/external/perfetto/src/shared_lib/track_event.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker /*
2*6dbdd20aSAndroid Build Coastguard Worker  * Copyright (C) 2023 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/track_event_abi.h"
18*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/public/abi/track_event_hl_abi.h"
19*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/public/abi/track_event_ll_abi.h"
20*6dbdd20aSAndroid Build Coastguard Worker 
21*6dbdd20aSAndroid Build Coastguard Worker #include <algorithm>
22*6dbdd20aSAndroid Build Coastguard Worker #include <atomic>
23*6dbdd20aSAndroid Build Coastguard Worker #include <limits>
24*6dbdd20aSAndroid Build Coastguard Worker #include <mutex>
25*6dbdd20aSAndroid Build Coastguard Worker #include <optional>
26*6dbdd20aSAndroid Build Coastguard Worker 
27*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/compiler.h"
28*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/flat_set.h"
29*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/thread_annotations.h"
30*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/file_utils.h"
31*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/no_destructor.h"
32*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/string_splitter.h"
33*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/string_view.h"
34*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/thread_utils.h"
35*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/protozero/contiguous_memory_range.h"
36*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/public/compiler.h"
37*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/tracing/data_source.h"
38*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/tracing/internal/basic_types.h"
39*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/tracing/internal/data_source_internal.h"
40*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/tracing/internal/track_event_internal.h"
41*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/tracing/track.h"
42*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/common/data_source_descriptor.gen.h"
43*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/common/track_event_descriptor.pbzero.h"
44*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/config/data_source_config.gen.h"
45*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/config/track_event/track_event_config.gen.h"
46*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/clock_snapshot.pbzero.h"
47*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
48*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/trace_packet.pbzero.h"
49*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/trace_packet_defaults.pbzero.h"
50*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
51*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/track_event/process_descriptor.pbzero.h"
52*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/track_event/thread_descriptor.pbzero.h"
53*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
54*6dbdd20aSAndroid Build Coastguard Worker #include "src/shared_lib/intern_map.h"
55*6dbdd20aSAndroid Build Coastguard Worker #include "src/shared_lib/reset_for_testing.h"
56*6dbdd20aSAndroid Build Coastguard Worker 
57*6dbdd20aSAndroid Build Coastguard Worker struct PerfettoTeCategoryImpl* perfetto_te_any_categories;
58*6dbdd20aSAndroid Build Coastguard Worker 
59*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_ATOMIC(bool) * perfetto_te_any_categories_enabled;
60*6dbdd20aSAndroid Build Coastguard Worker 
61*6dbdd20aSAndroid Build Coastguard Worker uint64_t perfetto_te_process_track_uuid;
62*6dbdd20aSAndroid Build Coastguard Worker 
63*6dbdd20aSAndroid Build Coastguard Worker struct PerfettoTeCategoryImpl {
64*6dbdd20aSAndroid Build Coastguard Worker   std::atomic<bool> flag{false};
65*6dbdd20aSAndroid Build Coastguard Worker   std::atomic<uint8_t> instances{0};
66*6dbdd20aSAndroid Build Coastguard Worker   PerfettoTeCategoryDescriptor* desc = nullptr;
67*6dbdd20aSAndroid Build Coastguard Worker   uint64_t cat_iid = 0;
68*6dbdd20aSAndroid Build Coastguard Worker   PerfettoTeCategoryImplCallback cb = nullptr;
69*6dbdd20aSAndroid Build Coastguard Worker   void* cb_user_arg = nullptr;
70*6dbdd20aSAndroid Build Coastguard Worker };
71*6dbdd20aSAndroid Build Coastguard Worker 
72*6dbdd20aSAndroid Build Coastguard Worker enum class MatchType { kExact, kPattern };
73*6dbdd20aSAndroid Build Coastguard Worker 
NameMatchesPattern(const std::string & pattern,const perfetto::base::StringView & name,MatchType match_type)74*6dbdd20aSAndroid Build Coastguard Worker static bool NameMatchesPattern(const std::string& pattern,
75*6dbdd20aSAndroid Build Coastguard Worker                                const perfetto::base::StringView& name,
76*6dbdd20aSAndroid Build Coastguard Worker                                MatchType match_type) {
77*6dbdd20aSAndroid Build Coastguard Worker   // To avoid pulling in all of std::regex, for now we only support a single "*"
78*6dbdd20aSAndroid Build Coastguard Worker   // wildcard at the end of the pattern.
79*6dbdd20aSAndroid Build Coastguard Worker   size_t i = pattern.find('*');
80*6dbdd20aSAndroid Build Coastguard Worker   if (i != std::string::npos) {
81*6dbdd20aSAndroid Build Coastguard Worker     if (match_type != MatchType::kPattern)
82*6dbdd20aSAndroid Build Coastguard Worker       return false;
83*6dbdd20aSAndroid Build Coastguard Worker     return name.substr(0, i) ==
84*6dbdd20aSAndroid Build Coastguard Worker            perfetto::base::StringView(pattern).substr(0, i);
85*6dbdd20aSAndroid Build Coastguard Worker   }
86*6dbdd20aSAndroid Build Coastguard Worker   return name == perfetto::base::StringView(pattern);
87*6dbdd20aSAndroid Build Coastguard Worker }
88*6dbdd20aSAndroid Build Coastguard Worker 
NameMatchesPatternList(const std::vector<std::string> & patterns,const perfetto::base::StringView & name,MatchType match_type)89*6dbdd20aSAndroid Build Coastguard Worker static bool NameMatchesPatternList(const std::vector<std::string>& patterns,
90*6dbdd20aSAndroid Build Coastguard Worker                                    const perfetto::base::StringView& name,
91*6dbdd20aSAndroid Build Coastguard Worker                                    MatchType match_type) {
92*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& pattern : patterns) {
93*6dbdd20aSAndroid Build Coastguard Worker     if (NameMatchesPattern(pattern, name, match_type))
94*6dbdd20aSAndroid Build Coastguard Worker       return true;
95*6dbdd20aSAndroid Build Coastguard Worker   }
96*6dbdd20aSAndroid Build Coastguard Worker   return false;
97*6dbdd20aSAndroid Build Coastguard Worker }
98*6dbdd20aSAndroid Build Coastguard Worker 
IsSingleCategoryEnabled(const PerfettoTeCategoryDescriptor & c,const perfetto::protos::gen::TrackEventConfig & config)99*6dbdd20aSAndroid Build Coastguard Worker static bool IsSingleCategoryEnabled(
100*6dbdd20aSAndroid Build Coastguard Worker     const PerfettoTeCategoryDescriptor& c,
101*6dbdd20aSAndroid Build Coastguard Worker     const perfetto::protos::gen::TrackEventConfig& config) {
102*6dbdd20aSAndroid Build Coastguard Worker   auto has_matching_tag = [&](std::function<bool(const char*)> matcher) {
103*6dbdd20aSAndroid Build Coastguard Worker     for (size_t i = 0; i < c.num_tags; ++i) {
104*6dbdd20aSAndroid Build Coastguard Worker       if (matcher(c.tags[i]))
105*6dbdd20aSAndroid Build Coastguard Worker         return true;
106*6dbdd20aSAndroid Build Coastguard Worker     }
107*6dbdd20aSAndroid Build Coastguard Worker     return false;
108*6dbdd20aSAndroid Build Coastguard Worker   };
109*6dbdd20aSAndroid Build Coastguard Worker   // First try exact matches, then pattern matches.
110*6dbdd20aSAndroid Build Coastguard Worker   const std::array<MatchType, 2> match_types = {
111*6dbdd20aSAndroid Build Coastguard Worker       {MatchType::kExact, MatchType::kPattern}};
112*6dbdd20aSAndroid Build Coastguard Worker   for (auto match_type : match_types) {
113*6dbdd20aSAndroid Build Coastguard Worker     // 1. Enabled categories.
114*6dbdd20aSAndroid Build Coastguard Worker     if (NameMatchesPatternList(config.enabled_categories(), c.name,
115*6dbdd20aSAndroid Build Coastguard Worker                                match_type)) {
116*6dbdd20aSAndroid Build Coastguard Worker       return true;
117*6dbdd20aSAndroid Build Coastguard Worker     }
118*6dbdd20aSAndroid Build Coastguard Worker 
119*6dbdd20aSAndroid Build Coastguard Worker     // 2. Enabled tags.
120*6dbdd20aSAndroid Build Coastguard Worker     if (has_matching_tag([&](const char* tag) {
121*6dbdd20aSAndroid Build Coastguard Worker           return NameMatchesPatternList(config.enabled_tags(), tag, match_type);
122*6dbdd20aSAndroid Build Coastguard Worker         })) {
123*6dbdd20aSAndroid Build Coastguard Worker       return true;
124*6dbdd20aSAndroid Build Coastguard Worker     }
125*6dbdd20aSAndroid Build Coastguard Worker 
126*6dbdd20aSAndroid Build Coastguard Worker     // 3. Disabled categories.
127*6dbdd20aSAndroid Build Coastguard Worker     if (NameMatchesPatternList(config.disabled_categories(), c.name,
128*6dbdd20aSAndroid Build Coastguard Worker                                match_type)) {
129*6dbdd20aSAndroid Build Coastguard Worker       return false;
130*6dbdd20aSAndroid Build Coastguard Worker     }
131*6dbdd20aSAndroid Build Coastguard Worker 
132*6dbdd20aSAndroid Build Coastguard Worker     // 4. Disabled tags.
133*6dbdd20aSAndroid Build Coastguard Worker     if (has_matching_tag([&](const char* tag) {
134*6dbdd20aSAndroid Build Coastguard Worker           return NameMatchesPatternList(config.disabled_tags(), tag,
135*6dbdd20aSAndroid Build Coastguard Worker                                         match_type);
136*6dbdd20aSAndroid Build Coastguard Worker         })) {
137*6dbdd20aSAndroid Build Coastguard Worker       return false;
138*6dbdd20aSAndroid Build Coastguard Worker     }
139*6dbdd20aSAndroid Build Coastguard Worker   }
140*6dbdd20aSAndroid Build Coastguard Worker 
141*6dbdd20aSAndroid Build Coastguard Worker   // If nothing matched, the category is disabled by default. N.B. this behavior
142*6dbdd20aSAndroid Build Coastguard Worker   // is different than the C++ TrackEvent API.
143*6dbdd20aSAndroid Build Coastguard Worker   return false;
144*6dbdd20aSAndroid Build Coastguard Worker }
145*6dbdd20aSAndroid Build Coastguard Worker 
IsRegisteredCategoryEnabled(const PerfettoTeCategoryImpl & cat,const perfetto::protos::gen::TrackEventConfig & config)146*6dbdd20aSAndroid Build Coastguard Worker static bool IsRegisteredCategoryEnabled(
147*6dbdd20aSAndroid Build Coastguard Worker     const PerfettoTeCategoryImpl& cat,
148*6dbdd20aSAndroid Build Coastguard Worker     const perfetto::protos::gen::TrackEventConfig& config) {
149*6dbdd20aSAndroid Build Coastguard Worker   if (!cat.desc) {
150*6dbdd20aSAndroid Build Coastguard Worker     return false;
151*6dbdd20aSAndroid Build Coastguard Worker   }
152*6dbdd20aSAndroid Build Coastguard Worker   return IsSingleCategoryEnabled(*cat.desc, config);
153*6dbdd20aSAndroid Build Coastguard Worker }
154*6dbdd20aSAndroid Build Coastguard Worker 
EnableRegisteredCategory(PerfettoTeCategoryImpl * cat,uint32_t instance_index)155*6dbdd20aSAndroid Build Coastguard Worker static void EnableRegisteredCategory(PerfettoTeCategoryImpl* cat,
156*6dbdd20aSAndroid Build Coastguard Worker                                      uint32_t instance_index) {
157*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_DCHECK(instance_index < perfetto::internal::kMaxDataSourceInstances);
158*6dbdd20aSAndroid Build Coastguard Worker   // Matches the acquire_load in DataSource::Trace().
159*6dbdd20aSAndroid Build Coastguard Worker   uint8_t old = cat->instances.fetch_or(
160*6dbdd20aSAndroid Build Coastguard Worker       static_cast<uint8_t>(1u << instance_index), std::memory_order_release);
161*6dbdd20aSAndroid Build Coastguard Worker   bool global_state_changed = old == 0;
162*6dbdd20aSAndroid Build Coastguard Worker   if (global_state_changed) {
163*6dbdd20aSAndroid Build Coastguard Worker     cat->flag.store(true, std::memory_order_relaxed);
164*6dbdd20aSAndroid Build Coastguard Worker   }
165*6dbdd20aSAndroid Build Coastguard Worker   if (cat->cb) {
166*6dbdd20aSAndroid Build Coastguard Worker     cat->cb(cat, instance_index, /*created=*/true, global_state_changed,
167*6dbdd20aSAndroid Build Coastguard Worker             cat->cb_user_arg);
168*6dbdd20aSAndroid Build Coastguard Worker   }
169*6dbdd20aSAndroid Build Coastguard Worker }
170*6dbdd20aSAndroid Build Coastguard Worker 
DisableRegisteredCategory(PerfettoTeCategoryImpl * cat,uint32_t instance_index)171*6dbdd20aSAndroid Build Coastguard Worker static void DisableRegisteredCategory(PerfettoTeCategoryImpl* cat,
172*6dbdd20aSAndroid Build Coastguard Worker                                       uint32_t instance_index) {
173*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_DCHECK(instance_index < perfetto::internal::kMaxDataSourceInstances);
174*6dbdd20aSAndroid Build Coastguard Worker   // Matches the acquire_load in DataSource::Trace().
175*6dbdd20aSAndroid Build Coastguard Worker   cat->instances.fetch_and(static_cast<uint8_t>(~(1u << instance_index)),
176*6dbdd20aSAndroid Build Coastguard Worker                            std::memory_order_release);
177*6dbdd20aSAndroid Build Coastguard Worker   bool global_state_changed = false;
178*6dbdd20aSAndroid Build Coastguard Worker   if (!cat->instances.load(std::memory_order_relaxed)) {
179*6dbdd20aSAndroid Build Coastguard Worker     cat->flag.store(false, std::memory_order_relaxed);
180*6dbdd20aSAndroid Build Coastguard Worker     global_state_changed = true;
181*6dbdd20aSAndroid Build Coastguard Worker   }
182*6dbdd20aSAndroid Build Coastguard Worker   if (cat->cb) {
183*6dbdd20aSAndroid Build Coastguard Worker     cat->cb(cat, instance_index, /*created=*/false, global_state_changed,
184*6dbdd20aSAndroid Build Coastguard Worker             cat->cb_user_arg);
185*6dbdd20aSAndroid Build Coastguard Worker   }
186*6dbdd20aSAndroid Build Coastguard Worker }
187*6dbdd20aSAndroid Build Coastguard Worker 
SerializeCategory(const PerfettoTeCategoryDescriptor & desc,perfetto::protos::pbzero::TrackEventDescriptor * ted)188*6dbdd20aSAndroid Build Coastguard Worker static void SerializeCategory(
189*6dbdd20aSAndroid Build Coastguard Worker     const PerfettoTeCategoryDescriptor& desc,
190*6dbdd20aSAndroid Build Coastguard Worker     perfetto::protos::pbzero::TrackEventDescriptor* ted) {
191*6dbdd20aSAndroid Build Coastguard Worker   auto* c = ted->add_available_categories();
192*6dbdd20aSAndroid Build Coastguard Worker   c->set_name(desc.name);
193*6dbdd20aSAndroid Build Coastguard Worker   if (desc.desc)
194*6dbdd20aSAndroid Build Coastguard Worker     c->set_description(desc.desc);
195*6dbdd20aSAndroid Build Coastguard Worker   for (size_t j = 0; j < desc.num_tags; ++j) {
196*6dbdd20aSAndroid Build Coastguard Worker     c->add_tags(desc.tags[j]);
197*6dbdd20aSAndroid Build Coastguard Worker   }
198*6dbdd20aSAndroid Build Coastguard Worker }
199*6dbdd20aSAndroid Build Coastguard Worker 
200*6dbdd20aSAndroid Build Coastguard Worker namespace perfetto {
201*6dbdd20aSAndroid Build Coastguard Worker namespace shlib {
202*6dbdd20aSAndroid Build Coastguard Worker 
203*6dbdd20aSAndroid Build Coastguard Worker struct TrackEventIncrementalState {
204*6dbdd20aSAndroid Build Coastguard Worker   // A heap-allocated message for storing newly seen interned data while we are
205*6dbdd20aSAndroid Build Coastguard Worker   // in the middle of writing a track event. When a track event wants to write
206*6dbdd20aSAndroid Build Coastguard Worker   // new interned data into the trace, it is first serialized into this message
207*6dbdd20aSAndroid Build Coastguard Worker   // and then flushed to the real trace in EventContext when the packet ends.
208*6dbdd20aSAndroid Build Coastguard Worker   // The message is cached here as a part of incremental state so that we can
209*6dbdd20aSAndroid Build Coastguard Worker   // reuse the underlying buffer allocation for subsequently written interned
210*6dbdd20aSAndroid Build Coastguard Worker   // data.
211*6dbdd20aSAndroid Build Coastguard Worker   uint64_t last_timestamp_ns = 0;
212*6dbdd20aSAndroid Build Coastguard Worker   protozero::HeapBuffered<protos::pbzero::InternedData>
213*6dbdd20aSAndroid Build Coastguard Worker       serialized_interned_data;
214*6dbdd20aSAndroid Build Coastguard Worker   bool was_cleared = true;
215*6dbdd20aSAndroid Build Coastguard Worker   base::FlatSet<uint64_t> seen_track_uuids;
216*6dbdd20aSAndroid Build Coastguard Worker   // Map from serialized representation of a dynamic category to its enabled
217*6dbdd20aSAndroid Build Coastguard Worker   // state.
218*6dbdd20aSAndroid Build Coastguard Worker   base::FlatHashMap<std::string, bool> dynamic_categories;
219*6dbdd20aSAndroid Build Coastguard Worker   InternMap iids;
220*6dbdd20aSAndroid Build Coastguard Worker };
221*6dbdd20aSAndroid Build Coastguard Worker 
222*6dbdd20aSAndroid Build Coastguard Worker struct TrackEventTlsState {
223*6dbdd20aSAndroid Build Coastguard Worker   template <typename TraceContext>
TrackEventTlsStateperfetto::shlib::TrackEventTlsState224*6dbdd20aSAndroid Build Coastguard Worker   explicit TrackEventTlsState(const TraceContext& trace_context) {
225*6dbdd20aSAndroid Build Coastguard Worker     auto locked_ds = trace_context.GetDataSourceLocked();
226*6dbdd20aSAndroid Build Coastguard Worker     bool disable_incremental_timestamps = false;
227*6dbdd20aSAndroid Build Coastguard Worker     timestamp_unit_multiplier = 1;
228*6dbdd20aSAndroid Build Coastguard Worker     if (locked_ds.valid()) {
229*6dbdd20aSAndroid Build Coastguard Worker       const auto& config = locked_ds->GetConfig();
230*6dbdd20aSAndroid Build Coastguard Worker       disable_incremental_timestamps = config.disable_incremental_timestamps();
231*6dbdd20aSAndroid Build Coastguard Worker       if (config.has_timestamp_unit_multiplier() &&
232*6dbdd20aSAndroid Build Coastguard Worker           config.timestamp_unit_multiplier() != 0) {
233*6dbdd20aSAndroid Build Coastguard Worker         timestamp_unit_multiplier = config.timestamp_unit_multiplier();
234*6dbdd20aSAndroid Build Coastguard Worker       }
235*6dbdd20aSAndroid Build Coastguard Worker     }
236*6dbdd20aSAndroid Build Coastguard Worker     if (disable_incremental_timestamps) {
237*6dbdd20aSAndroid Build Coastguard Worker       if (timestamp_unit_multiplier == 1) {
238*6dbdd20aSAndroid Build Coastguard Worker         default_clock_id = PERFETTO_I_CLOCK_INCREMENTAL_UNDERNEATH;
239*6dbdd20aSAndroid Build Coastguard Worker       } else {
240*6dbdd20aSAndroid Build Coastguard Worker         default_clock_id = PERFETTO_TE_TIMESTAMP_TYPE_ABSOLUTE;
241*6dbdd20aSAndroid Build Coastguard Worker       }
242*6dbdd20aSAndroid Build Coastguard Worker     } else {
243*6dbdd20aSAndroid Build Coastguard Worker       default_clock_id = PERFETTO_TE_TIMESTAMP_TYPE_INCREMENTAL;
244*6dbdd20aSAndroid Build Coastguard Worker     }
245*6dbdd20aSAndroid Build Coastguard Worker   }
246*6dbdd20aSAndroid Build Coastguard Worker   uint32_t default_clock_id;
247*6dbdd20aSAndroid Build Coastguard Worker   uint64_t timestamp_unit_multiplier;
248*6dbdd20aSAndroid Build Coastguard Worker };
249*6dbdd20aSAndroid Build Coastguard Worker 
250*6dbdd20aSAndroid Build Coastguard Worker struct TrackEventDataSourceTraits : public perfetto::DefaultDataSourceTraits {
251*6dbdd20aSAndroid Build Coastguard Worker   using IncrementalStateType = TrackEventIncrementalState;
252*6dbdd20aSAndroid Build Coastguard Worker   using TlsStateType = TrackEventTlsState;
253*6dbdd20aSAndroid Build Coastguard Worker };
254*6dbdd20aSAndroid Build Coastguard Worker 
255*6dbdd20aSAndroid Build Coastguard Worker class TrackEvent
256*6dbdd20aSAndroid Build Coastguard Worker     : public perfetto::DataSource<TrackEvent, TrackEventDataSourceTraits> {
257*6dbdd20aSAndroid Build Coastguard Worker  public:
258*6dbdd20aSAndroid Build Coastguard Worker   ~TrackEvent() override;
OnSetup(const DataSourceBase::SetupArgs & args)259*6dbdd20aSAndroid Build Coastguard Worker   void OnSetup(const DataSourceBase::SetupArgs& args) override {
260*6dbdd20aSAndroid Build Coastguard Worker     const std::string& config_raw = args.config->track_event_config_raw();
261*6dbdd20aSAndroid Build Coastguard Worker     bool ok = config_.ParseFromArray(config_raw.data(), config_raw.size());
262*6dbdd20aSAndroid Build Coastguard Worker     if (!ok) {
263*6dbdd20aSAndroid Build Coastguard Worker       PERFETTO_LOG("Failed to parse config");
264*6dbdd20aSAndroid Build Coastguard Worker     }
265*6dbdd20aSAndroid Build Coastguard Worker     inst_id_ = args.internal_instance_index;
266*6dbdd20aSAndroid Build Coastguard Worker   }
267*6dbdd20aSAndroid Build Coastguard Worker 
OnStart(const DataSourceBase::StartArgs &)268*6dbdd20aSAndroid Build Coastguard Worker   void OnStart(const DataSourceBase::StartArgs&) override {
269*6dbdd20aSAndroid Build Coastguard Worker     GlobalState::Instance().OnStart(config_, inst_id_);
270*6dbdd20aSAndroid Build Coastguard Worker   }
271*6dbdd20aSAndroid Build Coastguard Worker 
OnStop(const DataSourceBase::StopArgs &)272*6dbdd20aSAndroid Build Coastguard Worker   void OnStop(const DataSourceBase::StopArgs&) override {
273*6dbdd20aSAndroid Build Coastguard Worker     GlobalState::Instance().OnStop(inst_id_);
274*6dbdd20aSAndroid Build Coastguard Worker   }
275*6dbdd20aSAndroid Build Coastguard Worker 
GetConfig() const276*6dbdd20aSAndroid Build Coastguard Worker   const perfetto::protos::gen::TrackEventConfig& GetConfig() const {
277*6dbdd20aSAndroid Build Coastguard Worker     return config_;
278*6dbdd20aSAndroid Build Coastguard Worker   }
279*6dbdd20aSAndroid Build Coastguard Worker 
Init()280*6dbdd20aSAndroid Build Coastguard Worker   static void Init() {
281*6dbdd20aSAndroid Build Coastguard Worker     DataSourceDescriptor dsd =
282*6dbdd20aSAndroid Build Coastguard Worker         GlobalState::Instance().GenerateDescriptorFromCategories();
283*6dbdd20aSAndroid Build Coastguard Worker     Register(dsd);
284*6dbdd20aSAndroid Build Coastguard Worker   }
285*6dbdd20aSAndroid Build Coastguard Worker 
RegisterCategory(PerfettoTeCategoryImpl * cat)286*6dbdd20aSAndroid Build Coastguard Worker   static void RegisterCategory(PerfettoTeCategoryImpl* cat) {
287*6dbdd20aSAndroid Build Coastguard Worker     GlobalState::Instance().RegisterCategory(cat);
288*6dbdd20aSAndroid Build Coastguard Worker   }
289*6dbdd20aSAndroid Build Coastguard Worker 
UpdateDescriptorFromCategories()290*6dbdd20aSAndroid Build Coastguard Worker   static void UpdateDescriptorFromCategories() {
291*6dbdd20aSAndroid Build Coastguard Worker     DataSourceDescriptor dsd =
292*6dbdd20aSAndroid Build Coastguard Worker         GlobalState::Instance().GenerateDescriptorFromCategories();
293*6dbdd20aSAndroid Build Coastguard Worker     UpdateDescriptor(dsd);
294*6dbdd20aSAndroid Build Coastguard Worker   }
295*6dbdd20aSAndroid Build Coastguard Worker 
UnregisterCategory(PerfettoTeCategoryImpl * cat)296*6dbdd20aSAndroid Build Coastguard Worker   static void UnregisterCategory(PerfettoTeCategoryImpl* cat) {
297*6dbdd20aSAndroid Build Coastguard Worker     GlobalState::Instance().UnregisterCategory(cat);
298*6dbdd20aSAndroid Build Coastguard Worker   }
299*6dbdd20aSAndroid Build Coastguard Worker 
CategorySetCallback(struct PerfettoTeCategoryImpl * cat,PerfettoTeCategoryImplCallback cb,void * user_arg)300*6dbdd20aSAndroid Build Coastguard Worker   static void CategorySetCallback(struct PerfettoTeCategoryImpl* cat,
301*6dbdd20aSAndroid Build Coastguard Worker                                   PerfettoTeCategoryImplCallback cb,
302*6dbdd20aSAndroid Build Coastguard Worker                                   void* user_arg) {
303*6dbdd20aSAndroid Build Coastguard Worker     GlobalState::Instance().CategorySetCallback(cat, cb, user_arg);
304*6dbdd20aSAndroid Build Coastguard Worker   }
305*6dbdd20aSAndroid Build Coastguard Worker 
306*6dbdd20aSAndroid Build Coastguard Worker   static internal::DataSourceType* GetType();
307*6dbdd20aSAndroid Build Coastguard Worker 
308*6dbdd20aSAndroid Build Coastguard Worker   static internal::DataSourceThreadLocalState** GetTlsState();
309*6dbdd20aSAndroid Build Coastguard Worker 
310*6dbdd20aSAndroid Build Coastguard Worker  private:
311*6dbdd20aSAndroid Build Coastguard Worker   class GlobalState {
312*6dbdd20aSAndroid Build Coastguard Worker    public:
Instance()313*6dbdd20aSAndroid Build Coastguard Worker     static GlobalState& Instance() {
314*6dbdd20aSAndroid Build Coastguard Worker       static GlobalState* instance = new GlobalState();
315*6dbdd20aSAndroid Build Coastguard Worker       return *instance;
316*6dbdd20aSAndroid Build Coastguard Worker     }
317*6dbdd20aSAndroid Build Coastguard Worker 
OnStart(const perfetto::protos::gen::TrackEventConfig & config,uint32_t instance_id)318*6dbdd20aSAndroid Build Coastguard Worker     void OnStart(const perfetto::protos::gen::TrackEventConfig& config,
319*6dbdd20aSAndroid Build Coastguard Worker                  uint32_t instance_id) PERFETTO_LOCKS_EXCLUDED(mu_) {
320*6dbdd20aSAndroid Build Coastguard Worker       std::lock_guard<std::mutex> lock(mu_);
321*6dbdd20aSAndroid Build Coastguard Worker       EnableRegisteredCategory(perfetto_te_any_categories, instance_id);
322*6dbdd20aSAndroid Build Coastguard Worker       for (PerfettoTeCategoryImpl* cat : categories_) {
323*6dbdd20aSAndroid Build Coastguard Worker         if (IsRegisteredCategoryEnabled(*cat, config)) {
324*6dbdd20aSAndroid Build Coastguard Worker           EnableRegisteredCategory(cat, instance_id);
325*6dbdd20aSAndroid Build Coastguard Worker         }
326*6dbdd20aSAndroid Build Coastguard Worker       }
327*6dbdd20aSAndroid Build Coastguard Worker     }
328*6dbdd20aSAndroid Build Coastguard Worker 
OnStop(uint32_t instance_id)329*6dbdd20aSAndroid Build Coastguard Worker     void OnStop(uint32_t instance_id) PERFETTO_LOCKS_EXCLUDED(mu_) {
330*6dbdd20aSAndroid Build Coastguard Worker       std::lock_guard<std::mutex> lock(mu_);
331*6dbdd20aSAndroid Build Coastguard Worker       for (PerfettoTeCategoryImpl* cat : categories_) {
332*6dbdd20aSAndroid Build Coastguard Worker         DisableRegisteredCategory(cat, instance_id);
333*6dbdd20aSAndroid Build Coastguard Worker       }
334*6dbdd20aSAndroid Build Coastguard Worker       DisableRegisteredCategory(perfetto_te_any_categories, instance_id);
335*6dbdd20aSAndroid Build Coastguard Worker     }
336*6dbdd20aSAndroid Build Coastguard Worker 
RegisterCategory(PerfettoTeCategoryImpl * cat)337*6dbdd20aSAndroid Build Coastguard Worker     void RegisterCategory(PerfettoTeCategoryImpl* cat)
338*6dbdd20aSAndroid Build Coastguard Worker         PERFETTO_LOCKS_EXCLUDED(mu_) {
339*6dbdd20aSAndroid Build Coastguard Worker       {
340*6dbdd20aSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(mu_);
341*6dbdd20aSAndroid Build Coastguard Worker         Trace([cat](TraceContext ctx) {
342*6dbdd20aSAndroid Build Coastguard Worker           auto ds = ctx.GetDataSourceLocked();
343*6dbdd20aSAndroid Build Coastguard Worker 
344*6dbdd20aSAndroid Build Coastguard Worker           if (IsRegisteredCategoryEnabled(*cat, ds->GetConfig())) {
345*6dbdd20aSAndroid Build Coastguard Worker             EnableRegisteredCategory(cat, ds->inst_id_);
346*6dbdd20aSAndroid Build Coastguard Worker           }
347*6dbdd20aSAndroid Build Coastguard Worker         });
348*6dbdd20aSAndroid Build Coastguard Worker         categories_.push_back(cat);
349*6dbdd20aSAndroid Build Coastguard Worker         cat->cat_iid = ++interned_categories_;
350*6dbdd20aSAndroid Build Coastguard Worker       }
351*6dbdd20aSAndroid Build Coastguard Worker     }
352*6dbdd20aSAndroid Build Coastguard Worker 
UnregisterCategory(PerfettoTeCategoryImpl * cat)353*6dbdd20aSAndroid Build Coastguard Worker     void UnregisterCategory(PerfettoTeCategoryImpl* cat)
354*6dbdd20aSAndroid Build Coastguard Worker         PERFETTO_LOCKS_EXCLUDED(mu_) {
355*6dbdd20aSAndroid Build Coastguard Worker       std::lock_guard<std::mutex> lock(mu_);
356*6dbdd20aSAndroid Build Coastguard Worker       categories_.erase(
357*6dbdd20aSAndroid Build Coastguard Worker           std::remove(categories_.begin(), categories_.end(), cat),
358*6dbdd20aSAndroid Build Coastguard Worker           categories_.end());
359*6dbdd20aSAndroid Build Coastguard Worker     }
360*6dbdd20aSAndroid Build Coastguard Worker 
CategorySetCallback(struct PerfettoTeCategoryImpl * cat,PerfettoTeCategoryImplCallback cb,void * user_arg)361*6dbdd20aSAndroid Build Coastguard Worker     void CategorySetCallback(struct PerfettoTeCategoryImpl* cat,
362*6dbdd20aSAndroid Build Coastguard Worker                              PerfettoTeCategoryImplCallback cb,
363*6dbdd20aSAndroid Build Coastguard Worker                              void* user_arg) PERFETTO_LOCKS_EXCLUDED(mu_) {
364*6dbdd20aSAndroid Build Coastguard Worker       std::lock_guard<std::mutex> lock(mu_);
365*6dbdd20aSAndroid Build Coastguard Worker       cat->cb = cb;
366*6dbdd20aSAndroid Build Coastguard Worker       cat->cb_user_arg = user_arg;
367*6dbdd20aSAndroid Build Coastguard Worker       if (!cat->cb) {
368*6dbdd20aSAndroid Build Coastguard Worker         return;
369*6dbdd20aSAndroid Build Coastguard Worker       }
370*6dbdd20aSAndroid Build Coastguard Worker 
371*6dbdd20aSAndroid Build Coastguard Worker       bool first = true;
372*6dbdd20aSAndroid Build Coastguard Worker       uint8_t active_instances = cat->instances.load(std::memory_order_relaxed);
373*6dbdd20aSAndroid Build Coastguard Worker       for (PerfettoDsInstanceIndex i = 0; i < internal::kMaxDataSourceInstances;
374*6dbdd20aSAndroid Build Coastguard Worker            i++) {
375*6dbdd20aSAndroid Build Coastguard Worker         if ((active_instances & (1 << i)) == 0) {
376*6dbdd20aSAndroid Build Coastguard Worker           continue;
377*6dbdd20aSAndroid Build Coastguard Worker         }
378*6dbdd20aSAndroid Build Coastguard Worker         cb(cat, i, true, first, user_arg);
379*6dbdd20aSAndroid Build Coastguard Worker         first = false;
380*6dbdd20aSAndroid Build Coastguard Worker       }
381*6dbdd20aSAndroid Build Coastguard Worker     }
382*6dbdd20aSAndroid Build Coastguard Worker 
GenerateDescriptorFromCategories() const383*6dbdd20aSAndroid Build Coastguard Worker     DataSourceDescriptor GenerateDescriptorFromCategories() const
384*6dbdd20aSAndroid Build Coastguard Worker         PERFETTO_LOCKS_EXCLUDED(mu_) {
385*6dbdd20aSAndroid Build Coastguard Worker       DataSourceDescriptor dsd;
386*6dbdd20aSAndroid Build Coastguard Worker       dsd.set_name("track_event");
387*6dbdd20aSAndroid Build Coastguard Worker 
388*6dbdd20aSAndroid Build Coastguard Worker       protozero::HeapBuffered<perfetto::protos::pbzero::TrackEventDescriptor>
389*6dbdd20aSAndroid Build Coastguard Worker           ted;
390*6dbdd20aSAndroid Build Coastguard Worker       {
391*6dbdd20aSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(mu_);
392*6dbdd20aSAndroid Build Coastguard Worker         for (PerfettoTeCategoryImpl* cat : categories_) {
393*6dbdd20aSAndroid Build Coastguard Worker           SerializeCategory(*cat->desc, ted.get());
394*6dbdd20aSAndroid Build Coastguard Worker         }
395*6dbdd20aSAndroid Build Coastguard Worker       }
396*6dbdd20aSAndroid Build Coastguard Worker       dsd.set_track_event_descriptor_raw(ted.SerializeAsString());
397*6dbdd20aSAndroid Build Coastguard Worker       return dsd;
398*6dbdd20aSAndroid Build Coastguard Worker     }
399*6dbdd20aSAndroid Build Coastguard Worker 
400*6dbdd20aSAndroid Build Coastguard Worker    private:
GlobalState()401*6dbdd20aSAndroid Build Coastguard Worker     GlobalState() : interned_categories_(0) {
402*6dbdd20aSAndroid Build Coastguard Worker       perfetto_te_any_categories = new PerfettoTeCategoryImpl;
403*6dbdd20aSAndroid Build Coastguard Worker       perfetto_te_any_categories_enabled = &perfetto_te_any_categories->flag;
404*6dbdd20aSAndroid Build Coastguard Worker     }
405*6dbdd20aSAndroid Build Coastguard Worker 
406*6dbdd20aSAndroid Build Coastguard Worker     mutable std::mutex mu_;
407*6dbdd20aSAndroid Build Coastguard Worker     std::vector<PerfettoTeCategoryImpl*> categories_ PERFETTO_GUARDED_BY(mu_);
408*6dbdd20aSAndroid Build Coastguard Worker     uint64_t interned_categories_ PERFETTO_GUARDED_BY(mu_);
409*6dbdd20aSAndroid Build Coastguard Worker   };
410*6dbdd20aSAndroid Build Coastguard Worker 
411*6dbdd20aSAndroid Build Coastguard Worker   uint32_t inst_id_;
412*6dbdd20aSAndroid Build Coastguard Worker   perfetto::protos::gen::TrackEventConfig config_;
413*6dbdd20aSAndroid Build Coastguard Worker };
414*6dbdd20aSAndroid Build Coastguard Worker 
415*6dbdd20aSAndroid Build Coastguard Worker TrackEvent::~TrackEvent() = default;
416*6dbdd20aSAndroid Build Coastguard Worker 
ResetTrackEventTls()417*6dbdd20aSAndroid Build Coastguard Worker void ResetTrackEventTls() {
418*6dbdd20aSAndroid Build Coastguard Worker   *TrackEvent::GetTlsState() = nullptr;
419*6dbdd20aSAndroid Build Coastguard Worker }
420*6dbdd20aSAndroid Build Coastguard Worker 
421*6dbdd20aSAndroid Build Coastguard Worker struct TracePointTraits {
422*6dbdd20aSAndroid Build Coastguard Worker   struct TracePointData {
423*6dbdd20aSAndroid Build Coastguard Worker     struct PerfettoTeCategoryImpl* enabled;
424*6dbdd20aSAndroid Build Coastguard Worker   };
GetActiveInstancesperfetto::shlib::TracePointTraits425*6dbdd20aSAndroid Build Coastguard Worker   static constexpr std::atomic<uint8_t>* GetActiveInstances(
426*6dbdd20aSAndroid Build Coastguard Worker       TracePointData data) {
427*6dbdd20aSAndroid Build Coastguard Worker     return &data.enabled->instances;
428*6dbdd20aSAndroid Build Coastguard Worker   }
429*6dbdd20aSAndroid Build Coastguard Worker };
430*6dbdd20aSAndroid Build Coastguard Worker 
431*6dbdd20aSAndroid Build Coastguard Worker }  // namespace shlib
432*6dbdd20aSAndroid Build Coastguard Worker }  // namespace perfetto
433*6dbdd20aSAndroid Build Coastguard Worker 
434*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(
435*6dbdd20aSAndroid Build Coastguard Worker     perfetto::shlib::TrackEvent,
436*6dbdd20aSAndroid Build Coastguard Worker     perfetto::shlib::TrackEventDataSourceTraits);
437*6dbdd20aSAndroid Build Coastguard Worker 
438*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(
439*6dbdd20aSAndroid Build Coastguard Worker     perfetto::shlib::TrackEvent,
440*6dbdd20aSAndroid Build Coastguard Worker     perfetto::shlib::TrackEventDataSourceTraits);
441*6dbdd20aSAndroid Build Coastguard Worker 
GetType()442*6dbdd20aSAndroid Build Coastguard Worker perfetto::internal::DataSourceType* perfetto::shlib::TrackEvent::GetType() {
443*6dbdd20aSAndroid Build Coastguard Worker   return &perfetto::shlib::TrackEvent::Helper::type();
444*6dbdd20aSAndroid Build Coastguard Worker }
445*6dbdd20aSAndroid Build Coastguard Worker 
446*6dbdd20aSAndroid Build Coastguard Worker perfetto::internal::DataSourceThreadLocalState**
GetTlsState()447*6dbdd20aSAndroid Build Coastguard Worker perfetto::shlib::TrackEvent::GetTlsState() {
448*6dbdd20aSAndroid Build Coastguard Worker   return &tls_state_;
449*6dbdd20aSAndroid Build Coastguard Worker }
450*6dbdd20aSAndroid Build Coastguard Worker 
451*6dbdd20aSAndroid Build Coastguard Worker namespace {
452*6dbdd20aSAndroid Build Coastguard Worker 
453*6dbdd20aSAndroid Build Coastguard Worker using perfetto::internal::TrackEventInternal;
454*6dbdd20aSAndroid Build Coastguard Worker 
EventType(int32_t type)455*6dbdd20aSAndroid Build Coastguard Worker perfetto::protos::pbzero::TrackEvent::Type EventType(int32_t type) {
456*6dbdd20aSAndroid Build Coastguard Worker   using Type = perfetto::protos::pbzero::TrackEvent::Type;
457*6dbdd20aSAndroid Build Coastguard Worker   auto enum_type = static_cast<PerfettoTeType>(type);
458*6dbdd20aSAndroid Build Coastguard Worker   switch (enum_type) {
459*6dbdd20aSAndroid Build Coastguard Worker     case PERFETTO_TE_TYPE_SLICE_BEGIN:
460*6dbdd20aSAndroid Build Coastguard Worker       return Type::TYPE_SLICE_BEGIN;
461*6dbdd20aSAndroid Build Coastguard Worker     case PERFETTO_TE_TYPE_SLICE_END:
462*6dbdd20aSAndroid Build Coastguard Worker       return Type::TYPE_SLICE_END;
463*6dbdd20aSAndroid Build Coastguard Worker     case PERFETTO_TE_TYPE_INSTANT:
464*6dbdd20aSAndroid Build Coastguard Worker       return Type::TYPE_INSTANT;
465*6dbdd20aSAndroid Build Coastguard Worker     case PERFETTO_TE_TYPE_COUNTER:
466*6dbdd20aSAndroid Build Coastguard Worker       return Type::TYPE_COUNTER;
467*6dbdd20aSAndroid Build Coastguard Worker   }
468*6dbdd20aSAndroid Build Coastguard Worker   return Type::TYPE_UNSPECIFIED;
469*6dbdd20aSAndroid Build Coastguard Worker }
470*6dbdd20aSAndroid Build Coastguard Worker 
471*6dbdd20aSAndroid Build Coastguard Worker protozero::MessageHandle<perfetto::protos::pbzero::TracePacket>
NewTracePacketInternal(perfetto::TraceWriterBase * trace_writer,perfetto::shlib::TrackEventIncrementalState * incr_state,const perfetto::shlib::TrackEventTlsState & tls_state,perfetto::TraceTimestamp timestamp,uint32_t seq_flags)472*6dbdd20aSAndroid Build Coastguard Worker NewTracePacketInternal(perfetto::TraceWriterBase* trace_writer,
473*6dbdd20aSAndroid Build Coastguard Worker                        perfetto::shlib::TrackEventIncrementalState* incr_state,
474*6dbdd20aSAndroid Build Coastguard Worker                        const perfetto::shlib::TrackEventTlsState& tls_state,
475*6dbdd20aSAndroid Build Coastguard Worker                        perfetto::TraceTimestamp timestamp,
476*6dbdd20aSAndroid Build Coastguard Worker                        uint32_t seq_flags) {
477*6dbdd20aSAndroid Build Coastguard Worker   // PERFETTO_TE_TIMESTAMP_TYPE_INCREMENTAL is the default timestamp returned
478*6dbdd20aSAndroid Build Coastguard Worker   // by TrackEventInternal::GetTraceTime(). If the configuration in `tls_state`
479*6dbdd20aSAndroid Build Coastguard Worker   // uses a different clock, we have to use that instead.
480*6dbdd20aSAndroid Build Coastguard Worker   if (PERFETTO_UNLIKELY(tls_state.default_clock_id !=
481*6dbdd20aSAndroid Build Coastguard Worker                             PERFETTO_TE_TIMESTAMP_TYPE_INCREMENTAL &&
482*6dbdd20aSAndroid Build Coastguard Worker                         timestamp.clock_id ==
483*6dbdd20aSAndroid Build Coastguard Worker                             PERFETTO_TE_TIMESTAMP_TYPE_INCREMENTAL)) {
484*6dbdd20aSAndroid Build Coastguard Worker     timestamp.clock_id = tls_state.default_clock_id;
485*6dbdd20aSAndroid Build Coastguard Worker   }
486*6dbdd20aSAndroid Build Coastguard Worker   auto packet = trace_writer->NewTracePacket();
487*6dbdd20aSAndroid Build Coastguard Worker   auto ts_unit_multiplier = tls_state.timestamp_unit_multiplier;
488*6dbdd20aSAndroid Build Coastguard Worker   if (PERFETTO_LIKELY(timestamp.clock_id ==
489*6dbdd20aSAndroid Build Coastguard Worker                       PERFETTO_TE_TIMESTAMP_TYPE_INCREMENTAL)) {
490*6dbdd20aSAndroid Build Coastguard Worker     if (PERFETTO_LIKELY(incr_state->last_timestamp_ns <= timestamp.value)) {
491*6dbdd20aSAndroid Build Coastguard Worker       // No need to set the clock id here, since
492*6dbdd20aSAndroid Build Coastguard Worker       // PERFETTO_TE_TIMESTAMP_TYPE_INCREMENTAL is the clock id assumed by
493*6dbdd20aSAndroid Build Coastguard Worker       // default.
494*6dbdd20aSAndroid Build Coastguard Worker       auto time_diff_ns = timestamp.value - incr_state->last_timestamp_ns;
495*6dbdd20aSAndroid Build Coastguard Worker       auto time_diff_units = time_diff_ns / ts_unit_multiplier;
496*6dbdd20aSAndroid Build Coastguard Worker       packet->set_timestamp(time_diff_units);
497*6dbdd20aSAndroid Build Coastguard Worker       incr_state->last_timestamp_ns += time_diff_units * ts_unit_multiplier;
498*6dbdd20aSAndroid Build Coastguard Worker     } else {
499*6dbdd20aSAndroid Build Coastguard Worker       packet->set_timestamp(timestamp.value / ts_unit_multiplier);
500*6dbdd20aSAndroid Build Coastguard Worker       packet->set_timestamp_clock_id(
501*6dbdd20aSAndroid Build Coastguard Worker           ts_unit_multiplier == 1
502*6dbdd20aSAndroid Build Coastguard Worker               ? static_cast<uint32_t>(PERFETTO_I_CLOCK_INCREMENTAL_UNDERNEATH)
503*6dbdd20aSAndroid Build Coastguard Worker               : static_cast<uint32_t>(PERFETTO_TE_TIMESTAMP_TYPE_ABSOLUTE));
504*6dbdd20aSAndroid Build Coastguard Worker     }
505*6dbdd20aSAndroid Build Coastguard Worker   } else if (PERFETTO_LIKELY(timestamp.clock_id ==
506*6dbdd20aSAndroid Build Coastguard Worker                              tls_state.default_clock_id)) {
507*6dbdd20aSAndroid Build Coastguard Worker     packet->set_timestamp(timestamp.value / ts_unit_multiplier);
508*6dbdd20aSAndroid Build Coastguard Worker   } else {
509*6dbdd20aSAndroid Build Coastguard Worker     packet->set_timestamp(timestamp.value);
510*6dbdd20aSAndroid Build Coastguard Worker     packet->set_timestamp_clock_id(timestamp.clock_id);
511*6dbdd20aSAndroid Build Coastguard Worker   }
512*6dbdd20aSAndroid Build Coastguard Worker   packet->set_sequence_flags(seq_flags);
513*6dbdd20aSAndroid Build Coastguard Worker   return packet;
514*6dbdd20aSAndroid Build Coastguard Worker }
515*6dbdd20aSAndroid Build Coastguard Worker 
516*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
517*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
GetCmdLine()518*6dbdd20aSAndroid Build Coastguard Worker std::vector<std::string> GetCmdLine() {
519*6dbdd20aSAndroid Build Coastguard Worker   std::vector<std::string> cmdline_str;
520*6dbdd20aSAndroid Build Coastguard Worker   std::string cmdline;
521*6dbdd20aSAndroid Build Coastguard Worker   if (perfetto::base::ReadFile("/proc/self/cmdline", &cmdline)) {
522*6dbdd20aSAndroid Build Coastguard Worker     perfetto::base::StringSplitter splitter(std::move(cmdline), '\0');
523*6dbdd20aSAndroid Build Coastguard Worker     while (splitter.Next()) {
524*6dbdd20aSAndroid Build Coastguard Worker       cmdline_str.emplace_back(splitter.cur_token(), splitter.cur_token_size());
525*6dbdd20aSAndroid Build Coastguard Worker     }
526*6dbdd20aSAndroid Build Coastguard Worker   }
527*6dbdd20aSAndroid Build Coastguard Worker   return cmdline_str;
528*6dbdd20aSAndroid Build Coastguard Worker }
529*6dbdd20aSAndroid Build Coastguard Worker #endif
530*6dbdd20aSAndroid Build Coastguard Worker 
ResetIncrementalStateIfRequired(perfetto::TraceWriterBase * trace_writer,perfetto::shlib::TrackEventIncrementalState * incr_state,const perfetto::shlib::TrackEventTlsState & tls_state,const perfetto::TraceTimestamp & timestamp)531*6dbdd20aSAndroid Build Coastguard Worker void ResetIncrementalStateIfRequired(
532*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TraceWriterBase* trace_writer,
533*6dbdd20aSAndroid Build Coastguard Worker     perfetto::shlib::TrackEventIncrementalState* incr_state,
534*6dbdd20aSAndroid Build Coastguard Worker     const perfetto::shlib::TrackEventTlsState& tls_state,
535*6dbdd20aSAndroid Build Coastguard Worker     const perfetto::TraceTimestamp& timestamp) {
536*6dbdd20aSAndroid Build Coastguard Worker   if (!incr_state->was_cleared) {
537*6dbdd20aSAndroid Build Coastguard Worker     return;
538*6dbdd20aSAndroid Build Coastguard Worker   }
539*6dbdd20aSAndroid Build Coastguard Worker   incr_state->was_cleared = false;
540*6dbdd20aSAndroid Build Coastguard Worker 
541*6dbdd20aSAndroid Build Coastguard Worker   auto sequence_timestamp = timestamp;
542*6dbdd20aSAndroid Build Coastguard Worker   if (timestamp.clock_id != PERFETTO_I_CLOCK_INCREMENTAL_UNDERNEATH &&
543*6dbdd20aSAndroid Build Coastguard Worker       timestamp.clock_id != PERFETTO_TE_TIMESTAMP_TYPE_INCREMENTAL) {
544*6dbdd20aSAndroid Build Coastguard Worker     sequence_timestamp = TrackEventInternal::GetTraceTime();
545*6dbdd20aSAndroid Build Coastguard Worker   }
546*6dbdd20aSAndroid Build Coastguard Worker 
547*6dbdd20aSAndroid Build Coastguard Worker   incr_state->last_timestamp_ns = sequence_timestamp.value;
548*6dbdd20aSAndroid Build Coastguard Worker   auto tid = perfetto::base::GetThreadId();
549*6dbdd20aSAndroid Build Coastguard Worker   auto pid = perfetto::Platform::GetCurrentProcessId();
550*6dbdd20aSAndroid Build Coastguard Worker   uint64_t thread_track_uuid =
551*6dbdd20aSAndroid Build Coastguard Worker       perfetto_te_process_track_uuid ^ static_cast<uint64_t>(tid);
552*6dbdd20aSAndroid Build Coastguard Worker   auto ts_unit_multiplier = tls_state.timestamp_unit_multiplier;
553*6dbdd20aSAndroid Build Coastguard Worker   {
554*6dbdd20aSAndroid Build Coastguard Worker     // Mark any incremental state before this point invalid. Also set up
555*6dbdd20aSAndroid Build Coastguard Worker     // defaults so that we don't need to repeat constant data for each packet.
556*6dbdd20aSAndroid Build Coastguard Worker     auto packet = NewTracePacketInternal(
557*6dbdd20aSAndroid Build Coastguard Worker         trace_writer, incr_state, tls_state, timestamp,
558*6dbdd20aSAndroid Build Coastguard Worker         perfetto::protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED);
559*6dbdd20aSAndroid Build Coastguard Worker     auto defaults = packet->set_trace_packet_defaults();
560*6dbdd20aSAndroid Build Coastguard Worker     defaults->set_timestamp_clock_id(tls_state.default_clock_id);
561*6dbdd20aSAndroid Build Coastguard Worker     // Establish the default track for this event sequence.
562*6dbdd20aSAndroid Build Coastguard Worker     auto track_defaults = defaults->set_track_event_defaults();
563*6dbdd20aSAndroid Build Coastguard Worker     track_defaults->set_track_uuid(thread_track_uuid);
564*6dbdd20aSAndroid Build Coastguard Worker 
565*6dbdd20aSAndroid Build Coastguard Worker     if (tls_state.default_clock_id != PERFETTO_I_CLOCK_INCREMENTAL_UNDERNEATH) {
566*6dbdd20aSAndroid Build Coastguard Worker       perfetto::protos::pbzero::ClockSnapshot* clocks =
567*6dbdd20aSAndroid Build Coastguard Worker           packet->set_clock_snapshot();
568*6dbdd20aSAndroid Build Coastguard Worker       // Trace clock.
569*6dbdd20aSAndroid Build Coastguard Worker       perfetto::protos::pbzero::ClockSnapshot::Clock* trace_clock =
570*6dbdd20aSAndroid Build Coastguard Worker           clocks->add_clocks();
571*6dbdd20aSAndroid Build Coastguard Worker       trace_clock->set_clock_id(PERFETTO_I_CLOCK_INCREMENTAL_UNDERNEATH);
572*6dbdd20aSAndroid Build Coastguard Worker       trace_clock->set_timestamp(sequence_timestamp.value);
573*6dbdd20aSAndroid Build Coastguard Worker 
574*6dbdd20aSAndroid Build Coastguard Worker       if (PERFETTO_LIKELY(tls_state.default_clock_id ==
575*6dbdd20aSAndroid Build Coastguard Worker                           PERFETTO_TE_TIMESTAMP_TYPE_INCREMENTAL)) {
576*6dbdd20aSAndroid Build Coastguard Worker         // Delta-encoded incremental clock in nanoseconds by default but
577*6dbdd20aSAndroid Build Coastguard Worker         // configurable by |tls_state.timestamp_unit_multiplier|.
578*6dbdd20aSAndroid Build Coastguard Worker         perfetto::protos::pbzero::ClockSnapshot::Clock* clock_incremental =
579*6dbdd20aSAndroid Build Coastguard Worker             clocks->add_clocks();
580*6dbdd20aSAndroid Build Coastguard Worker         clock_incremental->set_clock_id(PERFETTO_TE_TIMESTAMP_TYPE_INCREMENTAL);
581*6dbdd20aSAndroid Build Coastguard Worker         clock_incremental->set_timestamp(sequence_timestamp.value /
582*6dbdd20aSAndroid Build Coastguard Worker                                          ts_unit_multiplier);
583*6dbdd20aSAndroid Build Coastguard Worker         clock_incremental->set_is_incremental(true);
584*6dbdd20aSAndroid Build Coastguard Worker         clock_incremental->set_unit_multiplier_ns(ts_unit_multiplier);
585*6dbdd20aSAndroid Build Coastguard Worker       }
586*6dbdd20aSAndroid Build Coastguard Worker       if (ts_unit_multiplier > 1) {
587*6dbdd20aSAndroid Build Coastguard Worker         // absolute clock with custom timestamp_unit_multiplier.
588*6dbdd20aSAndroid Build Coastguard Worker         perfetto::protos::pbzero::ClockSnapshot::Clock* absolute_clock =
589*6dbdd20aSAndroid Build Coastguard Worker             clocks->add_clocks();
590*6dbdd20aSAndroid Build Coastguard Worker         absolute_clock->set_clock_id(PERFETTO_TE_TIMESTAMP_TYPE_ABSOLUTE);
591*6dbdd20aSAndroid Build Coastguard Worker         absolute_clock->set_timestamp(sequence_timestamp.value /
592*6dbdd20aSAndroid Build Coastguard Worker                                       ts_unit_multiplier);
593*6dbdd20aSAndroid Build Coastguard Worker         absolute_clock->set_is_incremental(false);
594*6dbdd20aSAndroid Build Coastguard Worker         absolute_clock->set_unit_multiplier_ns(ts_unit_multiplier);
595*6dbdd20aSAndroid Build Coastguard Worker       }
596*6dbdd20aSAndroid Build Coastguard Worker     }
597*6dbdd20aSAndroid Build Coastguard Worker   }
598*6dbdd20aSAndroid Build Coastguard Worker 
599*6dbdd20aSAndroid Build Coastguard Worker   // Every thread should write a descriptor for its default track, because most
600*6dbdd20aSAndroid Build Coastguard Worker   // trace points won't explicitly reference it. We also write the process
601*6dbdd20aSAndroid Build Coastguard Worker   // descriptor from every thread that writes trace events to ensure it gets
602*6dbdd20aSAndroid Build Coastguard Worker   // emitted at least once.
603*6dbdd20aSAndroid Build Coastguard Worker   {
604*6dbdd20aSAndroid Build Coastguard Worker     auto packet = NewTracePacketInternal(
605*6dbdd20aSAndroid Build Coastguard Worker         trace_writer, incr_state, tls_state, timestamp,
606*6dbdd20aSAndroid Build Coastguard Worker         perfetto::protos::pbzero::TracePacket::SEQ_NEEDS_INCREMENTAL_STATE);
607*6dbdd20aSAndroid Build Coastguard Worker     auto* track = packet->set_track_descriptor();
608*6dbdd20aSAndroid Build Coastguard Worker     track->set_uuid(thread_track_uuid);
609*6dbdd20aSAndroid Build Coastguard Worker     track->set_parent_uuid(perfetto_te_process_track_uuid);
610*6dbdd20aSAndroid Build Coastguard Worker     auto* td = track->set_thread();
611*6dbdd20aSAndroid Build Coastguard Worker 
612*6dbdd20aSAndroid Build Coastguard Worker     td->set_pid(static_cast<int32_t>(pid));
613*6dbdd20aSAndroid Build Coastguard Worker     td->set_tid(static_cast<int32_t>(tid));
614*6dbdd20aSAndroid Build Coastguard Worker     std::string thread_name;
615*6dbdd20aSAndroid Build Coastguard Worker     if (perfetto::base::GetThreadName(thread_name))
616*6dbdd20aSAndroid Build Coastguard Worker       td->set_thread_name(thread_name);
617*6dbdd20aSAndroid Build Coastguard Worker   }
618*6dbdd20aSAndroid Build Coastguard Worker   {
619*6dbdd20aSAndroid Build Coastguard Worker     auto packet = NewTracePacketInternal(
620*6dbdd20aSAndroid Build Coastguard Worker         trace_writer, incr_state, tls_state, timestamp,
621*6dbdd20aSAndroid Build Coastguard Worker         perfetto::protos::pbzero::TracePacket::SEQ_NEEDS_INCREMENTAL_STATE);
622*6dbdd20aSAndroid Build Coastguard Worker     auto* track = packet->set_track_descriptor();
623*6dbdd20aSAndroid Build Coastguard Worker     track->set_uuid(perfetto_te_process_track_uuid);
624*6dbdd20aSAndroid Build Coastguard Worker     auto* pd = track->set_process();
625*6dbdd20aSAndroid Build Coastguard Worker 
626*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
627*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
628*6dbdd20aSAndroid Build Coastguard Worker     static perfetto::base::NoDestructor<std::vector<std::string>> cmdline(
629*6dbdd20aSAndroid Build Coastguard Worker         GetCmdLine());
630*6dbdd20aSAndroid Build Coastguard Worker     if (!cmdline.ref().empty()) {
631*6dbdd20aSAndroid Build Coastguard Worker       // Since cmdline is a zero-terminated list of arguments, this ends up
632*6dbdd20aSAndroid Build Coastguard Worker       // writing just the first element, i.e., the process name, into the
633*6dbdd20aSAndroid Build Coastguard Worker       // process name field.
634*6dbdd20aSAndroid Build Coastguard Worker       pd->set_process_name(cmdline.ref()[0]);
635*6dbdd20aSAndroid Build Coastguard Worker       for (const std::string& arg : cmdline.ref()) {
636*6dbdd20aSAndroid Build Coastguard Worker         pd->add_cmdline(arg);
637*6dbdd20aSAndroid Build Coastguard Worker       }
638*6dbdd20aSAndroid Build Coastguard Worker     }
639*6dbdd20aSAndroid Build Coastguard Worker #endif
640*6dbdd20aSAndroid Build Coastguard Worker     pd->set_pid(static_cast<int32_t>(pid));
641*6dbdd20aSAndroid Build Coastguard Worker   }
642*6dbdd20aSAndroid Build Coastguard Worker }
643*6dbdd20aSAndroid Build Coastguard Worker 
644*6dbdd20aSAndroid Build Coastguard Worker // Appends the fields described by `fields` to `msg`.
AppendHlProtoFields(protozero::Message * msg,PerfettoTeHlProtoField * const * fields)645*6dbdd20aSAndroid Build Coastguard Worker void AppendHlProtoFields(protozero::Message* msg,
646*6dbdd20aSAndroid Build Coastguard Worker                          PerfettoTeHlProtoField* const* fields) {
647*6dbdd20aSAndroid Build Coastguard Worker   for (PerfettoTeHlProtoField* const* p = fields; *p != nullptr; p++) {
648*6dbdd20aSAndroid Build Coastguard Worker     switch ((*p)->type) {
649*6dbdd20aSAndroid Build Coastguard Worker       case PERFETTO_TE_HL_PROTO_TYPE_CSTR: {
650*6dbdd20aSAndroid Build Coastguard Worker         auto field = reinterpret_cast<PerfettoTeHlProtoFieldCstr*>(*p);
651*6dbdd20aSAndroid Build Coastguard Worker         msg->AppendString(field->header.id, field->str);
652*6dbdd20aSAndroid Build Coastguard Worker         break;
653*6dbdd20aSAndroid Build Coastguard Worker       }
654*6dbdd20aSAndroid Build Coastguard Worker       case PERFETTO_TE_HL_PROTO_TYPE_BYTES: {
655*6dbdd20aSAndroid Build Coastguard Worker         auto field = reinterpret_cast<PerfettoTeHlProtoFieldBytes*>(*p);
656*6dbdd20aSAndroid Build Coastguard Worker         msg->AppendBytes(field->header.id, field->buf, field->len);
657*6dbdd20aSAndroid Build Coastguard Worker         break;
658*6dbdd20aSAndroid Build Coastguard Worker       }
659*6dbdd20aSAndroid Build Coastguard Worker       case PERFETTO_TE_HL_PROTO_TYPE_NESTED: {
660*6dbdd20aSAndroid Build Coastguard Worker         auto field = reinterpret_cast<PerfettoTeHlProtoFieldNested*>(*p);
661*6dbdd20aSAndroid Build Coastguard Worker         auto* nested =
662*6dbdd20aSAndroid Build Coastguard Worker             msg->BeginNestedMessage<protozero::Message>(field->header.id);
663*6dbdd20aSAndroid Build Coastguard Worker         AppendHlProtoFields(nested, field->fields);
664*6dbdd20aSAndroid Build Coastguard Worker         break;
665*6dbdd20aSAndroid Build Coastguard Worker       }
666*6dbdd20aSAndroid Build Coastguard Worker       case PERFETTO_TE_HL_PROTO_TYPE_VARINT: {
667*6dbdd20aSAndroid Build Coastguard Worker         auto field = reinterpret_cast<PerfettoTeHlProtoFieldVarInt*>(*p);
668*6dbdd20aSAndroid Build Coastguard Worker         msg->AppendVarInt(field->header.id, field->value);
669*6dbdd20aSAndroid Build Coastguard Worker         break;
670*6dbdd20aSAndroid Build Coastguard Worker       }
671*6dbdd20aSAndroid Build Coastguard Worker       case PERFETTO_TE_HL_PROTO_TYPE_FIXED64: {
672*6dbdd20aSAndroid Build Coastguard Worker         auto field = reinterpret_cast<PerfettoTeHlProtoFieldFixed64*>(*p);
673*6dbdd20aSAndroid Build Coastguard Worker         msg->AppendFixed(field->header.id, field->value);
674*6dbdd20aSAndroid Build Coastguard Worker         break;
675*6dbdd20aSAndroid Build Coastguard Worker       }
676*6dbdd20aSAndroid Build Coastguard Worker       case PERFETTO_TE_HL_PROTO_TYPE_FIXED32: {
677*6dbdd20aSAndroid Build Coastguard Worker         auto field = reinterpret_cast<PerfettoTeHlProtoFieldFixed32*>(*p);
678*6dbdd20aSAndroid Build Coastguard Worker         msg->AppendFixed(field->header.id, field->value);
679*6dbdd20aSAndroid Build Coastguard Worker         break;
680*6dbdd20aSAndroid Build Coastguard Worker       }
681*6dbdd20aSAndroid Build Coastguard Worker       case PERFETTO_TE_HL_PROTO_TYPE_DOUBLE: {
682*6dbdd20aSAndroid Build Coastguard Worker         auto field = reinterpret_cast<PerfettoTeHlProtoFieldDouble*>(*p);
683*6dbdd20aSAndroid Build Coastguard Worker         msg->AppendFixed(field->header.id, field->value);
684*6dbdd20aSAndroid Build Coastguard Worker         break;
685*6dbdd20aSAndroid Build Coastguard Worker       }
686*6dbdd20aSAndroid Build Coastguard Worker       case PERFETTO_TE_HL_PROTO_TYPE_FLOAT: {
687*6dbdd20aSAndroid Build Coastguard Worker         auto field = reinterpret_cast<PerfettoTeHlProtoFieldFloat*>(*p);
688*6dbdd20aSAndroid Build Coastguard Worker         msg->AppendFixed(field->header.id, field->value);
689*6dbdd20aSAndroid Build Coastguard Worker         break;
690*6dbdd20aSAndroid Build Coastguard Worker       }
691*6dbdd20aSAndroid Build Coastguard Worker     }
692*6dbdd20aSAndroid Build Coastguard Worker   }
693*6dbdd20aSAndroid Build Coastguard Worker }
694*6dbdd20aSAndroid Build Coastguard Worker 
WriteTrackEvent(perfetto::shlib::TrackEventIncrementalState * incr,perfetto::protos::pbzero::TrackEvent * event,PerfettoTeCategoryImpl * cat,perfetto::protos::pbzero::TrackEvent::Type type,const char * name,const PerfettoTeHlExtra * const * extra_data,std::optional<uint64_t> track_uuid,const PerfettoTeCategoryDescriptor * dynamic_cat,bool use_interning)695*6dbdd20aSAndroid Build Coastguard Worker void WriteTrackEvent(perfetto::shlib::TrackEventIncrementalState* incr,
696*6dbdd20aSAndroid Build Coastguard Worker                      perfetto::protos::pbzero::TrackEvent* event,
697*6dbdd20aSAndroid Build Coastguard Worker                      PerfettoTeCategoryImpl* cat,
698*6dbdd20aSAndroid Build Coastguard Worker                      perfetto::protos::pbzero::TrackEvent::Type type,
699*6dbdd20aSAndroid Build Coastguard Worker                      const char* name,
700*6dbdd20aSAndroid Build Coastguard Worker                      const PerfettoTeHlExtra* const* extra_data,
701*6dbdd20aSAndroid Build Coastguard Worker                      std::optional<uint64_t> track_uuid,
702*6dbdd20aSAndroid Build Coastguard Worker                      const PerfettoTeCategoryDescriptor* dynamic_cat,
703*6dbdd20aSAndroid Build Coastguard Worker                      bool use_interning) {
704*6dbdd20aSAndroid Build Coastguard Worker   if (type != perfetto::protos::pbzero::TrackEvent::TYPE_UNSPECIFIED) {
705*6dbdd20aSAndroid Build Coastguard Worker     event->set_type(type);
706*6dbdd20aSAndroid Build Coastguard Worker   }
707*6dbdd20aSAndroid Build Coastguard Worker 
708*6dbdd20aSAndroid Build Coastguard Worker   if (!dynamic_cat &&
709*6dbdd20aSAndroid Build Coastguard Worker       type != perfetto::protos::pbzero::TrackEvent::TYPE_SLICE_END &&
710*6dbdd20aSAndroid Build Coastguard Worker       type != perfetto::protos::pbzero::TrackEvent::TYPE_COUNTER) {
711*6dbdd20aSAndroid Build Coastguard Worker     uint64_t iid = cat->cat_iid;
712*6dbdd20aSAndroid Build Coastguard Worker     auto res = incr->iids.FindOrAssign(
713*6dbdd20aSAndroid Build Coastguard Worker         perfetto::protos::pbzero::InternedData::kEventCategoriesFieldNumber,
714*6dbdd20aSAndroid Build Coastguard Worker         &iid, sizeof(iid));
715*6dbdd20aSAndroid Build Coastguard Worker     if (res.newly_assigned) {
716*6dbdd20aSAndroid Build Coastguard Worker       auto* ser = incr->serialized_interned_data->add_event_categories();
717*6dbdd20aSAndroid Build Coastguard Worker       ser->set_iid(iid);
718*6dbdd20aSAndroid Build Coastguard Worker       ser->set_name(cat->desc->name);
719*6dbdd20aSAndroid Build Coastguard Worker     }
720*6dbdd20aSAndroid Build Coastguard Worker     event->add_category_iids(iid);
721*6dbdd20aSAndroid Build Coastguard Worker   }
722*6dbdd20aSAndroid Build Coastguard Worker 
723*6dbdd20aSAndroid Build Coastguard Worker   if (type != perfetto::protos::pbzero::TrackEvent::TYPE_SLICE_END) {
724*6dbdd20aSAndroid Build Coastguard Worker     if (name) {
725*6dbdd20aSAndroid Build Coastguard Worker       if (use_interning) {
726*6dbdd20aSAndroid Build Coastguard Worker         const void* str = name;
727*6dbdd20aSAndroid Build Coastguard Worker         size_t len = strlen(name);
728*6dbdd20aSAndroid Build Coastguard Worker         auto res = incr->iids.FindOrAssign(
729*6dbdd20aSAndroid Build Coastguard Worker             perfetto::protos::pbzero::InternedData::kEventNamesFieldNumber, str,
730*6dbdd20aSAndroid Build Coastguard Worker             len);
731*6dbdd20aSAndroid Build Coastguard Worker         if (res.newly_assigned) {
732*6dbdd20aSAndroid Build Coastguard Worker           auto* ser = incr->serialized_interned_data->add_event_names();
733*6dbdd20aSAndroid Build Coastguard Worker           ser->set_iid(res.iid);
734*6dbdd20aSAndroid Build Coastguard Worker           ser->set_name(name);
735*6dbdd20aSAndroid Build Coastguard Worker         }
736*6dbdd20aSAndroid Build Coastguard Worker         event->set_name_iid(res.iid);
737*6dbdd20aSAndroid Build Coastguard Worker       } else {
738*6dbdd20aSAndroid Build Coastguard Worker         event->set_name(name);
739*6dbdd20aSAndroid Build Coastguard Worker       }
740*6dbdd20aSAndroid Build Coastguard Worker     }
741*6dbdd20aSAndroid Build Coastguard Worker   }
742*6dbdd20aSAndroid Build Coastguard Worker 
743*6dbdd20aSAndroid Build Coastguard Worker   if (dynamic_cat &&
744*6dbdd20aSAndroid Build Coastguard Worker       type != perfetto::protos::pbzero::TrackEvent::TYPE_SLICE_END &&
745*6dbdd20aSAndroid Build Coastguard Worker       type != perfetto::protos::pbzero::TrackEvent::TYPE_COUNTER) {
746*6dbdd20aSAndroid Build Coastguard Worker     event->add_categories(dynamic_cat->name);
747*6dbdd20aSAndroid Build Coastguard Worker   }
748*6dbdd20aSAndroid Build Coastguard Worker 
749*6dbdd20aSAndroid Build Coastguard Worker   if (track_uuid) {
750*6dbdd20aSAndroid Build Coastguard Worker     event->set_track_uuid(*track_uuid);
751*6dbdd20aSAndroid Build Coastguard Worker   }
752*6dbdd20aSAndroid Build Coastguard Worker 
753*6dbdd20aSAndroid Build Coastguard Worker   for (const auto* it = extra_data; *it != nullptr; it++) {
754*6dbdd20aSAndroid Build Coastguard Worker     const struct PerfettoTeHlExtra& extra = **it;
755*6dbdd20aSAndroid Build Coastguard Worker     if (extra.type == PERFETTO_TE_HL_EXTRA_TYPE_COUNTER_INT64 &&
756*6dbdd20aSAndroid Build Coastguard Worker         type == perfetto::protos::pbzero::TrackEvent::TYPE_COUNTER) {
757*6dbdd20aSAndroid Build Coastguard Worker       event->set_counter_value(
758*6dbdd20aSAndroid Build Coastguard Worker           reinterpret_cast<const struct PerfettoTeHlExtraCounterInt64&>(extra)
759*6dbdd20aSAndroid Build Coastguard Worker               .value);
760*6dbdd20aSAndroid Build Coastguard Worker     } else if (extra.type == PERFETTO_TE_HL_EXTRA_TYPE_COUNTER_DOUBLE) {
761*6dbdd20aSAndroid Build Coastguard Worker       event->set_double_counter_value(
762*6dbdd20aSAndroid Build Coastguard Worker           reinterpret_cast<const struct PerfettoTeHlExtraCounterDouble&>(extra)
763*6dbdd20aSAndroid Build Coastguard Worker               .value);
764*6dbdd20aSAndroid Build Coastguard Worker     }
765*6dbdd20aSAndroid Build Coastguard Worker   }
766*6dbdd20aSAndroid Build Coastguard Worker 
767*6dbdd20aSAndroid Build Coastguard Worker   for (const auto* it = extra_data; *it != nullptr; it++) {
768*6dbdd20aSAndroid Build Coastguard Worker     const struct PerfettoTeHlExtra& extra = **it;
769*6dbdd20aSAndroid Build Coastguard Worker     if (extra.type == PERFETTO_TE_HL_EXTRA_TYPE_DEBUG_ARG_BOOL ||
770*6dbdd20aSAndroid Build Coastguard Worker         extra.type == PERFETTO_TE_HL_EXTRA_TYPE_DEBUG_ARG_UINT64 ||
771*6dbdd20aSAndroid Build Coastguard Worker         extra.type == PERFETTO_TE_HL_EXTRA_TYPE_DEBUG_ARG_INT64 ||
772*6dbdd20aSAndroid Build Coastguard Worker         extra.type == PERFETTO_TE_HL_EXTRA_TYPE_DEBUG_ARG_DOUBLE ||
773*6dbdd20aSAndroid Build Coastguard Worker         extra.type == PERFETTO_TE_HL_EXTRA_TYPE_DEBUG_ARG_STRING ||
774*6dbdd20aSAndroid Build Coastguard Worker         extra.type == PERFETTO_TE_HL_EXTRA_TYPE_DEBUG_ARG_POINTER) {
775*6dbdd20aSAndroid Build Coastguard Worker       auto* dbg = event->add_debug_annotations();
776*6dbdd20aSAndroid Build Coastguard Worker       const char* arg_name = nullptr;
777*6dbdd20aSAndroid Build Coastguard Worker       if (extra.type == PERFETTO_TE_HL_EXTRA_TYPE_DEBUG_ARG_BOOL) {
778*6dbdd20aSAndroid Build Coastguard Worker         const auto& arg =
779*6dbdd20aSAndroid Build Coastguard Worker             reinterpret_cast<const struct PerfettoTeHlExtraDebugArgBool&>(
780*6dbdd20aSAndroid Build Coastguard Worker                 extra);
781*6dbdd20aSAndroid Build Coastguard Worker         dbg->set_bool_value(arg.value);
782*6dbdd20aSAndroid Build Coastguard Worker         arg_name = arg.name;
783*6dbdd20aSAndroid Build Coastguard Worker       } else if (extra.type == PERFETTO_TE_HL_EXTRA_TYPE_DEBUG_ARG_UINT64) {
784*6dbdd20aSAndroid Build Coastguard Worker         const auto& arg =
785*6dbdd20aSAndroid Build Coastguard Worker             reinterpret_cast<const struct PerfettoTeHlExtraDebugArgUint64&>(
786*6dbdd20aSAndroid Build Coastguard Worker                 extra);
787*6dbdd20aSAndroid Build Coastguard Worker         dbg->set_uint_value(arg.value);
788*6dbdd20aSAndroid Build Coastguard Worker         arg_name = arg.name;
789*6dbdd20aSAndroid Build Coastguard Worker       } else if (extra.type == PERFETTO_TE_HL_EXTRA_TYPE_DEBUG_ARG_INT64) {
790*6dbdd20aSAndroid Build Coastguard Worker         const auto& arg =
791*6dbdd20aSAndroid Build Coastguard Worker             reinterpret_cast<const struct PerfettoTeHlExtraDebugArgInt64&>(
792*6dbdd20aSAndroid Build Coastguard Worker                 extra);
793*6dbdd20aSAndroid Build Coastguard Worker         dbg->set_int_value(arg.value);
794*6dbdd20aSAndroid Build Coastguard Worker         arg_name = arg.name;
795*6dbdd20aSAndroid Build Coastguard Worker       } else if (extra.type == PERFETTO_TE_HL_EXTRA_TYPE_DEBUG_ARG_DOUBLE) {
796*6dbdd20aSAndroid Build Coastguard Worker         const auto& arg =
797*6dbdd20aSAndroid Build Coastguard Worker             reinterpret_cast<const struct PerfettoTeHlExtraDebugArgDouble&>(
798*6dbdd20aSAndroid Build Coastguard Worker                 extra);
799*6dbdd20aSAndroid Build Coastguard Worker         dbg->set_double_value(arg.value);
800*6dbdd20aSAndroid Build Coastguard Worker         arg_name = arg.name;
801*6dbdd20aSAndroid Build Coastguard Worker       } else if (extra.type == PERFETTO_TE_HL_EXTRA_TYPE_DEBUG_ARG_STRING) {
802*6dbdd20aSAndroid Build Coastguard Worker         const auto& arg =
803*6dbdd20aSAndroid Build Coastguard Worker             reinterpret_cast<const struct PerfettoTeHlExtraDebugArgString&>(
804*6dbdd20aSAndroid Build Coastguard Worker                 extra);
805*6dbdd20aSAndroid Build Coastguard Worker         dbg->set_string_value(arg.value);
806*6dbdd20aSAndroid Build Coastguard Worker         arg_name = arg.name;
807*6dbdd20aSAndroid Build Coastguard Worker       } else if (extra.type == PERFETTO_TE_HL_EXTRA_TYPE_DEBUG_ARG_POINTER) {
808*6dbdd20aSAndroid Build Coastguard Worker         const auto& arg =
809*6dbdd20aSAndroid Build Coastguard Worker             reinterpret_cast<const struct PerfettoTeHlExtraDebugArgPointer&>(
810*6dbdd20aSAndroid Build Coastguard Worker                 extra);
811*6dbdd20aSAndroid Build Coastguard Worker         dbg->set_pointer_value(arg.value);
812*6dbdd20aSAndroid Build Coastguard Worker         arg_name = arg.name;
813*6dbdd20aSAndroid Build Coastguard Worker       }
814*6dbdd20aSAndroid Build Coastguard Worker 
815*6dbdd20aSAndroid Build Coastguard Worker       if (arg_name != nullptr) {
816*6dbdd20aSAndroid Build Coastguard Worker         const void* str = arg_name;
817*6dbdd20aSAndroid Build Coastguard Worker         size_t len = strlen(arg_name);
818*6dbdd20aSAndroid Build Coastguard Worker         auto res =
819*6dbdd20aSAndroid Build Coastguard Worker             incr->iids.FindOrAssign(perfetto::protos::pbzero::InternedData::
820*6dbdd20aSAndroid Build Coastguard Worker                                         kDebugAnnotationNamesFieldNumber,
821*6dbdd20aSAndroid Build Coastguard Worker                                     str, len);
822*6dbdd20aSAndroid Build Coastguard Worker         if (res.newly_assigned) {
823*6dbdd20aSAndroid Build Coastguard Worker           auto* ser =
824*6dbdd20aSAndroid Build Coastguard Worker               incr->serialized_interned_data->add_debug_annotation_names();
825*6dbdd20aSAndroid Build Coastguard Worker           ser->set_iid(res.iid);
826*6dbdd20aSAndroid Build Coastguard Worker           ser->set_name(arg_name);
827*6dbdd20aSAndroid Build Coastguard Worker         }
828*6dbdd20aSAndroid Build Coastguard Worker         dbg->set_name_iid(res.iid);
829*6dbdd20aSAndroid Build Coastguard Worker       }
830*6dbdd20aSAndroid Build Coastguard Worker     }
831*6dbdd20aSAndroid Build Coastguard Worker   }
832*6dbdd20aSAndroid Build Coastguard Worker 
833*6dbdd20aSAndroid Build Coastguard Worker   for (const auto* it = extra_data; *it != nullptr; it++) {
834*6dbdd20aSAndroid Build Coastguard Worker     const struct PerfettoTeHlExtra& extra = **it;
835*6dbdd20aSAndroid Build Coastguard Worker     if (extra.type == PERFETTO_TE_HL_EXTRA_TYPE_FLOW) {
836*6dbdd20aSAndroid Build Coastguard Worker       event->add_flow_ids(
837*6dbdd20aSAndroid Build Coastguard Worker           reinterpret_cast<const struct PerfettoTeHlExtraFlow&>(extra).id);
838*6dbdd20aSAndroid Build Coastguard Worker     }
839*6dbdd20aSAndroid Build Coastguard Worker   }
840*6dbdd20aSAndroid Build Coastguard Worker 
841*6dbdd20aSAndroid Build Coastguard Worker   for (const auto* it = extra_data; *it != nullptr; it++) {
842*6dbdd20aSAndroid Build Coastguard Worker     const struct PerfettoTeHlExtra& extra = **it;
843*6dbdd20aSAndroid Build Coastguard Worker     if (extra.type == PERFETTO_TE_HL_EXTRA_TYPE_TERMINATING_FLOW) {
844*6dbdd20aSAndroid Build Coastguard Worker       event->add_terminating_flow_ids(
845*6dbdd20aSAndroid Build Coastguard Worker           reinterpret_cast<const struct PerfettoTeHlExtraFlow&>(extra).id);
846*6dbdd20aSAndroid Build Coastguard Worker     }
847*6dbdd20aSAndroid Build Coastguard Worker   }
848*6dbdd20aSAndroid Build Coastguard Worker 
849*6dbdd20aSAndroid Build Coastguard Worker   for (const auto* it = extra_data; *it != nullptr; it++) {
850*6dbdd20aSAndroid Build Coastguard Worker     const struct PerfettoTeHlExtra& extra = **it;
851*6dbdd20aSAndroid Build Coastguard Worker     if (extra.type == PERFETTO_TE_HL_EXTRA_TYPE_PROTO_FIELDS) {
852*6dbdd20aSAndroid Build Coastguard Worker       const auto* fields =
853*6dbdd20aSAndroid Build Coastguard Worker           reinterpret_cast<const struct PerfettoTeHlExtraProtoFields&>(extra)
854*6dbdd20aSAndroid Build Coastguard Worker               .fields;
855*6dbdd20aSAndroid Build Coastguard Worker       AppendHlProtoFields(event, fields);
856*6dbdd20aSAndroid Build Coastguard Worker     }
857*6dbdd20aSAndroid Build Coastguard Worker   }
858*6dbdd20aSAndroid Build Coastguard Worker }
859*6dbdd20aSAndroid Build Coastguard Worker 
860*6dbdd20aSAndroid Build Coastguard Worker }  // namespace
861*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoTeCategoryImplCreate(struct PerfettoTeCategoryDescriptor * desc)862*6dbdd20aSAndroid Build Coastguard Worker struct PerfettoTeCategoryImpl* PerfettoTeCategoryImplCreate(
863*6dbdd20aSAndroid Build Coastguard Worker     struct PerfettoTeCategoryDescriptor* desc) {
864*6dbdd20aSAndroid Build Coastguard Worker   auto* cat = new PerfettoTeCategoryImpl;
865*6dbdd20aSAndroid Build Coastguard Worker   cat->desc = desc;
866*6dbdd20aSAndroid Build Coastguard Worker   perfetto::shlib::TrackEvent::RegisterCategory(cat);
867*6dbdd20aSAndroid Build Coastguard Worker   return cat;
868*6dbdd20aSAndroid Build Coastguard Worker }
869*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoTePublishCategories()870*6dbdd20aSAndroid Build Coastguard Worker void PerfettoTePublishCategories() {
871*6dbdd20aSAndroid Build Coastguard Worker   perfetto::shlib::TrackEvent::UpdateDescriptorFromCategories();
872*6dbdd20aSAndroid Build Coastguard Worker }
873*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoTeCategoryImplSetCallback(struct PerfettoTeCategoryImpl * cat,PerfettoTeCategoryImplCallback cb,void * user_arg)874*6dbdd20aSAndroid Build Coastguard Worker void PerfettoTeCategoryImplSetCallback(struct PerfettoTeCategoryImpl* cat,
875*6dbdd20aSAndroid Build Coastguard Worker                                        PerfettoTeCategoryImplCallback cb,
876*6dbdd20aSAndroid Build Coastguard Worker                                        void* user_arg) {
877*6dbdd20aSAndroid Build Coastguard Worker   perfetto::shlib::TrackEvent::CategorySetCallback(cat, cb, user_arg);
878*6dbdd20aSAndroid Build Coastguard Worker }
879*6dbdd20aSAndroid Build Coastguard Worker 
PERFETTO_ATOMIC(bool)880*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_ATOMIC(bool) *
881*6dbdd20aSAndroid Build Coastguard Worker     PerfettoTeCategoryImplGetEnabled(struct PerfettoTeCategoryImpl* cat) {
882*6dbdd20aSAndroid Build Coastguard Worker   return &cat->flag;
883*6dbdd20aSAndroid Build Coastguard Worker }
884*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoTeCategoryImplGetIid(struct PerfettoTeCategoryImpl * cat)885*6dbdd20aSAndroid Build Coastguard Worker uint64_t PerfettoTeCategoryImplGetIid(struct PerfettoTeCategoryImpl* cat) {
886*6dbdd20aSAndroid Build Coastguard Worker   return cat->cat_iid;
887*6dbdd20aSAndroid Build Coastguard Worker }
888*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoTeCategoryImplDestroy(struct PerfettoTeCategoryImpl * cat)889*6dbdd20aSAndroid Build Coastguard Worker void PerfettoTeCategoryImplDestroy(struct PerfettoTeCategoryImpl* cat) {
890*6dbdd20aSAndroid Build Coastguard Worker   perfetto::shlib::TrackEvent::UnregisterCategory(cat);
891*6dbdd20aSAndroid Build Coastguard Worker   delete cat;
892*6dbdd20aSAndroid Build Coastguard Worker }
893*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoTeInit(void)894*6dbdd20aSAndroid Build Coastguard Worker void PerfettoTeInit(void) {
895*6dbdd20aSAndroid Build Coastguard Worker   perfetto::shlib::TrackEvent::Init();
896*6dbdd20aSAndroid Build Coastguard Worker   perfetto_te_process_track_uuid =
897*6dbdd20aSAndroid Build Coastguard Worker       perfetto::internal::TrackRegistry::ComputeProcessUuid();
898*6dbdd20aSAndroid Build Coastguard Worker }
899*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoTeGetTimestamp(void)900*6dbdd20aSAndroid Build Coastguard Worker struct PerfettoTeTimestamp PerfettoTeGetTimestamp(void) {
901*6dbdd20aSAndroid Build Coastguard Worker   struct PerfettoTeTimestamp ret;
902*6dbdd20aSAndroid Build Coastguard Worker   ret.clock_id = PERFETTO_TE_TIMESTAMP_TYPE_BOOT;
903*6dbdd20aSAndroid Build Coastguard Worker   ret.value = TrackEventInternal::GetTimeNs();
904*6dbdd20aSAndroid Build Coastguard Worker   return ret;
905*6dbdd20aSAndroid Build Coastguard Worker }
906*6dbdd20aSAndroid Build Coastguard Worker 
IsDynamicCategoryEnabled(uint32_t inst_idx,perfetto::shlib::TrackEventIncrementalState * incr_state,const struct PerfettoTeCategoryDescriptor & desc)907*6dbdd20aSAndroid Build Coastguard Worker static bool IsDynamicCategoryEnabled(
908*6dbdd20aSAndroid Build Coastguard Worker     uint32_t inst_idx,
909*6dbdd20aSAndroid Build Coastguard Worker     perfetto::shlib::TrackEventIncrementalState* incr_state,
910*6dbdd20aSAndroid Build Coastguard Worker     const struct PerfettoTeCategoryDescriptor& desc) {
911*6dbdd20aSAndroid Build Coastguard Worker   constexpr size_t kMaxCacheSize = 20;
912*6dbdd20aSAndroid Build Coastguard Worker   perfetto::internal::DataSourceType* ds =
913*6dbdd20aSAndroid Build Coastguard Worker       perfetto::shlib::TrackEvent::GetType();
914*6dbdd20aSAndroid Build Coastguard Worker   auto& cache = incr_state->dynamic_categories;
915*6dbdd20aSAndroid Build Coastguard Worker   protozero::HeapBuffered<perfetto::protos::pbzero::TrackEventDescriptor> ted;
916*6dbdd20aSAndroid Build Coastguard Worker   SerializeCategory(desc, ted.get());
917*6dbdd20aSAndroid Build Coastguard Worker   std::string serialized = ted.SerializeAsString();
918*6dbdd20aSAndroid Build Coastguard Worker   auto* cached = cache.Find(serialized);
919*6dbdd20aSAndroid Build Coastguard Worker   if (cached) {
920*6dbdd20aSAndroid Build Coastguard Worker     return *cached;
921*6dbdd20aSAndroid Build Coastguard Worker   }
922*6dbdd20aSAndroid Build Coastguard Worker 
923*6dbdd20aSAndroid Build Coastguard Worker   auto* internal_state = ds->static_state()->TryGet(inst_idx);
924*6dbdd20aSAndroid Build Coastguard Worker   if (!internal_state)
925*6dbdd20aSAndroid Build Coastguard Worker     return false;
926*6dbdd20aSAndroid Build Coastguard Worker   std::unique_lock<std::recursive_mutex> lock(internal_state->lock);
927*6dbdd20aSAndroid Build Coastguard Worker   auto* sds = static_cast<perfetto::shlib::TrackEvent*>(
928*6dbdd20aSAndroid Build Coastguard Worker       internal_state->data_source.get());
929*6dbdd20aSAndroid Build Coastguard Worker 
930*6dbdd20aSAndroid Build Coastguard Worker   bool res = IsSingleCategoryEnabled(desc, sds->GetConfig());
931*6dbdd20aSAndroid Build Coastguard Worker   if (cache.size() < kMaxCacheSize) {
932*6dbdd20aSAndroid Build Coastguard Worker     cache[serialized] = res;
933*6dbdd20aSAndroid Build Coastguard Worker   }
934*6dbdd20aSAndroid Build Coastguard Worker   return res;
935*6dbdd20aSAndroid Build Coastguard Worker }
936*6dbdd20aSAndroid Build Coastguard Worker 
937*6dbdd20aSAndroid Build Coastguard Worker // If the category `dyn_cat` is enabled on the data source instance pointed by
938*6dbdd20aSAndroid Build Coastguard Worker // `ii`, returns immediately. Otherwise, advances `ii` to a data source instance
939*6dbdd20aSAndroid Build Coastguard Worker // where `dyn_cat` is enabled. If there's no data source instance where
940*6dbdd20aSAndroid Build Coastguard Worker // `dyn_cat` is enabled, `ii->instance` will be nullptr.
AdvanceToFirstEnabledDynamicCategory(perfetto::internal::DataSourceType::InstancesIterator * ii,perfetto::internal::DataSourceThreadLocalState * tls_state,struct PerfettoTeCategoryImpl * cat,const PerfettoTeCategoryDescriptor & dyn_cat)941*6dbdd20aSAndroid Build Coastguard Worker static void AdvanceToFirstEnabledDynamicCategory(
942*6dbdd20aSAndroid Build Coastguard Worker     perfetto::internal::DataSourceType::InstancesIterator* ii,
943*6dbdd20aSAndroid Build Coastguard Worker     perfetto::internal::DataSourceThreadLocalState* tls_state,
944*6dbdd20aSAndroid Build Coastguard Worker     struct PerfettoTeCategoryImpl* cat,
945*6dbdd20aSAndroid Build Coastguard Worker     const PerfettoTeCategoryDescriptor& dyn_cat) {
946*6dbdd20aSAndroid Build Coastguard Worker   perfetto::internal::DataSourceType* ds =
947*6dbdd20aSAndroid Build Coastguard Worker       perfetto::shlib::TrackEvent::GetType();
948*6dbdd20aSAndroid Build Coastguard Worker   for (; ii->instance;
949*6dbdd20aSAndroid Build Coastguard Worker        ds->NextIteration</*Traits=*/perfetto::shlib::TracePointTraits>(
950*6dbdd20aSAndroid Build Coastguard Worker            ii, tls_state, {cat})) {
951*6dbdd20aSAndroid Build Coastguard Worker     auto* incr_state =
952*6dbdd20aSAndroid Build Coastguard Worker         static_cast<perfetto::shlib::TrackEventIncrementalState*>(
953*6dbdd20aSAndroid Build Coastguard Worker             ds->GetIncrementalState(ii->instance, ii->i));
954*6dbdd20aSAndroid Build Coastguard Worker     if (IsDynamicCategoryEnabled(ii->i, incr_state, dyn_cat)) {
955*6dbdd20aSAndroid Build Coastguard Worker       break;
956*6dbdd20aSAndroid Build Coastguard Worker     }
957*6dbdd20aSAndroid Build Coastguard Worker   }
958*6dbdd20aSAndroid Build Coastguard Worker }
959*6dbdd20aSAndroid Build Coastguard Worker 
InstanceOp(perfetto::internal::DataSourceType * ds,perfetto::internal::DataSourceType::InstancesIterator * ii,perfetto::internal::DataSourceThreadLocalState * tls_state,struct PerfettoTeCategoryImpl * cat,perfetto::protos::pbzero::TrackEvent::Type type,const char * name,struct PerfettoTeHlExtra * const * extra_data)960*6dbdd20aSAndroid Build Coastguard Worker static void InstanceOp(
961*6dbdd20aSAndroid Build Coastguard Worker     perfetto::internal::DataSourceType* ds,
962*6dbdd20aSAndroid Build Coastguard Worker     perfetto::internal::DataSourceType::InstancesIterator* ii,
963*6dbdd20aSAndroid Build Coastguard Worker     perfetto::internal::DataSourceThreadLocalState* tls_state,
964*6dbdd20aSAndroid Build Coastguard Worker     struct PerfettoTeCategoryImpl* cat,
965*6dbdd20aSAndroid Build Coastguard Worker     perfetto::protos::pbzero::TrackEvent::Type type,
966*6dbdd20aSAndroid Build Coastguard Worker     const char* name,
967*6dbdd20aSAndroid Build Coastguard Worker     struct PerfettoTeHlExtra* const* extra_data) {
968*6dbdd20aSAndroid Build Coastguard Worker   if (!ii->instance) {
969*6dbdd20aSAndroid Build Coastguard Worker     return;
970*6dbdd20aSAndroid Build Coastguard Worker   }
971*6dbdd20aSAndroid Build Coastguard Worker 
972*6dbdd20aSAndroid Build Coastguard Worker   std::variant<std::monostate, const PerfettoTeRegisteredTrackImpl*,
973*6dbdd20aSAndroid Build Coastguard Worker                const PerfettoTeHlExtraNamedTrack*,
974*6dbdd20aSAndroid Build Coastguard Worker                const PerfettoTeHlExtraProtoTrack*>
975*6dbdd20aSAndroid Build Coastguard Worker       track;
976*6dbdd20aSAndroid Build Coastguard Worker   std::optional<uint64_t> track_uuid;
977*6dbdd20aSAndroid Build Coastguard Worker 
978*6dbdd20aSAndroid Build Coastguard Worker   const struct PerfettoTeHlExtraTimestamp* custom_timestamp = nullptr;
979*6dbdd20aSAndroid Build Coastguard Worker   const struct PerfettoTeCategoryDescriptor* dynamic_cat = nullptr;
980*6dbdd20aSAndroid Build Coastguard Worker   std::optional<int64_t> int_counter;
981*6dbdd20aSAndroid Build Coastguard Worker   std::optional<double> double_counter;
982*6dbdd20aSAndroid Build Coastguard Worker   bool use_interning = true;
983*6dbdd20aSAndroid Build Coastguard Worker   bool flush = false;
984*6dbdd20aSAndroid Build Coastguard Worker 
985*6dbdd20aSAndroid Build Coastguard Worker   for (const auto* it = extra_data; *it != nullptr; it++) {
986*6dbdd20aSAndroid Build Coastguard Worker     const struct PerfettoTeHlExtra& extra = **it;
987*6dbdd20aSAndroid Build Coastguard Worker     if (extra.type == PERFETTO_TE_HL_EXTRA_TYPE_REGISTERED_TRACK) {
988*6dbdd20aSAndroid Build Coastguard Worker       const auto& cast =
989*6dbdd20aSAndroid Build Coastguard Worker           reinterpret_cast<const struct PerfettoTeHlExtraRegisteredTrack&>(
990*6dbdd20aSAndroid Build Coastguard Worker               extra);
991*6dbdd20aSAndroid Build Coastguard Worker       track = cast.track;
992*6dbdd20aSAndroid Build Coastguard Worker     } else if (extra.type == PERFETTO_TE_HL_EXTRA_TYPE_NAMED_TRACK) {
993*6dbdd20aSAndroid Build Coastguard Worker       track =
994*6dbdd20aSAndroid Build Coastguard Worker           &reinterpret_cast<const struct PerfettoTeHlExtraNamedTrack&>(extra);
995*6dbdd20aSAndroid Build Coastguard Worker     } else if (extra.type == PERFETTO_TE_HL_EXTRA_TYPE_PROTO_TRACK) {
996*6dbdd20aSAndroid Build Coastguard Worker       track =
997*6dbdd20aSAndroid Build Coastguard Worker           &reinterpret_cast<const struct PerfettoTeHlExtraProtoTrack&>(extra);
998*6dbdd20aSAndroid Build Coastguard Worker     } else if (extra.type == PERFETTO_TE_HL_EXTRA_TYPE_TIMESTAMP) {
999*6dbdd20aSAndroid Build Coastguard Worker       custom_timestamp =
1000*6dbdd20aSAndroid Build Coastguard Worker           &reinterpret_cast<const struct PerfettoTeHlExtraTimestamp&>(extra);
1001*6dbdd20aSAndroid Build Coastguard Worker     } else if (extra.type == PERFETTO_TE_HL_EXTRA_TYPE_DYNAMIC_CATEGORY) {
1002*6dbdd20aSAndroid Build Coastguard Worker       dynamic_cat =
1003*6dbdd20aSAndroid Build Coastguard Worker           reinterpret_cast<const struct PerfettoTeHlExtraDynamicCategory&>(
1004*6dbdd20aSAndroid Build Coastguard Worker               extra)
1005*6dbdd20aSAndroid Build Coastguard Worker               .desc;
1006*6dbdd20aSAndroid Build Coastguard Worker     } else if (extra.type == PERFETTO_TE_HL_EXTRA_TYPE_COUNTER_INT64) {
1007*6dbdd20aSAndroid Build Coastguard Worker       int_counter =
1008*6dbdd20aSAndroid Build Coastguard Worker           reinterpret_cast<const struct PerfettoTeHlExtraCounterInt64&>(extra)
1009*6dbdd20aSAndroid Build Coastguard Worker               .value;
1010*6dbdd20aSAndroid Build Coastguard Worker     } else if (extra.type == PERFETTO_TE_HL_EXTRA_TYPE_COUNTER_DOUBLE) {
1011*6dbdd20aSAndroid Build Coastguard Worker       double_counter =
1012*6dbdd20aSAndroid Build Coastguard Worker           reinterpret_cast<const struct PerfettoTeHlExtraCounterInt64&>(extra)
1013*6dbdd20aSAndroid Build Coastguard Worker               .value;
1014*6dbdd20aSAndroid Build Coastguard Worker     } else if (extra.type == PERFETTO_TE_HL_EXTRA_TYPE_NO_INTERN) {
1015*6dbdd20aSAndroid Build Coastguard Worker       use_interning = false;
1016*6dbdd20aSAndroid Build Coastguard Worker     } else if (extra.type == PERFETTO_TE_HL_EXTRA_TYPE_FLUSH) {
1017*6dbdd20aSAndroid Build Coastguard Worker       flush = true;
1018*6dbdd20aSAndroid Build Coastguard Worker     }
1019*6dbdd20aSAndroid Build Coastguard Worker   }
1020*6dbdd20aSAndroid Build Coastguard Worker 
1021*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceTimestamp ts;
1022*6dbdd20aSAndroid Build Coastguard Worker   if (custom_timestamp) {
1023*6dbdd20aSAndroid Build Coastguard Worker     ts.clock_id = custom_timestamp->timestamp.clock_id;
1024*6dbdd20aSAndroid Build Coastguard Worker     ts.value = custom_timestamp->timestamp.value;
1025*6dbdd20aSAndroid Build Coastguard Worker   } else {
1026*6dbdd20aSAndroid Build Coastguard Worker     ts = TrackEventInternal::GetTraceTime();
1027*6dbdd20aSAndroid Build Coastguard Worker   }
1028*6dbdd20aSAndroid Build Coastguard Worker 
1029*6dbdd20aSAndroid Build Coastguard Worker   if (PERFETTO_UNLIKELY(dynamic_cat)) {
1030*6dbdd20aSAndroid Build Coastguard Worker     AdvanceToFirstEnabledDynamicCategory(ii, tls_state, cat, *dynamic_cat);
1031*6dbdd20aSAndroid Build Coastguard Worker     if (!ii->instance) {
1032*6dbdd20aSAndroid Build Coastguard Worker       return;
1033*6dbdd20aSAndroid Build Coastguard Worker     }
1034*6dbdd20aSAndroid Build Coastguard Worker   }
1035*6dbdd20aSAndroid Build Coastguard Worker 
1036*6dbdd20aSAndroid Build Coastguard Worker   const auto& track_event_tls =
1037*6dbdd20aSAndroid Build Coastguard Worker       *static_cast<perfetto::shlib::TrackEventTlsState*>(
1038*6dbdd20aSAndroid Build Coastguard Worker           ii->instance->data_source_custom_tls.get());
1039*6dbdd20aSAndroid Build Coastguard Worker 
1040*6dbdd20aSAndroid Build Coastguard Worker   auto* incr_state = static_cast<perfetto::shlib::TrackEventIncrementalState*>(
1041*6dbdd20aSAndroid Build Coastguard Worker       ds->GetIncrementalState(ii->instance, ii->i));
1042*6dbdd20aSAndroid Build Coastguard Worker   ResetIncrementalStateIfRequired(ii->instance->trace_writer.get(), incr_state,
1043*6dbdd20aSAndroid Build Coastguard Worker                                   track_event_tls, ts);
1044*6dbdd20aSAndroid Build Coastguard Worker 
1045*6dbdd20aSAndroid Build Coastguard Worker   if (std::holds_alternative<const PerfettoTeRegisteredTrackImpl*>(track)) {
1046*6dbdd20aSAndroid Build Coastguard Worker     auto* registered_track =
1047*6dbdd20aSAndroid Build Coastguard Worker         std::get<const PerfettoTeRegisteredTrackImpl*>(track);
1048*6dbdd20aSAndroid Build Coastguard Worker     if (incr_state->seen_track_uuids.insert(registered_track->uuid).second) {
1049*6dbdd20aSAndroid Build Coastguard Worker       auto packet = ii->instance->trace_writer->NewTracePacket();
1050*6dbdd20aSAndroid Build Coastguard Worker       auto* track_descriptor = packet->set_track_descriptor();
1051*6dbdd20aSAndroid Build Coastguard Worker       track_descriptor->AppendRawProtoBytes(registered_track->descriptor,
1052*6dbdd20aSAndroid Build Coastguard Worker                                             registered_track->descriptor_size);
1053*6dbdd20aSAndroid Build Coastguard Worker     }
1054*6dbdd20aSAndroid Build Coastguard Worker     track_uuid = registered_track->uuid;
1055*6dbdd20aSAndroid Build Coastguard Worker   } else if (std::holds_alternative<const PerfettoTeHlExtraNamedTrack*>(
1056*6dbdd20aSAndroid Build Coastguard Worker                  track)) {
1057*6dbdd20aSAndroid Build Coastguard Worker     auto* named_track = std::get<const PerfettoTeHlExtraNamedTrack*>(track);
1058*6dbdd20aSAndroid Build Coastguard Worker     uint64_t uuid = named_track->parent_uuid;
1059*6dbdd20aSAndroid Build Coastguard Worker     uuid ^= PerfettoFnv1a(named_track->name, strlen(named_track->name));
1060*6dbdd20aSAndroid Build Coastguard Worker     uuid ^= named_track->id;
1061*6dbdd20aSAndroid Build Coastguard Worker     if (incr_state->seen_track_uuids.insert(uuid).second) {
1062*6dbdd20aSAndroid Build Coastguard Worker       auto packet = ii->instance->trace_writer->NewTracePacket();
1063*6dbdd20aSAndroid Build Coastguard Worker       auto* track_descriptor = packet->set_track_descriptor();
1064*6dbdd20aSAndroid Build Coastguard Worker       track_descriptor->set_uuid(uuid);
1065*6dbdd20aSAndroid Build Coastguard Worker       if (named_track->parent_uuid) {
1066*6dbdd20aSAndroid Build Coastguard Worker         track_descriptor->set_parent_uuid(named_track->parent_uuid);
1067*6dbdd20aSAndroid Build Coastguard Worker       }
1068*6dbdd20aSAndroid Build Coastguard Worker       track_descriptor->set_name(named_track->name);
1069*6dbdd20aSAndroid Build Coastguard Worker     }
1070*6dbdd20aSAndroid Build Coastguard Worker     track_uuid = uuid;
1071*6dbdd20aSAndroid Build Coastguard Worker   } else if (std::holds_alternative<const PerfettoTeHlExtraProtoTrack*>(
1072*6dbdd20aSAndroid Build Coastguard Worker                  track)) {
1073*6dbdd20aSAndroid Build Coastguard Worker     auto* counter_track = std::get<const PerfettoTeHlExtraProtoTrack*>(track);
1074*6dbdd20aSAndroid Build Coastguard Worker     uint64_t uuid = counter_track->uuid;
1075*6dbdd20aSAndroid Build Coastguard Worker     if (incr_state->seen_track_uuids.insert(uuid).second) {
1076*6dbdd20aSAndroid Build Coastguard Worker       auto packet = ii->instance->trace_writer->NewTracePacket();
1077*6dbdd20aSAndroid Build Coastguard Worker       auto* track_descriptor = packet->set_track_descriptor();
1078*6dbdd20aSAndroid Build Coastguard Worker       track_descriptor->set_uuid(uuid);
1079*6dbdd20aSAndroid Build Coastguard Worker       AppendHlProtoFields(track_descriptor, counter_track->fields);
1080*6dbdd20aSAndroid Build Coastguard Worker     }
1081*6dbdd20aSAndroid Build Coastguard Worker     track_uuid = uuid;
1082*6dbdd20aSAndroid Build Coastguard Worker   }
1083*6dbdd20aSAndroid Build Coastguard Worker 
1084*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceWriterBase* trace_writer = ii->instance->trace_writer.get();
1085*6dbdd20aSAndroid Build Coastguard Worker   {
1086*6dbdd20aSAndroid Build Coastguard Worker     auto packet = NewTracePacketInternal(
1087*6dbdd20aSAndroid Build Coastguard Worker         trace_writer, incr_state, track_event_tls, ts,
1088*6dbdd20aSAndroid Build Coastguard Worker         perfetto::protos::pbzero::TracePacket::SEQ_NEEDS_INCREMENTAL_STATE);
1089*6dbdd20aSAndroid Build Coastguard Worker     auto* track_event = packet->set_track_event();
1090*6dbdd20aSAndroid Build Coastguard Worker     WriteTrackEvent(incr_state, track_event, cat, type, name, extra_data,
1091*6dbdd20aSAndroid Build Coastguard Worker                     track_uuid, dynamic_cat, use_interning);
1092*6dbdd20aSAndroid Build Coastguard Worker     track_event->Finalize();
1093*6dbdd20aSAndroid Build Coastguard Worker 
1094*6dbdd20aSAndroid Build Coastguard Worker     if (!incr_state->serialized_interned_data.empty()) {
1095*6dbdd20aSAndroid Build Coastguard Worker       auto ranges = incr_state->serialized_interned_data.GetRanges();
1096*6dbdd20aSAndroid Build Coastguard Worker       packet->AppendScatteredBytes(
1097*6dbdd20aSAndroid Build Coastguard Worker           perfetto::protos::pbzero::TracePacket::kInternedDataFieldNumber,
1098*6dbdd20aSAndroid Build Coastguard Worker           ranges.data(), ranges.size());
1099*6dbdd20aSAndroid Build Coastguard Worker       incr_state->serialized_interned_data.Reset();
1100*6dbdd20aSAndroid Build Coastguard Worker     }
1101*6dbdd20aSAndroid Build Coastguard Worker   }
1102*6dbdd20aSAndroid Build Coastguard Worker 
1103*6dbdd20aSAndroid Build Coastguard Worker   if (PERFETTO_UNLIKELY(flush)) {
1104*6dbdd20aSAndroid Build Coastguard Worker     trace_writer->Flush();
1105*6dbdd20aSAndroid Build Coastguard Worker   }
1106*6dbdd20aSAndroid Build Coastguard Worker }
1107*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoTeHlEmitImpl(struct PerfettoTeCategoryImpl * cat,int32_t type,const char * name,struct PerfettoTeHlExtra * const * extra_data)1108*6dbdd20aSAndroid Build Coastguard Worker void PerfettoTeHlEmitImpl(struct PerfettoTeCategoryImpl* cat,
1109*6dbdd20aSAndroid Build Coastguard Worker                           int32_t type,
1110*6dbdd20aSAndroid Build Coastguard Worker                           const char* name,
1111*6dbdd20aSAndroid Build Coastguard Worker                           struct PerfettoTeHlExtra* const* extra_data) {
1112*6dbdd20aSAndroid Build Coastguard Worker   uint32_t cached_instances =
1113*6dbdd20aSAndroid Build Coastguard Worker       perfetto::shlib::TracePointTraits::GetActiveInstances({cat})->load(
1114*6dbdd20aSAndroid Build Coastguard Worker           std::memory_order_relaxed);
1115*6dbdd20aSAndroid Build Coastguard Worker   if (!cached_instances) {
1116*6dbdd20aSAndroid Build Coastguard Worker     return;
1117*6dbdd20aSAndroid Build Coastguard Worker   }
1118*6dbdd20aSAndroid Build Coastguard Worker 
1119*6dbdd20aSAndroid Build Coastguard Worker   perfetto::internal::DataSourceType* ds =
1120*6dbdd20aSAndroid Build Coastguard Worker       perfetto::shlib::TrackEvent::GetType();
1121*6dbdd20aSAndroid Build Coastguard Worker 
1122*6dbdd20aSAndroid Build Coastguard Worker   perfetto::internal::DataSourceThreadLocalState*& tls_state =
1123*6dbdd20aSAndroid Build Coastguard Worker       *perfetto::shlib::TrackEvent::GetTlsState();
1124*6dbdd20aSAndroid Build Coastguard Worker 
1125*6dbdd20aSAndroid Build Coastguard Worker   if (!ds->TracePrologue<perfetto::shlib::TrackEventDataSourceTraits,
1126*6dbdd20aSAndroid Build Coastguard Worker                          perfetto::shlib::TracePointTraits>(
1127*6dbdd20aSAndroid Build Coastguard Worker           &tls_state, &cached_instances, {cat})) {
1128*6dbdd20aSAndroid Build Coastguard Worker     return;
1129*6dbdd20aSAndroid Build Coastguard Worker   }
1130*6dbdd20aSAndroid Build Coastguard Worker 
1131*6dbdd20aSAndroid Build Coastguard Worker   for (perfetto::internal::DataSourceType::InstancesIterator ii =
1132*6dbdd20aSAndroid Build Coastguard Worker            ds->BeginIteration<perfetto::shlib::TracePointTraits>(
1133*6dbdd20aSAndroid Build Coastguard Worker                cached_instances, tls_state, {cat});
1134*6dbdd20aSAndroid Build Coastguard Worker        ii.instance;
1135*6dbdd20aSAndroid Build Coastguard Worker        ds->NextIteration</*Traits=*/perfetto::shlib::TracePointTraits>(
1136*6dbdd20aSAndroid Build Coastguard Worker            &ii, tls_state, {cat})) {
1137*6dbdd20aSAndroid Build Coastguard Worker     InstanceOp(ds, &ii, tls_state, cat, EventType(type), name, extra_data);
1138*6dbdd20aSAndroid Build Coastguard Worker   }
1139*6dbdd20aSAndroid Build Coastguard Worker   ds->TraceEpilogue(tls_state);
1140*6dbdd20aSAndroid Build Coastguard Worker }
1141*6dbdd20aSAndroid Build Coastguard Worker 
FillIterator(const perfetto::internal::DataSourceType::InstancesIterator * ii,struct PerfettoTeTimestamp ts,struct PerfettoTeLlImplIterator * iterator)1142*6dbdd20aSAndroid Build Coastguard Worker static void FillIterator(
1143*6dbdd20aSAndroid Build Coastguard Worker     const perfetto::internal::DataSourceType::InstancesIterator* ii,
1144*6dbdd20aSAndroid Build Coastguard Worker     struct PerfettoTeTimestamp ts,
1145*6dbdd20aSAndroid Build Coastguard Worker     struct PerfettoTeLlImplIterator* iterator) {
1146*6dbdd20aSAndroid Build Coastguard Worker   perfetto::internal::DataSourceType* ds =
1147*6dbdd20aSAndroid Build Coastguard Worker       perfetto::shlib::TrackEvent::GetType();
1148*6dbdd20aSAndroid Build Coastguard Worker 
1149*6dbdd20aSAndroid Build Coastguard Worker   auto& track_event_tls = *static_cast<perfetto::shlib::TrackEventTlsState*>(
1150*6dbdd20aSAndroid Build Coastguard Worker       ii->instance->data_source_custom_tls.get());
1151*6dbdd20aSAndroid Build Coastguard Worker 
1152*6dbdd20aSAndroid Build Coastguard Worker   auto* incr_state = static_cast<perfetto::shlib::TrackEventIncrementalState*>(
1153*6dbdd20aSAndroid Build Coastguard Worker       ds->GetIncrementalState(ii->instance, ii->i));
1154*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceTimestamp tts;
1155*6dbdd20aSAndroid Build Coastguard Worker   tts.clock_id = ts.clock_id;
1156*6dbdd20aSAndroid Build Coastguard Worker   tts.value = ts.value;
1157*6dbdd20aSAndroid Build Coastguard Worker   ResetIncrementalStateIfRequired(ii->instance->trace_writer.get(), incr_state,
1158*6dbdd20aSAndroid Build Coastguard Worker                                   track_event_tls, tts);
1159*6dbdd20aSAndroid Build Coastguard Worker 
1160*6dbdd20aSAndroid Build Coastguard Worker   iterator->incr = reinterpret_cast<struct PerfettoTeLlImplIncr*>(incr_state);
1161*6dbdd20aSAndroid Build Coastguard Worker   iterator->tls =
1162*6dbdd20aSAndroid Build Coastguard Worker       reinterpret_cast<struct PerfettoTeLlImplTls*>(&track_event_tls);
1163*6dbdd20aSAndroid Build Coastguard Worker }
1164*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoTeLlImplBegin(struct PerfettoTeCategoryImpl * cat,struct PerfettoTeTimestamp ts)1165*6dbdd20aSAndroid Build Coastguard Worker struct PerfettoTeLlImplIterator PerfettoTeLlImplBegin(
1166*6dbdd20aSAndroid Build Coastguard Worker     struct PerfettoTeCategoryImpl* cat,
1167*6dbdd20aSAndroid Build Coastguard Worker     struct PerfettoTeTimestamp ts) {
1168*6dbdd20aSAndroid Build Coastguard Worker   struct PerfettoTeLlImplIterator ret = {};
1169*6dbdd20aSAndroid Build Coastguard Worker   uint32_t cached_instances =
1170*6dbdd20aSAndroid Build Coastguard Worker       perfetto::shlib::TracePointTraits::GetActiveInstances({cat})->load(
1171*6dbdd20aSAndroid Build Coastguard Worker           std::memory_order_relaxed);
1172*6dbdd20aSAndroid Build Coastguard Worker   if (!cached_instances) {
1173*6dbdd20aSAndroid Build Coastguard Worker     return ret;
1174*6dbdd20aSAndroid Build Coastguard Worker   }
1175*6dbdd20aSAndroid Build Coastguard Worker 
1176*6dbdd20aSAndroid Build Coastguard Worker   perfetto::internal::DataSourceType* ds =
1177*6dbdd20aSAndroid Build Coastguard Worker       perfetto::shlib::TrackEvent::GetType();
1178*6dbdd20aSAndroid Build Coastguard Worker 
1179*6dbdd20aSAndroid Build Coastguard Worker   perfetto::internal::DataSourceThreadLocalState*& tls_state =
1180*6dbdd20aSAndroid Build Coastguard Worker       *perfetto::shlib::TrackEvent::GetTlsState();
1181*6dbdd20aSAndroid Build Coastguard Worker 
1182*6dbdd20aSAndroid Build Coastguard Worker   if (!ds->TracePrologue<perfetto::shlib::TrackEventDataSourceTraits,
1183*6dbdd20aSAndroid Build Coastguard Worker                          perfetto::shlib::TracePointTraits>(
1184*6dbdd20aSAndroid Build Coastguard Worker           &tls_state, &cached_instances, {cat})) {
1185*6dbdd20aSAndroid Build Coastguard Worker     return ret;
1186*6dbdd20aSAndroid Build Coastguard Worker   }
1187*6dbdd20aSAndroid Build Coastguard Worker 
1188*6dbdd20aSAndroid Build Coastguard Worker   perfetto::internal::DataSourceType::InstancesIterator ii =
1189*6dbdd20aSAndroid Build Coastguard Worker       ds->BeginIteration<perfetto::shlib::TracePointTraits>(cached_instances,
1190*6dbdd20aSAndroid Build Coastguard Worker                                                             tls_state, {cat});
1191*6dbdd20aSAndroid Build Coastguard Worker 
1192*6dbdd20aSAndroid Build Coastguard Worker   ret.ds.inst_id = ii.i;
1193*6dbdd20aSAndroid Build Coastguard Worker   tls_state->root_tls->cached_instances = ii.cached_instances;
1194*6dbdd20aSAndroid Build Coastguard Worker   ret.ds.tracer = reinterpret_cast<struct PerfettoDsTracerImpl*>(ii.instance);
1195*6dbdd20aSAndroid Build Coastguard Worker   if (!ret.ds.tracer) {
1196*6dbdd20aSAndroid Build Coastguard Worker     ds->TraceEpilogue(tls_state);
1197*6dbdd20aSAndroid Build Coastguard Worker     return ret;
1198*6dbdd20aSAndroid Build Coastguard Worker   }
1199*6dbdd20aSAndroid Build Coastguard Worker 
1200*6dbdd20aSAndroid Build Coastguard Worker   FillIterator(&ii, ts, &ret);
1201*6dbdd20aSAndroid Build Coastguard Worker 
1202*6dbdd20aSAndroid Build Coastguard Worker   ret.ds.tls = reinterpret_cast<struct PerfettoDsTlsImpl*>(tls_state);
1203*6dbdd20aSAndroid Build Coastguard Worker   return ret;
1204*6dbdd20aSAndroid Build Coastguard Worker }
1205*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoTeLlImplNext(struct PerfettoTeCategoryImpl * cat,struct PerfettoTeTimestamp ts,struct PerfettoTeLlImplIterator * iterator)1206*6dbdd20aSAndroid Build Coastguard Worker void PerfettoTeLlImplNext(struct PerfettoTeCategoryImpl* cat,
1207*6dbdd20aSAndroid Build Coastguard Worker                           struct PerfettoTeTimestamp ts,
1208*6dbdd20aSAndroid Build Coastguard Worker                           struct PerfettoTeLlImplIterator* iterator) {
1209*6dbdd20aSAndroid Build Coastguard Worker   auto* tls = reinterpret_cast<perfetto::internal::DataSourceThreadLocalState*>(
1210*6dbdd20aSAndroid Build Coastguard Worker       iterator->ds.tls);
1211*6dbdd20aSAndroid Build Coastguard Worker 
1212*6dbdd20aSAndroid Build Coastguard Worker   perfetto::internal::DataSourceType::InstancesIterator ii;
1213*6dbdd20aSAndroid Build Coastguard Worker   ii.i = iterator->ds.inst_id;
1214*6dbdd20aSAndroid Build Coastguard Worker   ii.cached_instances = tls->root_tls->cached_instances;
1215*6dbdd20aSAndroid Build Coastguard Worker   ii.instance =
1216*6dbdd20aSAndroid Build Coastguard Worker       reinterpret_cast<perfetto::internal::DataSourceInstanceThreadLocalState*>(
1217*6dbdd20aSAndroid Build Coastguard Worker           iterator->ds.tracer);
1218*6dbdd20aSAndroid Build Coastguard Worker 
1219*6dbdd20aSAndroid Build Coastguard Worker   perfetto::internal::DataSourceType* ds =
1220*6dbdd20aSAndroid Build Coastguard Worker       perfetto::shlib::TrackEvent::GetType();
1221*6dbdd20aSAndroid Build Coastguard Worker 
1222*6dbdd20aSAndroid Build Coastguard Worker   ds->NextIteration</*Traits=*/perfetto::shlib::TracePointTraits>(&ii, tls,
1223*6dbdd20aSAndroid Build Coastguard Worker                                                                   {cat});
1224*6dbdd20aSAndroid Build Coastguard Worker 
1225*6dbdd20aSAndroid Build Coastguard Worker   iterator->ds.inst_id = ii.i;
1226*6dbdd20aSAndroid Build Coastguard Worker   tls->root_tls->cached_instances = ii.cached_instances;
1227*6dbdd20aSAndroid Build Coastguard Worker   iterator->ds.tracer =
1228*6dbdd20aSAndroid Build Coastguard Worker       reinterpret_cast<struct PerfettoDsTracerImpl*>(ii.instance);
1229*6dbdd20aSAndroid Build Coastguard Worker 
1230*6dbdd20aSAndroid Build Coastguard Worker   if (!iterator->ds.tracer) {
1231*6dbdd20aSAndroid Build Coastguard Worker     ds->TraceEpilogue(tls);
1232*6dbdd20aSAndroid Build Coastguard Worker     return;
1233*6dbdd20aSAndroid Build Coastguard Worker   }
1234*6dbdd20aSAndroid Build Coastguard Worker 
1235*6dbdd20aSAndroid Build Coastguard Worker   FillIterator(&ii, ts, iterator);
1236*6dbdd20aSAndroid Build Coastguard Worker }
1237*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoTeLlImplBreak(struct PerfettoTeCategoryImpl *,struct PerfettoTeLlImplIterator * iterator)1238*6dbdd20aSAndroid Build Coastguard Worker void PerfettoTeLlImplBreak(struct PerfettoTeCategoryImpl*,
1239*6dbdd20aSAndroid Build Coastguard Worker                            struct PerfettoTeLlImplIterator* iterator) {
1240*6dbdd20aSAndroid Build Coastguard Worker   auto* tls = reinterpret_cast<perfetto::internal::DataSourceThreadLocalState*>(
1241*6dbdd20aSAndroid Build Coastguard Worker       iterator->ds.tls);
1242*6dbdd20aSAndroid Build Coastguard Worker 
1243*6dbdd20aSAndroid Build Coastguard Worker   perfetto::internal::DataSourceType* ds =
1244*6dbdd20aSAndroid Build Coastguard Worker       perfetto::shlib::TrackEvent::GetType();
1245*6dbdd20aSAndroid Build Coastguard Worker 
1246*6dbdd20aSAndroid Build Coastguard Worker   ds->TraceEpilogue(tls);
1247*6dbdd20aSAndroid Build Coastguard Worker }
1248*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoTeLlImplDynCatEnabled(struct PerfettoDsTracerImpl * tracer,PerfettoDsInstanceIndex inst_id,const struct PerfettoTeCategoryDescriptor * dyn_cat)1249*6dbdd20aSAndroid Build Coastguard Worker bool PerfettoTeLlImplDynCatEnabled(
1250*6dbdd20aSAndroid Build Coastguard Worker     struct PerfettoDsTracerImpl* tracer,
1251*6dbdd20aSAndroid Build Coastguard Worker     PerfettoDsInstanceIndex inst_id,
1252*6dbdd20aSAndroid Build Coastguard Worker     const struct PerfettoTeCategoryDescriptor* dyn_cat) {
1253*6dbdd20aSAndroid Build Coastguard Worker   perfetto::internal::DataSourceType* ds =
1254*6dbdd20aSAndroid Build Coastguard Worker       perfetto::shlib::TrackEvent::GetType();
1255*6dbdd20aSAndroid Build Coastguard Worker 
1256*6dbdd20aSAndroid Build Coastguard Worker   auto* tls_inst =
1257*6dbdd20aSAndroid Build Coastguard Worker       reinterpret_cast<perfetto::internal::DataSourceInstanceThreadLocalState*>(
1258*6dbdd20aSAndroid Build Coastguard Worker           tracer);
1259*6dbdd20aSAndroid Build Coastguard Worker 
1260*6dbdd20aSAndroid Build Coastguard Worker   auto* incr_state = static_cast<perfetto::shlib::TrackEventIncrementalState*>(
1261*6dbdd20aSAndroid Build Coastguard Worker       ds->GetIncrementalState(tls_inst, inst_id));
1262*6dbdd20aSAndroid Build Coastguard Worker 
1263*6dbdd20aSAndroid Build Coastguard Worker   return IsDynamicCategoryEnabled(inst_id, incr_state, *dyn_cat);
1264*6dbdd20aSAndroid Build Coastguard Worker }
1265*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoTeLlImplTrackSeen(struct PerfettoTeLlImplIncr * incr,uint64_t uuid)1266*6dbdd20aSAndroid Build Coastguard Worker bool PerfettoTeLlImplTrackSeen(struct PerfettoTeLlImplIncr* incr,
1267*6dbdd20aSAndroid Build Coastguard Worker                                uint64_t uuid) {
1268*6dbdd20aSAndroid Build Coastguard Worker   auto* incr_state =
1269*6dbdd20aSAndroid Build Coastguard Worker       reinterpret_cast<perfetto::shlib::TrackEventIncrementalState*>(incr);
1270*6dbdd20aSAndroid Build Coastguard Worker 
1271*6dbdd20aSAndroid Build Coastguard Worker   return !incr_state->seen_track_uuids.insert(uuid).second;
1272*6dbdd20aSAndroid Build Coastguard Worker }
1273*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoTeLlImplIntern(struct PerfettoTeLlImplIncr * incr,int32_t type,const void * data,size_t data_size,bool * seen)1274*6dbdd20aSAndroid Build Coastguard Worker uint64_t PerfettoTeLlImplIntern(struct PerfettoTeLlImplIncr* incr,
1275*6dbdd20aSAndroid Build Coastguard Worker                                 int32_t type,
1276*6dbdd20aSAndroid Build Coastguard Worker                                 const void* data,
1277*6dbdd20aSAndroid Build Coastguard Worker                                 size_t data_size,
1278*6dbdd20aSAndroid Build Coastguard Worker                                 bool* seen) {
1279*6dbdd20aSAndroid Build Coastguard Worker   auto* incr_state =
1280*6dbdd20aSAndroid Build Coastguard Worker       reinterpret_cast<perfetto::shlib::TrackEventIncrementalState*>(incr);
1281*6dbdd20aSAndroid Build Coastguard Worker 
1282*6dbdd20aSAndroid Build Coastguard Worker   auto res = incr_state->iids.FindOrAssign(type, data, data_size);
1283*6dbdd20aSAndroid Build Coastguard Worker   *seen = !res.newly_assigned;
1284*6dbdd20aSAndroid Build Coastguard Worker   return res.iid;
1285*6dbdd20aSAndroid Build Coastguard Worker }
1286