• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "src/trace_processor/importers/common/track_tracker.h"
18 
19 #include "src/trace_processor/importers/common/args_tracker.h"
20 #include "src/trace_processor/importers/common/process_tracker.h"
21 
22 namespace perfetto {
23 namespace trace_processor {
24 
TrackTracker(TraceProcessorContext * context)25 TrackTracker::TrackTracker(TraceProcessorContext* context)
26     : source_key_(context->storage->InternString("source")),
27       source_id_key_(context->storage->InternString("source_id")),
28       source_id_is_process_scoped_key_(
29           context->storage->InternString("source_id_is_process_scoped")),
30       source_scope_key_(context->storage->InternString("source_scope")),
31       category_key_(context->storage->InternString("category")),
32       fuchsia_source_(context->storage->InternString("fuchsia")),
33       chrome_source_(context->storage->InternString("chrome")),
34       context_(context) {}
35 
InternThreadTrack(UniqueTid utid)36 TrackId TrackTracker::InternThreadTrack(UniqueTid utid) {
37   auto it = thread_tracks_.find(utid);
38   if (it != thread_tracks_.end())
39     return it->second;
40 
41   tables::ThreadTrackTable::Row row;
42   row.utid = utid;
43   auto id = context_->storage->mutable_thread_track_table()->Insert(row).id;
44   thread_tracks_[utid] = id;
45   return id;
46 }
47 
InternProcessTrack(UniquePid upid)48 TrackId TrackTracker::InternProcessTrack(UniquePid upid) {
49   auto it = process_tracks_.find(upid);
50   if (it != process_tracks_.end())
51     return it->second;
52 
53   tables::ProcessTrackTable::Row row;
54   row.upid = upid;
55   auto id = context_->storage->mutable_process_track_table()->Insert(row).id;
56   process_tracks_[upid] = id;
57   return id;
58 }
59 
InternFuchsiaAsyncTrack(StringId name,uint32_t upid,int64_t correlation_id)60 TrackId TrackTracker::InternFuchsiaAsyncTrack(StringId name,
61                                               uint32_t upid,
62                                               int64_t correlation_id) {
63   return InternLegacyChromeAsyncTrack(name, upid, correlation_id, false,
64                                       StringId());
65 }
66 
InternCpuTrack(StringId name,uint32_t cpu)67 TrackId TrackTracker::InternCpuTrack(StringId name, uint32_t cpu) {
68   auto it = cpu_tracks_.find(std::make_pair(name, cpu));
69   if (it != cpu_tracks_.end()) {
70     return it->second;
71   }
72 
73   tables::TrackTable::Row row(name);
74   auto id = context_->storage->mutable_track_table()->Insert(row).id;
75   cpu_tracks_[std::make_pair(name, cpu)] = id;
76 
77   return id;
78 }
79 
InternGpuTrack(const tables::GpuTrackTable::Row & row)80 TrackId TrackTracker::InternGpuTrack(const tables::GpuTrackTable::Row& row) {
81   GpuTrackTuple tuple{row.name, row.scope, row.context_id.value_or(0)};
82 
83   auto it = gpu_tracks_.find(tuple);
84   if (it != gpu_tracks_.end())
85     return it->second;
86 
87   auto id = context_->storage->mutable_gpu_track_table()->Insert(row).id;
88   gpu_tracks_[tuple] = id;
89   return id;
90 }
91 
InternLegacyChromeAsyncTrack(StringId name,uint32_t upid,int64_t source_id,bool source_id_is_process_scoped,StringId source_scope)92 TrackId TrackTracker::InternLegacyChromeAsyncTrack(
93     StringId name,
94     uint32_t upid,
95     int64_t source_id,
96     bool source_id_is_process_scoped,
97     StringId source_scope) {
98   ChromeTrackTuple tuple;
99   if (source_id_is_process_scoped)
100     tuple.upid = upid;
101   tuple.source_id = source_id;
102   tuple.source_scope = source_scope;
103 
104   auto it = chrome_tracks_.find(tuple);
105   if (it != chrome_tracks_.end()) {
106     if (name != kNullStringId) {
107       // The track may have been created for an end event without name. In that
108       // case, update it with this event's name.
109       auto* tracks = context_->storage->mutable_track_table();
110       uint32_t track_row = *tracks->id().IndexOf(it->second);
111       if (tracks->name()[track_row] == kNullStringId)
112         tracks->mutable_name()->Set(track_row, name);
113     }
114     return it->second;
115   }
116 
117   // Legacy async tracks are always drawn in the context of a process, even if
118   // the ID's scope is global.
119   tables::ProcessTrackTable::Row track(name);
120   track.upid = upid;
121   TrackId id =
122       context_->storage->mutable_process_track_table()->Insert(track).id;
123   chrome_tracks_[tuple] = id;
124 
125   context_->args_tracker->AddArgsTo(id)
126       .AddArg(source_key_, Variadic::String(chrome_source_))
127       .AddArg(source_id_key_, Variadic::Integer(source_id))
128       .AddArg(source_id_is_process_scoped_key_,
129               Variadic::Boolean(source_id_is_process_scoped))
130       .AddArg(source_scope_key_, Variadic::String(source_scope));
131 
132   return id;
133 }
134 
CreateGlobalAsyncTrack(StringId name,StringId source)135 TrackId TrackTracker::CreateGlobalAsyncTrack(StringId name, StringId source) {
136   tables::TrackTable::Row row(name);
137   auto id = context_->storage->mutable_track_table()->Insert(row).id;
138   if (!source.is_null()) {
139     context_->args_tracker->AddArgsTo(id).AddArg(source_key_,
140                                                  Variadic::String(source));
141   }
142   return id;
143 }
144 
CreateProcessAsyncTrack(StringId name,UniquePid upid,StringId source)145 TrackId TrackTracker::CreateProcessAsyncTrack(StringId name,
146                                               UniquePid upid,
147                                               StringId source) {
148   tables::ProcessTrackTable::Row row(name);
149   row.upid = upid;
150   auto id = context_->storage->mutable_process_track_table()->Insert(row).id;
151   if (!source.is_null()) {
152     context_->args_tracker->AddArgsTo(id).AddArg(source_key_,
153                                                  Variadic::String(source));
154   }
155   return id;
156 }
157 
InternLegacyChromeProcessInstantTrack(UniquePid upid)158 TrackId TrackTracker::InternLegacyChromeProcessInstantTrack(UniquePid upid) {
159   auto it = chrome_process_instant_tracks_.find(upid);
160   if (it != chrome_process_instant_tracks_.end())
161     return it->second;
162 
163   tables::ProcessTrackTable::Row row;
164   row.upid = upid;
165   auto id = context_->storage->mutable_process_track_table()->Insert(row).id;
166   chrome_process_instant_tracks_[upid] = id;
167 
168   context_->args_tracker->AddArgsTo(id).AddArg(
169       source_key_, Variadic::String(chrome_source_));
170 
171   return id;
172 }
173 
GetOrCreateLegacyChromeGlobalInstantTrack()174 TrackId TrackTracker::GetOrCreateLegacyChromeGlobalInstantTrack() {
175   if (!chrome_global_instant_track_id_) {
176     chrome_global_instant_track_id_ =
177         context_->storage->mutable_track_table()->Insert({}).id;
178 
179     context_->args_tracker->AddArgsTo(*chrome_global_instant_track_id_)
180         .AddArg(source_key_, Variadic::String(chrome_source_));
181   }
182   return *chrome_global_instant_track_id_;
183 }
184 
GetOrCreateTriggerTrack()185 TrackId TrackTracker::GetOrCreateTriggerTrack() {
186   if (trigger_track_id_) {
187     return *trigger_track_id_;
188   }
189   tables::TrackTable::Row row;
190   row.name = context_->storage->InternString("Trace Triggers");
191   trigger_track_id_ = context_->storage->mutable_track_table()->Insert(row).id;
192   return *trigger_track_id_;
193 }
194 
InternGlobalCounterTrack(StringId name,StringId unit,StringId description)195 TrackId TrackTracker::InternGlobalCounterTrack(StringId name,
196                                                StringId unit,
197                                                StringId description) {
198   auto it = global_counter_tracks_by_name_.find(name);
199   if (it != global_counter_tracks_by_name_.end()) {
200     return it->second;
201   }
202 
203   tables::CounterTrackTable::Row row(name);
204   row.unit = unit;
205   row.description = description;
206   TrackId track =
207       context_->storage->mutable_counter_track_table()->Insert(row).id;
208   global_counter_tracks_by_name_[name] = track;
209   return track;
210 }
211 
InternCpuCounterTrack(StringId name,uint32_t cpu)212 TrackId TrackTracker::InternCpuCounterTrack(StringId name, uint32_t cpu) {
213   auto it = cpu_counter_tracks_.find(std::make_pair(name, cpu));
214   if (it != cpu_counter_tracks_.end()) {
215     return it->second;
216   }
217 
218   tables::CpuCounterTrackTable::Row row(name);
219   row.cpu = cpu;
220 
221   TrackId track =
222       context_->storage->mutable_cpu_counter_track_table()->Insert(row).id;
223   cpu_counter_tracks_[std::make_pair(name, cpu)] = track;
224   return track;
225 }
226 
InternThreadCounterTrack(StringId name,UniqueTid utid)227 TrackId TrackTracker::InternThreadCounterTrack(StringId name, UniqueTid utid) {
228   auto it = utid_counter_tracks_.find(std::make_pair(name, utid));
229   if (it != utid_counter_tracks_.end()) {
230     return it->second;
231   }
232 
233   tables::ThreadCounterTrackTable::Row row(name);
234   row.utid = utid;
235 
236   TrackId track =
237       context_->storage->mutable_thread_counter_track_table()->Insert(row).id;
238   utid_counter_tracks_[std::make_pair(name, utid)] = track;
239   return track;
240 }
241 
InternProcessCounterTrack(StringId name,UniquePid upid,StringId unit,StringId description)242 TrackId TrackTracker::InternProcessCounterTrack(StringId name,
243                                                 UniquePid upid,
244                                                 StringId unit,
245                                                 StringId description) {
246   auto it = upid_counter_tracks_.find(std::make_pair(name, upid));
247   if (it != upid_counter_tracks_.end()) {
248     return it->second;
249   }
250 
251   tables::ProcessCounterTrackTable::Row row(name);
252   row.upid = upid;
253   row.unit = unit;
254   row.description = description;
255 
256   TrackId track =
257       context_->storage->mutable_process_counter_track_table()->Insert(row).id;
258   upid_counter_tracks_[std::make_pair(name, upid)] = track;
259   return track;
260 }
261 
InternIrqCounterTrack(StringId name,int32_t irq)262 TrackId TrackTracker::InternIrqCounterTrack(StringId name, int32_t irq) {
263   auto it = irq_counter_tracks_.find(std::make_pair(name, irq));
264   if (it != irq_counter_tracks_.end()) {
265     return it->second;
266   }
267 
268   tables::IrqCounterTrackTable::Row row(name);
269   row.irq = irq;
270 
271   TrackId track =
272       context_->storage->mutable_irq_counter_track_table()->Insert(row).id;
273   irq_counter_tracks_[std::make_pair(name, irq)] = track;
274   return track;
275 }
276 
InternSoftirqCounterTrack(StringId name,int32_t softirq)277 TrackId TrackTracker::InternSoftirqCounterTrack(StringId name,
278                                                 int32_t softirq) {
279   auto it = softirq_counter_tracks_.find(std::make_pair(name, softirq));
280   if (it != softirq_counter_tracks_.end()) {
281     return it->second;
282   }
283 
284   tables::SoftirqCounterTrackTable::Row row(name);
285   row.softirq = softirq;
286 
287   TrackId track =
288       context_->storage->mutable_softirq_counter_track_table()->Insert(row).id;
289   softirq_counter_tracks_[std::make_pair(name, softirq)] = track;
290   return track;
291 }
292 
InternGpuCounterTrack(StringId name,uint32_t gpu_id)293 TrackId TrackTracker::InternGpuCounterTrack(StringId name, uint32_t gpu_id) {
294   auto it = gpu_counter_tracks_.find(std::make_pair(name, gpu_id));
295   if (it != gpu_counter_tracks_.end()) {
296     return it->second;
297   }
298   TrackId track = CreateGpuCounterTrack(name, gpu_id);
299   gpu_counter_tracks_[std::make_pair(name, gpu_id)] = track;
300   return track;
301 }
302 
CreateGpuCounterTrack(StringId name,uint32_t gpu_id,StringId description,StringId unit)303 TrackId TrackTracker::CreateGpuCounterTrack(StringId name,
304                                             uint32_t gpu_id,
305                                             StringId description,
306                                             StringId unit) {
307   tables::GpuCounterTrackTable::Row row(name);
308   row.gpu_id = gpu_id;
309   row.description = description;
310   row.unit = unit;
311 
312   return context_->storage->mutable_gpu_counter_track_table()->Insert(row).id;
313 }
314 
CreatePerfCounterTrack(StringId name,uint32_t perf_session_id,uint32_t cpu,bool is_timebase)315 TrackId TrackTracker::CreatePerfCounterTrack(StringId name,
316                                              uint32_t perf_session_id,
317                                              uint32_t cpu,
318                                              bool is_timebase) {
319   tables::PerfCounterTrackTable::Row row(name);
320   row.perf_session_id = perf_session_id;
321   row.cpu = cpu;
322   row.is_timebase = is_timebase;
323   return context_->storage->mutable_perf_counter_track_table()->Insert(row).id;
324 }
325 
326 }  // namespace trace_processor
327 }  // namespace perfetto
328