• 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 #ifndef SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_TRACK_TRACKER_H_
18 #define SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_TRACK_TRACKER_H_
19 
20 #include <optional>
21 
22 #include "src/trace_processor/importers/common/args_tracker.h"
23 #include "src/trace_processor/storage/trace_storage.h"
24 #include "src/trace_processor/tables/profiler_tables_py.h"
25 #include "src/trace_processor/types/trace_processor_context.h"
26 
27 namespace perfetto {
28 namespace trace_processor {
29 
30 // Tracks and stores tracks based on track types, ids and scopes.
31 class TrackTracker {
32  public:
33   // Enum which groups global tracks to avoid an explosion of tracks at the top
34   // level.
35   // Try and keep members of this enum high level as every entry here
36   // corresponds to ~1 extra UI track.
37   enum class Group : uint32_t {
38     kMemory = 0,
39     kIo,
40     kVirtio,
41     kNetwork,
42     kPower,
43     kDeviceState,
44     kThermals,
45     kClockFrequency,
46     kBatteryMitigation,
47 
48     // Keep this last.
49     kSizeSentinel,
50   };
51   using SetArgsCallback = std::function<void(ArgsTracker::BoundInserter&)>;
52 
53   explicit TrackTracker(TraceProcessorContext*);
54 
55   // Interns a thread track into the storage.
56   TrackId InternThreadTrack(UniqueTid utid);
57 
58   // Interns a process track into the storage.
59   TrackId InternProcessTrack(UniquePid upid);
60 
61   // Interns a Fuchsia async track into the storage.
62   TrackId InternFuchsiaAsyncTrack(StringId name,
63                                   uint32_t upid,
64                                   int64_t correlation_id);
65 
66   // Interns a global track keyed by CPU + name into the storage.
67   TrackId InternCpuTrack(StringId name, uint32_t cpu);
68 
69   // Interns a given GPU track into the storage.
70   TrackId InternGpuTrack(const tables::GpuTrackTable::Row& row);
71 
72   // Interns a GPU work period track into the storage.
73   TrackId InternGpuWorkPeriodTrack(
74       const tables::GpuWorkPeriodTrackTable::Row& row);
75 
76   // Interns a legacy Chrome async event track into the storage.
77   TrackId InternLegacyChromeAsyncTrack(StringId name,
78                                        uint32_t upid,
79                                        int64_t trace_id,
80                                        bool trace_id_is_process_scoped,
81                                        StringId source_scope);
82 
83   // Interns a track for legacy Chrome process-scoped instant events into the
84   // storage.
85   TrackId InternLegacyChromeProcessInstantTrack(UniquePid upid);
86 
87   // Lazily creates the track for legacy Chrome global instant events.
88   TrackId GetOrCreateLegacyChromeGlobalInstantTrack();
89 
90   // Returns the ID of the implicit trace-global default track for triggers
91   // received by the service.
92   TrackId GetOrCreateTriggerTrack();
93 
94   // Returns the ID of the track for Google Interconnect events
95   TrackId GetOrCreateInterconnectTrack();
96 
97   // Interns a global counter track into the storage.
98   TrackId InternGlobalCounterTrack(Group group,
99                                    StringId name,
100                                    SetArgsCallback = {},
101                                    StringId unit = kNullStringId,
102                                    StringId description = kNullStringId);
103 
104   // Interns a counter track associated with a cpu into the storage.
105   TrackId InternCpuCounterTrack(StringId name, uint32_t cpu);
106 
107   // Interns a counter track associated with a thread into the storage.
108   TrackId InternThreadCounterTrack(StringId name, UniqueTid utid);
109 
110   // Interns a counter track associated with a process into the storage.
111   TrackId InternProcessCounterTrack(StringId name,
112                                     UniquePid upid,
113                                     StringId unit = kNullStringId,
114                                     StringId description = kNullStringId);
115 
116   // Interns a counter track associated with an irq into the storage.
117   TrackId InternIrqCounterTrack(StringId name, int32_t irq);
118 
119   // Interns a counter track associated with an softirq into the storage.
120   TrackId InternSoftirqCounterTrack(StringId name, int32_t softirq);
121 
122   // Interns a counter track associated with a GPU into the storage.
123   TrackId InternGpuCounterTrack(StringId name, uint32_t gpu_id);
124 
125   // Interns energy counter track associated with a
126   // Energy breakdown into the storage.
127   TrackId InternEnergyCounterTrack(StringId name,
128                                    int32_t consumer_id,
129                                    StringId consumer_type,
130                                    int32_t ordinal);
131 
132   // Interns a per process energy consumer counter track associated with a
133   // Energy Uid into the storage.
134   TrackId InternEnergyPerUidCounterTrack(StringId name,
135                                          int32_t consumer_id,
136                                          int32_t uid);
137 
138   // Interns a track associated with a Linux device (where a Linux device
139   // implies a kernel-level device managed by a Linux driver).
140   TrackId InternLinuxDeviceTrack(StringId name);
141 
142   // Creates a counter track associated with a GPU into the storage.
143   TrackId CreateGpuCounterTrack(StringId name,
144                                 uint32_t gpu_id,
145                                 StringId description = StringId::Null(),
146                                 StringId unit = StringId::Null());
147 
148   // Creates a counter track for values within perf samples.
149   // The tracks themselves are managed by PerfSampleTracker.
150   TrackId CreatePerfCounterTrack(StringId name,
151                                  tables::PerfSessionTable::Id perf_session_id,
152                                  uint32_t cpu,
153                                  bool is_timebase);
154 
155   // NOTE:
156   // The below method should only be called by AsyncTrackSetTracker
157 
158   // Creates and inserts a global async track into the storage.
159   TrackId CreateGlobalAsyncTrack(StringId name, StringId source);
160 
161   // Creates and inserts a Android async track into the storage.
162   TrackId CreateProcessAsyncTrack(StringId name,
163                                   UniquePid upid,
164                                   StringId source);
165 
166  private:
167   struct GpuTrackTuple {
168     StringId track_name;
169     StringId scope;
170     int64_t context_id;
171 
172     friend bool operator<(const GpuTrackTuple& l, const GpuTrackTuple& r) {
173       return std::tie(l.track_name, l.scope, l.context_id) <
174              std::tie(r.track_name, r.scope, r.context_id);
175     }
176   };
177   struct GpuWorkPeriodTrackTuple {
178     StringId track_name;
179     uint32_t gpu_id;
180     int32_t uid;
181 
182     friend bool operator<(const GpuWorkPeriodTrackTuple& l,
183                           const GpuWorkPeriodTrackTuple& r) {
184       return std::tie(l.track_name, l.gpu_id, l.uid) <
185              std::tie(r.track_name, r.gpu_id, r.uid);
186     }
187   };
188   struct ChromeTrackTuple {
189     std::optional<int64_t> upid;
190     int64_t trace_id = 0;
191     StringId source_scope = StringId::Null();
192 
193     friend bool operator<(const ChromeTrackTuple& l,
194                           const ChromeTrackTuple& r) {
195       return std::tie(l.trace_id, l.upid, l.source_scope) <
196              std::tie(r.trace_id, r.upid, r.source_scope);
197     }
198   };
199   static constexpr size_t kGroupCount =
200       static_cast<uint32_t>(Group::kSizeSentinel);
201 
202   TrackId InternTrackForGroup(Group group);
203 
204   std::array<std::optional<TrackId>, kGroupCount> group_track_ids_;
205 
206   std::map<UniqueTid, TrackId> thread_tracks_;
207   std::map<UniquePid, TrackId> process_tracks_;
208   std::map<int64_t /* correlation_id */, TrackId> fuchsia_async_tracks_;
209 
210   std::map<std::pair<StringId, uint32_t /* cpu */>, TrackId> cpu_tracks_;
211 
212   std::map<GpuTrackTuple, TrackId> gpu_tracks_;
213   std::map<ChromeTrackTuple, TrackId> chrome_tracks_;
214   std::map<UniquePid, TrackId> chrome_process_instant_tracks_;
215   std::map<std::pair<StringId, int32_t /*uid*/>, TrackId> uid_tracks_;
216   std::map<GpuWorkPeriodTrackTuple, TrackId> gpu_work_period_tracks_;
217 
218   std::map<StringId, TrackId> global_counter_tracks_by_name_;
219   std::map<std::pair<StringId, uint32_t>, TrackId> cpu_counter_tracks_;
220   std::map<std::pair<StringId, UniqueTid>, TrackId> utid_counter_tracks_;
221   std::map<std::pair<StringId, UniquePid>, TrackId> upid_counter_tracks_;
222   std::map<std::pair<StringId, int32_t>, TrackId> irq_counter_tracks_;
223   std::map<std::pair<StringId, int32_t>, TrackId> softirq_counter_tracks_;
224   std::map<std::pair<StringId, uint32_t>, TrackId> gpu_counter_tracks_;
225   std::map<std::pair<StringId, int32_t>, TrackId> energy_counter_tracks_;
226   std::map<std::pair<StringId, int32_t>, TrackId> uid_counter_tracks_;
227   std::map<std::pair<StringId, int32_t>, TrackId>
228       energy_per_uid_counter_tracks_;
229   std::map<StringId, TrackId> linux_device_tracks_;
230 
231   std::optional<TrackId> chrome_global_instant_track_id_;
232   std::optional<TrackId> trigger_track_id_;
233   std::optional<TrackId> interconnect_events_track_id_;
234 
235   const StringId source_key_ = kNullStringId;
236   const StringId trace_id_key_ = kNullStringId;
237   const StringId trace_id_is_process_scoped_key_ = kNullStringId;
238   const StringId source_scope_key_ = kNullStringId;
239   const StringId category_key_ = kNullStringId;
240 
241   const StringId fuchsia_source_ = kNullStringId;
242   const StringId chrome_source_ = kNullStringId;
243 
244   TraceProcessorContext* const context_;
245 };
246 
247 }  // namespace trace_processor
248 }  // namespace perfetto
249 
250 #endif  // SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_TRACK_TRACKER_H_
251