• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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/event_tracker.h"
18 
19 #include <cstdint>
20 #include <optional>
21 
22 #include "perfetto/base/compiler.h"
23 #include "src/trace_processor/importers/common/args_tracker.h"
24 #include "src/trace_processor/importers/common/track_tracker.h"
25 #include "src/trace_processor/importers/common/tracks.h"
26 #include "src/trace_processor/importers/common/tracks_common.h"
27 #include "src/trace_processor/storage/trace_storage.h"
28 #include "src/trace_processor/types/trace_processor_context.h"
29 
30 namespace perfetto::trace_processor {
31 
EventTracker(TraceProcessorContext * context)32 EventTracker::EventTracker(TraceProcessorContext* context)
33     : context_(context) {}
34 
35 EventTracker::~EventTracker() = default;
36 
PushProcessCounterForThread(ProcessCounterForThread pcounter,int64_t timestamp,double value,UniqueTid utid)37 void EventTracker::PushProcessCounterForThread(ProcessCounterForThread pcounter,
38                                                int64_t timestamp,
39                                                double value,
40                                                UniqueTid utid) {
41   const auto& counter = context_->storage->counter_table();
42   auto opt_id = PushCounter(timestamp, value, kInvalidTrackId);
43   if (opt_id) {
44     PendingUpidResolutionCounter pending;
45     pending.row = counter.FindById(*opt_id)->ToRowNumber().row_number();
46     pending.utid = utid;
47     pending.counter = pcounter;
48     pending_upid_resolution_counter_.emplace_back(pending);
49   }
50 }
51 
PushCounter(int64_t timestamp,double value,TrackId track_id)52 std::optional<CounterId> EventTracker::PushCounter(int64_t timestamp,
53                                                    double value,
54                                                    TrackId track_id) {
55   auto* counters = context_->storage->mutable_counter_table();
56   return counters->Insert({timestamp, track_id, value, {}}).id;
57 }
58 
PushCounter(int64_t timestamp,double value,TrackId track_id,const SetArgsCallback & args_callback)59 std::optional<CounterId> EventTracker::PushCounter(
60     int64_t timestamp,
61     double value,
62     TrackId track_id,
63     const SetArgsCallback& args_callback) {
64   auto maybe_counter_id = PushCounter(timestamp, value, track_id);
65   if (maybe_counter_id) {
66     auto inserter = context_->args_tracker->AddArgsTo(*maybe_counter_id);
67     args_callback(&inserter);
68   }
69   return maybe_counter_id;
70 }
71 
FlushPendingEvents()72 void EventTracker::FlushPendingEvents() {
73   const auto& thread_table = context_->storage->thread_table();
74   for (const auto& pending_counter : pending_upid_resolution_counter_) {
75     UniqueTid utid = pending_counter.utid;
76     std::optional<UniquePid> upid = thread_table[utid].upid();
77 
78     // If we still don't know which process this thread belongs to, fall back
79     // onto creating a thread counter track. It's too late to drop data
80     // because the counter values have already been inserted.
81     TrackId track_id;
82     switch (pending_counter.counter.index()) {
83       case base::variant_index<ProcessCounterForThread, OomScoreAdj>():
84         if (upid.has_value()) {
85           track_id = context_->track_tracker->InternTrack(
86               tracks::kOomScoreAdjBlueprint, tracks::Dimensions(*upid));
87         } else {
88           track_id = context_->track_tracker->InternTrack(
89               tracks::kOomScoreAdjThreadFallbackBlueprint,
90               tracks::Dimensions(utid));
91         }
92         break;
93       case base::variant_index<ProcessCounterForThread, MmEvent>(): {
94         const auto& mm_event = std::get<MmEvent>(pending_counter.counter);
95         if (upid.has_value()) {
96           track_id = context_->track_tracker->InternTrack(
97               tracks::kMmEventBlueprint,
98               tracks::Dimensions(*upid, mm_event.type, mm_event.metric));
99         } else {
100           track_id = context_->track_tracker->InternTrack(
101               tracks::kMmEventThreadFallbackBlueprint,
102               tracks::Dimensions(utid, mm_event.type, mm_event.metric));
103         }
104         break;
105       }
106       case base::variant_index<ProcessCounterForThread, RssStat>(): {
107         const auto& rss_stat = std::get<RssStat>(pending_counter.counter);
108         if (upid.has_value()) {
109           track_id = context_->track_tracker->InternTrack(
110               tracks::kProcessMemoryBlueprint,
111               tracks::Dimensions(*upid, rss_stat.process_memory_key));
112         } else {
113           track_id = context_->track_tracker->InternTrack(
114               tracks::kProcessMemoryThreadFallbackBlueprint,
115               tracks::Dimensions(utid, rss_stat.process_memory_key));
116         }
117         break;
118       }
119       case base::variant_index<ProcessCounterForThread, JsonCounter>(): {
120         const auto& json = std::get<JsonCounter>(pending_counter.counter);
121         if (upid.has_value()) {
122           track_id = context_->track_tracker->InternTrack(
123               tracks::kJsonCounterBlueprint,
124               tracks::Dimensions(
125                   *upid, context_->storage->GetString(json.counter_name_id)),
126               tracks::DynamicName(json.counter_name_id));
127         } else {
128           track_id = context_->track_tracker->InternTrack(
129               tracks::kJsonCounterThreadFallbackBlueprint,
130               tracks::Dimensions(
131                   utid, context_->storage->GetString(json.counter_name_id)),
132               tracks::DynamicName(json.counter_name_id));
133         }
134         break;
135       }
136     }
137     auto& counter = *context_->storage->mutable_counter_table();
138     counter[pending_counter.row].set_track_id(track_id);
139   }
140   pending_upid_resolution_counter_.clear();
141 }
142 
143 }  // namespace perfetto::trace_processor
144