blob: 0d46b3564fbbe59c7dbdcad9af0a67c401fa49ba [file] [log] [blame]
Lalit Maganti93b76362018-06-01 03:03:58 +01001/*
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
Primiano Tucci0d72a312018-08-07 14:42:45 +010017#include "src/trace_processor/proto_trace_parser.h"
Lalit Maganti93b76362018-06-01 03:03:58 +010018
Primiano Tucci132a34d2018-09-19 19:34:01 +010019#include <string.h>
20
Lalit Magantidf3e9262018-06-04 17:45:00 +010021#include <string>
22
Primiano Tuccid933d912018-09-04 09:15:07 +010023#include "perfetto/base/logging.h"
Primiano Tucci2da5d2e2018-08-10 14:23:31 +010024#include "perfetto/base/string_view.h"
Lalit Maganti93b76362018-06-01 03:03:58 +010025#include "perfetto/base/utils.h"
Primiano Tucci0d72a312018-08-07 14:42:45 +010026#include "perfetto/protozero/proto_decoder.h"
Isabelle Taylor54ce7052018-10-01 14:00:15 +010027#include "perfetto/traced/sys_stats_counters.h"
Isabelle Taylora97c5f52018-10-23 17:36:12 +010028#include "src/trace_processor/event_tracker.h"
Primiano Tucci0d72a312018-08-07 14:42:45 +010029#include "src/trace_processor/process_tracker.h"
Hector Dearman947f12a2018-09-11 16:50:36 +010030#include "src/trace_processor/slice_tracker.h"
Primiano Tucci0d72a312018-08-07 14:42:45 +010031#include "src/trace_processor/trace_processor_context.h"
32
Lalit Magantidf3e9262018-06-04 17:45:00 +010033#include "perfetto/trace/trace.pb.h"
34#include "perfetto/trace/trace_packet.pb.h"
Lalit Maganti93b76362018-06-01 03:03:58 +010035
36namespace perfetto {
37namespace trace_processor {
38
Hector Dearman947f12a2018-09-11 16:50:36 +010039// We have to handle trace_marker events of a few different types:
40// 1. some random text
41// 2. B|1636|pokeUserActivity
42// 3. E|1636
43// 4. C|1636|wq:monitor|0
44bool ParseSystraceTracePoint(base::StringView str, SystraceTracePoint* out) {
45 // THIS char* IS NOT NULL TERMINATED.
46 const char* s = str.data();
47 size_t len = str.size();
48
Hector Dearman9e6ddd82018-09-21 10:17:02 +010049 // If str matches '[BEC]\|[0-9]+[\|\n]' set tid_length to the length of
Hector Dearman947f12a2018-09-11 16:50:36 +010050 // the number. Otherwise return false.
Lalit Magantide6267f2018-11-08 12:35:34 +000051 if (s[1] != '|' && s[1] != '\n')
Hector Dearman947f12a2018-09-11 16:50:36 +010052 return false;
53 if (s[0] != 'B' && s[0] != 'E' && s[0] != 'C')
54 return false;
Lalit Magantide6267f2018-11-08 12:35:34 +000055 size_t tid_length = 0;
56 for (size_t i = 2; i < len; i++) {
Hector Dearman947f12a2018-09-11 16:50:36 +010057 if (s[i] == '|' || s[i] == '\n') {
Hector Dearman9e6ddd82018-09-21 10:17:02 +010058 tid_length = i - 2;
Hector Dearman947f12a2018-09-11 16:50:36 +010059 break;
60 }
61 if (s[i] < '0' || s[i] > '9')
62 return false;
63 }
64
Lalit Magantide6267f2018-11-08 12:35:34 +000065 if (tid_length == 0) {
66 out->tid = 0;
67 } else {
68 std::string tid_str(s + 2, tid_length);
69 out->tid = static_cast<uint32_t>(std::stoi(tid_str.c_str()));
70 }
Hector Dearman947f12a2018-09-11 16:50:36 +010071
72 out->phase = s[0];
73 switch (s[0]) {
74 case 'B': {
Hector Dearman9e6ddd82018-09-21 10:17:02 +010075 size_t name_index = 2 + tid_length + 1;
Hector Dearman947f12a2018-09-11 16:50:36 +010076 out->name = base::StringView(s + name_index, len - name_index);
77 return true;
78 }
Isabelle Taylor31e04402018-09-19 12:13:25 +010079 case 'E': {
Hector Dearman947f12a2018-09-11 16:50:36 +010080 return true;
Isabelle Taylor31e04402018-09-19 12:13:25 +010081 }
82 case 'C': {
Hector Dearman9e6ddd82018-09-21 10:17:02 +010083 size_t name_index = 2 + tid_length + 1;
Isabelle Taylor31e04402018-09-19 12:13:25 +010084 size_t name_length = 0;
85 for (size_t i = name_index; i < len; i++) {
86 if (s[i] == '|' || s[i] == '\n') {
87 name_length = i - name_index;
88 break;
89 }
90 }
91 out->name = base::StringView(s + name_index, name_length);
92 size_t value_index = name_index + name_length + 1;
93 char value_str[32];
Primiano Tucci132a34d2018-09-19 19:34:01 +010094 strcpy(value_str, s + value_index);
Isabelle Taylor31e04402018-09-19 12:13:25 +010095 out->value = std::stod(value_str);
Hector Dearman947f12a2018-09-11 16:50:36 +010096 return true;
Isabelle Taylor31e04402018-09-19 12:13:25 +010097 }
Hector Dearman947f12a2018-09-11 16:50:36 +010098 default:
99 return false;
100 }
101}
102
Lalit Magantidf3e9262018-06-04 17:45:00 +0100103using protozero::ProtoDecoder;
104using protozero::proto_utils::kFieldTypeLengthDelimited;
Lalit Magantidf3e9262018-06-04 17:45:00 +0100105
Primiano Tucci7e330292018-08-24 19:10:52 +0200106ProtoTraceParser::ProtoTraceParser(TraceProcessorContext* context)
Isabelle Taylor15314ea2018-09-19 11:35:19 +0100107 : context_(context),
Lalit Maganti6e9c55e2018-11-29 12:00:39 +0000108 utid_name_id_(context->storage->InternString("utid")),
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100109 cpu_freq_name_id_(context->storage->InternString("cpufreq")),
Hector Dearman7b794cc2018-11-30 14:35:30 +0000110 cpu_idle_name_id_(context->storage->InternString("cpuidle")),
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100111 num_forks_name_id_(context->storage->InternString("num_forks")),
112 num_irq_total_name_id_(context->storage->InternString("num_irq_total")),
113 num_softirq_total_name_id_(
114 context->storage->InternString("num_softirq_total")),
115 num_irq_name_id_(context->storage->InternString("num_irq")),
116 num_softirq_name_id_(context->storage->InternString("num_softirq")),
117 cpu_times_user_ns_id_(
118 context->storage->InternString("cpu.times.user_ns")),
119 cpu_times_user_ice_ns_id_(
120 context->storage->InternString("cpu.times.user_ice_ns")),
121 cpu_times_system_mode_ns_id_(
122 context->storage->InternString("cpu.times.system_mode_ns")),
123 cpu_times_idle_ns_id_(
124 context->storage->InternString("cpu.times.idle_ns")),
125 cpu_times_io_wait_ns_id_(
126 context->storage->InternString("cpu.times.io_wait_ns")),
127 cpu_times_irq_ns_id_(context->storage->InternString("cpu.times.irq_ns")),
128 cpu_times_softirq_ns_id_(
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100129 context->storage->InternString("cpu.times.softirq_ns")),
130 ion_heap_grow_id_(context->storage->InternString("ion_heap_grow")),
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000131 ion_heap_shrink_id_(context->storage->InternString("ion_heap_shrink")),
132 signal_deliver_id_(context->storage->InternString("signal_deliver")),
Primiano Tuccib86e9ca2018-12-03 20:20:11 +0100133 signal_generate_id_(context->storage->InternString("signal_generate")),
134 batt_charge_id_(context->storage->InternString("batt.charge_uah")),
135 batt_capacity_id_(context->storage->InternString("batt.capacity_pct")),
136 batt_current_id_(context->storage->InternString("batt.current_ua")),
137 batt_current_avg_id_(
Primiano Tucci44231042018-12-06 21:34:32 +0000138 context->storage->InternString("batt.current.avg_ua")),
139 oom_score_adj_id_(context->storage->InternString("oom_score_adj")) {
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100140 for (const auto& name : BuildMeminfoCounterNames()) {
141 meminfo_strs_id_.emplace_back(context->storage->InternString(name));
142 }
143 for (const auto& name : BuildVmstatCounterNames()) {
144 vmstat_strs_id_.emplace_back(context->storage->InternString(name));
145 }
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100146 rss_members_.emplace_back(
147 context->storage->InternString("rss_stat.mm_filepages"));
148 rss_members_.emplace_back(
149 context->storage->InternString("rss_stat.mm_anonpages"));
150 rss_members_.emplace_back(
151 context->storage->InternString("rss_stat.mm_swapents"));
152 rss_members_.emplace_back(
Primiano Tuccibc560992018-12-06 19:11:45 +0000153 context->storage->InternString("rss_stat.mm_shmempages"));
154 rss_members_.emplace_back(
155 context->storage->InternString("rss_stat.unknown")); // Keep this last.
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700156
157 using MemCounters = protos::ProcessStats::MemCounters;
158 proc_mem_counter_names_[MemCounters::kVmSizeKbFieldNumber] =
159 context->storage->InternString("mem.virt");
160 proc_mem_counter_names_[MemCounters::kVmRssKbFieldNumber] =
161 context->storage->InternString("mem.rss");
162 proc_mem_counter_names_[MemCounters::kRssAnonKbFieldNumber] =
163 context->storage->InternString("mem.rss.anon");
164 proc_mem_counter_names_[MemCounters::kRssFileKbFieldNumber] =
165 context->storage->InternString("mem.rss.file");
166 proc_mem_counter_names_[MemCounters::kRssShmemKbFieldNumber] =
167 context->storage->InternString("mem.rss.shmem");
168 proc_mem_counter_names_[MemCounters::kVmSwapKbFieldNumber] =
169 context->storage->InternString("mem.swap");
170 proc_mem_counter_names_[MemCounters::kVmLockedKbFieldNumber] =
171 context->storage->InternString("mem.locked");
172 proc_mem_counter_names_[MemCounters::kVmHwmKbFieldNumber] =
173 context->storage->InternString("mem.rss.watermark");
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100174}
Lalit Maganti93b76362018-06-01 03:03:58 +0100175
Primiano Tucci0d72a312018-08-07 14:42:45 +0100176ProtoTraceParser::~ProtoTraceParser() = default;
177
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000178void ProtoTraceParser::ParseTracePacket(int64_t ts, TraceBlobView packet) {
Primiano Tuccid933d912018-09-04 09:15:07 +0100179 ProtoDecoder decoder(packet.data(), packet.length());
Lalit Maganti93b76362018-06-01 03:03:58 +0100180
Lalit Magantidf3e9262018-06-04 17:45:00 +0100181 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
182 switch (fld.id) {
Primiano Tuccid933d912018-09-04 09:15:07 +0100183 case protos::TracePacket::kProcessTreeFieldNumber: {
184 const size_t fld_off = packet.offset_of(fld.data());
185 ParseProcessTree(packet.slice(fld_off, fld.size()));
Isabelle Taylord80932a2018-06-19 17:00:47 +0100186 break;
Primiano Tuccid933d912018-09-04 09:15:07 +0100187 }
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700188 case protos::TracePacket::kProcessStatsFieldNumber: {
189 const size_t fld_off = packet.offset_of(fld.data());
190 ParseProcessStats(ts, packet.slice(fld_off, fld.size()));
191 break;
192 }
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100193 case protos::TracePacket::kSysStatsFieldNumber: {
194 const size_t fld_off = packet.offset_of(fld.data());
195 ParseSysStats(ts, packet.slice(fld_off, fld.size()));
196 break;
197 }
Primiano Tuccib86e9ca2018-12-03 20:20:11 +0100198 case protos::TracePacket::kBatteryFieldNumber: {
199 const size_t fld_off = packet.offset_of(fld.data());
200 ParseBatteryCounters(ts, packet.slice(fld_off, fld.size()));
201 break;
202 }
Lalit Magantidf3e9262018-06-04 17:45:00 +0100203 default:
204 break;
205 }
206 }
207 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
208}
209
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000210void ProtoTraceParser::ParseSysStats(int64_t ts, TraceBlobView stats) {
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100211 ProtoDecoder decoder(stats.data(), stats.length());
212 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
213 switch (fld.id) {
214 case protos::SysStats::kMeminfoFieldNumber: {
215 const size_t fld_off = stats.offset_of(fld.data());
216 ParseMemInfo(ts, stats.slice(fld_off, fld.size()));
217 break;
218 }
219 case protos::SysStats::kVmstatFieldNumber: {
220 const size_t fld_off = stats.offset_of(fld.data());
221 ParseVmStat(ts, stats.slice(fld_off, fld.size()));
222 break;
223 }
224 case protos::SysStats::kCpuStatFieldNumber: {
225 const size_t fld_off = stats.offset_of(fld.data());
226 ParseCpuTimes(ts, stats.slice(fld_off, fld.size()));
227 break;
228 }
229 case protos::SysStats::kNumIrqFieldNumber: {
230 const size_t fld_off = stats.offset_of(fld.data());
231 ParseIrqCount(ts, stats.slice(fld_off, fld.size()),
232 /*is_softirq=*/false);
233 break;
234 }
235 case protos::SysStats::kNumSoftirqFieldNumber: {
236 const size_t fld_off = stats.offset_of(fld.data());
237 ParseIrqCount(ts, stats.slice(fld_off, fld.size()),
238 /*is_softirq=*/true);
239 break;
240 }
241 case protos::SysStats::kNumForksFieldNumber: {
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100242 context_->event_tracker->PushCounter(
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000243 ts, fld.as_uint32(), num_forks_name_id_, 0, RefType::kRefNoRef);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100244 break;
245 }
246 case protos::SysStats::kNumIrqTotalFieldNumber: {
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100247 context_->event_tracker->PushCounter(
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000248 ts, fld.as_uint32(), num_irq_total_name_id_, 0, RefType::kRefNoRef);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100249 break;
250 }
251 case protos::SysStats::kNumSoftirqTotalFieldNumber: {
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100252 context_->event_tracker->PushCounter(ts, fld.as_uint32(),
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100253 num_softirq_total_name_id_, 0,
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000254 RefType::kRefNoRef);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100255 break;
256 }
257 default:
258 break;
259 }
260 }
261}
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000262void ProtoTraceParser::ParseIrqCount(int64_t ts,
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100263 TraceBlobView irq,
264 bool is_soft) {
265 ProtoDecoder decoder(irq.data(), irq.length());
266 uint32_t key = 0;
267 uint32_t value = 0;
268 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
269 switch (fld.id) {
270 case protos::SysStats::InterruptCount::kIrqFieldNumber:
271 key = fld.as_uint32();
272 break;
273 case protos::SysStats::InterruptCount::kCountFieldNumber:
274 value = fld.as_uint32();
275 break;
276 }
277 }
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000278 RefType ref_type = is_soft ? RefType::kRefIrq : RefType::kRefSoftIrq;
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100279 StringId name_id = is_soft ? num_irq_name_id_ : num_softirq_name_id_;
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100280 context_->event_tracker->PushCounter(ts, value, name_id, key, ref_type);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100281}
282
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000283void ProtoTraceParser::ParseMemInfo(int64_t ts, TraceBlobView mem) {
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100284 ProtoDecoder decoder(mem.data(), mem.length());
285 uint32_t key = 0;
286 uint32_t value = 0;
287 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
288 switch (fld.id) {
289 case protos::SysStats::MeminfoValue::kKeyFieldNumber:
290 key = fld.as_uint32();
291 break;
292 case protos::SysStats::MeminfoValue::kValueFieldNumber:
293 value = fld.as_uint32();
294 break;
295 }
296 }
297 if (PERFETTO_UNLIKELY(key >= meminfo_strs_id_.size())) {
298 PERFETTO_ELOG("MemInfo key %d is not recognized.", key);
299 return;
300 }
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100301 context_->event_tracker->PushCounter(ts, value, meminfo_strs_id_[key], 0,
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000302 RefType::kRefNoRef);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100303}
304
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000305void ProtoTraceParser::ParseVmStat(int64_t ts, TraceBlobView stat) {
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100306 ProtoDecoder decoder(stat.data(), stat.length());
307 uint32_t key = 0;
308 uint32_t value = 0;
309 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
310 switch (fld.id) {
311 case protos::SysStats::VmstatValue::kKeyFieldNumber:
312 key = fld.as_uint32();
313 break;
314 case protos::SysStats::VmstatValue::kValueFieldNumber:
315 value = fld.as_uint32();
316 break;
317 }
318 }
319 if (PERFETTO_UNLIKELY(key >= vmstat_strs_id_.size())) {
320 PERFETTO_ELOG("VmStat key %d is not recognized.", key);
321 return;
322 }
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100323 context_->event_tracker->PushCounter(ts, value, vmstat_strs_id_[key], 0,
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000324 RefType::kRefNoRef);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100325}
326
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000327void ProtoTraceParser::ParseCpuTimes(int64_t ts, TraceBlobView cpu_times) {
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100328 ProtoDecoder decoder(cpu_times.data(), cpu_times.length());
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000329 uint64_t raw_cpu = 0;
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100330 uint32_t value = 0;
331 // Speculate on CPU being first.
332 constexpr auto kCpuFieldTag = protozero::proto_utils::MakeTagVarInt(
333 protos::SysStats::CpuTimes::kCpuIdFieldNumber);
334 if (cpu_times.length() > 2 && cpu_times.data()[0] == kCpuFieldTag &&
335 cpu_times.data()[1] < 0x80) {
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000336 raw_cpu = cpu_times.data()[1];
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100337 } else {
338 if (!PERFETTO_LIKELY((
339 decoder.FindIntField<protos::SysStats::CpuTimes::kCpuIdFieldNumber>(
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000340 &raw_cpu)))) {
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100341 PERFETTO_ELOG("CPU field not found in CpuTimes");
342 return;
343 }
344 }
345
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000346 int64_t cpu = static_cast<int64_t>(raw_cpu);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100347 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
348 switch (fld.id) {
349 case protos::SysStats::CpuTimes::kUserNsFieldNumber: {
350 value = fld.as_uint32();
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100351 context_->event_tracker->PushCounter(ts, value, cpu_times_user_ns_id_,
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000352 cpu, RefType::kRefCpuId);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100353 break;
354 }
355 case protos::SysStats::CpuTimes::kUserIceNsFieldNumber: {
356 value = fld.as_uint32();
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100357 context_->event_tracker->PushCounter(
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000358 ts, value, cpu_times_user_ice_ns_id_, cpu, RefType::kRefCpuId);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100359 break;
360 }
361 case protos::SysStats::CpuTimes::kSystemModeNsFieldNumber: {
362 value = fld.as_uint32();
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100363 context_->event_tracker->PushCounter(
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000364 ts, value, cpu_times_system_mode_ns_id_, cpu, RefType::kRefCpuId);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100365 break;
366 }
367 case protos::SysStats::CpuTimes::kIdleNsFieldNumber: {
368 value = fld.as_uint32();
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100369 context_->event_tracker->PushCounter(ts, value, cpu_times_idle_ns_id_,
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000370 cpu, RefType::kRefCpuId);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100371 break;
372 }
373 case protos::SysStats::CpuTimes::kIoWaitNsFieldNumber: {
374 value = fld.as_uint32();
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100375 context_->event_tracker->PushCounter(
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000376 ts, value, cpu_times_io_wait_ns_id_, cpu, RefType::kRefCpuId);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100377 break;
378 }
379 case protos::SysStats::CpuTimes::kIrqNsFieldNumber: {
380 value = fld.as_uint32();
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100381 context_->event_tracker->PushCounter(ts, value, cpu_times_irq_ns_id_,
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000382 cpu, RefType::kRefCpuId);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100383 break;
384 }
385 case protos::SysStats::CpuTimes::kSoftirqNsFieldNumber: {
386 value = fld.as_uint32();
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100387 context_->event_tracker->PushCounter(
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000388 ts, value, cpu_times_softirq_ns_id_, cpu, RefType::kRefCpuId);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100389 break;
390 }
391 default:
392 break;
393 }
394 }
395}
396
Primiano Tuccid933d912018-09-04 09:15:07 +0100397void ProtoTraceParser::ParseProcessTree(TraceBlobView pstree) {
398 ProtoDecoder decoder(pstree.data(), pstree.length());
Isabelle Taylord80932a2018-06-19 17:00:47 +0100399
Isabelle Taylord80932a2018-06-19 17:00:47 +0100400 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
Primiano Tuccid933d912018-09-04 09:15:07 +0100401 const size_t fld_off = pstree.offset_of(fld.data());
Isabelle Taylord80932a2018-06-19 17:00:47 +0100402 switch (fld.id) {
Primiano Tuccid933d912018-09-04 09:15:07 +0100403 case protos::ProcessTree::kProcessesFieldNumber: {
404 ParseProcess(pstree.slice(fld_off, fld.size()));
Isabelle Taylord80932a2018-06-19 17:00:47 +0100405 break;
Primiano Tuccid933d912018-09-04 09:15:07 +0100406 }
407 case protos::ProcessTree::kThreadsFieldNumber: {
408 ParseThread(pstree.slice(fld_off, fld.size()));
Isabelle Taylord80932a2018-06-19 17:00:47 +0100409 break;
Primiano Tuccid933d912018-09-04 09:15:07 +0100410 }
Isabelle Taylord80932a2018-06-19 17:00:47 +0100411 default:
412 break;
413 }
414 }
415 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
416}
417
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000418void ProtoTraceParser::ParseProcessStats(int64_t ts, TraceBlobView stats) {
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700419 ProtoDecoder decoder(stats.data(), stats.length());
420
421 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
422 const size_t fld_off = stats.offset_of(fld.data());
423 switch (fld.id) {
424 case protos::ProcessStats::kMemCountersFieldNumber: {
425 ParseProcMemCounters(ts, stats.slice(fld_off, fld.size()));
426 break;
427 }
428 default:
429 break;
430 }
431 }
432 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
433}
434
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000435void ProtoTraceParser::ParseProcMemCounters(int64_t ts,
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700436 TraceBlobView proc_stat) {
437 ProtoDecoder decoder(proc_stat.data(), proc_stat.length());
438 uint32_t pid = 0;
439 // Maps a process counter field it to its value.
440 // E.g., 4 := 1024 -> "mem.rss.anon" := 1024.
441 std::array<uint64_t, kProcMemCounterSize> counter_values{};
442 std::array<uint8_t, kProcMemCounterSize> has_counter{};
443
444 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
445 switch (fld.id) {
446 case protos::ProcessStats::MemCounters::kPidFieldNumber:
447 pid = fld.as_uint32();
448 break;
449 default:
450 if (fld.id < counter_values.size()) {
451 // Memory counters are in KB, keep values in bytes in the trace
452 // processor.
453 counter_values[fld.id] = fld.as_uint64() * 1024;
454 has_counter[fld.id] = 1;
455 } else {
456 PERFETTO_ELOG("Skipping unknown process counters %" PRIu32, fld.id);
457 }
458 }
459 }
460
Lalit Maganti6d2edf62018-11-08 16:36:35 +0000461 UniqueTid utid = context_->process_tracker->UpdateThread(ts, pid, 0);
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700462
463 // Skip field_id 0 (invalid) and 1 (pid).
464 for (size_t field_id = 2; field_id < counter_values.size(); field_id++) {
465 if (!has_counter[field_id])
466 continue;
467
468 // Lookup the interned string id from the field name using the
469 // pre-cached |proc_mem_counter_names_| map.
470 StringId name = proc_mem_counter_names_[field_id];
471 uint64_t value = counter_values[field_id];
Lalit Maganti5ea9e932018-11-30 14:19:39 +0000472 auto row_id = context_->event_tracker->PushCounter(
Lalit Maganti6e9c55e2018-11-29 12:00:39 +0000473 ts, value, name, utid, RefType::kRefUtidLookupUpid);
Lalit Maganti5ea9e932018-11-30 14:19:39 +0000474 context_->storage->mutable_args()->AddArg(row_id, utid_name_id_,
475 utid_name_id_, utid);
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700476 }
477
478 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
479}
480
Primiano Tuccid933d912018-09-04 09:15:07 +0100481void ProtoTraceParser::ParseThread(TraceBlobView thread) {
482 ProtoDecoder decoder(thread.data(), thread.length());
Isabelle Taylord80932a2018-06-19 17:00:47 +0100483 uint32_t tid = 0;
484 uint32_t tgid = 0;
Isabelle Taylord80932a2018-06-19 17:00:47 +0100485 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
486 switch (fld.id) {
487 case protos::ProcessTree::Thread::kTidFieldNumber:
488 tid = fld.as_uint32();
489 break;
490 case protos::ProcessTree::Thread::kTgidFieldNumber:
491 tgid = fld.as_uint32();
492 break;
Isabelle Taylord80932a2018-06-19 17:00:47 +0100493 default:
494 break;
495 }
496 }
Isabelle Taylora0a22972018-08-03 12:06:12 +0100497 context_->process_tracker->UpdateThread(tid, tgid);
Isabelle Taylord80932a2018-06-19 17:00:47 +0100498
499 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
500}
501
Primiano Tuccid933d912018-09-04 09:15:07 +0100502void ProtoTraceParser::ParseProcess(TraceBlobView process) {
503 ProtoDecoder decoder(process.data(), process.length());
504
Isabelle Taylord80932a2018-06-19 17:00:47 +0100505 uint32_t pid = 0;
Primiano Tucci2da5d2e2018-08-10 14:23:31 +0100506 base::StringView process_name;
Primiano Tuccid933d912018-09-04 09:15:07 +0100507
Isabelle Taylord80932a2018-06-19 17:00:47 +0100508 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
509 switch (fld.id) {
510 case protos::ProcessTree::Process::kPidFieldNumber:
511 pid = fld.as_uint32();
512 break;
513 case protos::ProcessTree::Process::kCmdlineFieldNumber:
Primiano Tucci2da5d2e2018-08-10 14:23:31 +0100514 if (process_name.empty())
515 process_name = fld.as_string();
Isabelle Taylord80932a2018-06-19 17:00:47 +0100516 break;
517 default:
518 break;
519 }
520 }
Primiano Tucci2da5d2e2018-08-10 14:23:31 +0100521 context_->process_tracker->UpdateProcess(pid, process_name);
Isabelle Taylord80932a2018-06-19 17:00:47 +0100522 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
523}
524
Primiano Tuccid933d912018-09-04 09:15:07 +0100525void ProtoTraceParser::ParseFtracePacket(uint32_t cpu,
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000526 int64_t timestamp,
Primiano Tuccid933d912018-09-04 09:15:07 +0100527 TraceBlobView ftrace) {
528 ProtoDecoder decoder(ftrace.data(), ftrace.length());
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100529 uint32_t pid = 0;
Lalit Magantidf3e9262018-06-04 17:45:00 +0100530 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
531 switch (fld.id) {
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100532 case protos::FtraceEvent::kPidFieldNumber: {
533 pid = fld.as_uint32();
534 break;
535 }
Primiano Tuccid933d912018-09-04 09:15:07 +0100536 case protos::FtraceEvent::kSchedSwitchFieldNumber: {
Lalit Magantidf3e9262018-06-04 17:45:00 +0100537 PERFETTO_DCHECK(timestamp > 0);
Primiano Tuccid933d912018-09-04 09:15:07 +0100538 const size_t fld_off = ftrace.offset_of(fld.data());
539 ParseSchedSwitch(cpu, timestamp, ftrace.slice(fld_off, fld.size()));
Lalit Magantidf3e9262018-06-04 17:45:00 +0100540 break;
Primiano Tuccid933d912018-09-04 09:15:07 +0100541 }
Isabelle Taylor14674d42018-09-07 11:33:11 +0100542 case protos::FtraceEvent::kCpuFrequency: {
543 PERFETTO_DCHECK(timestamp > 0);
544 const size_t fld_off = ftrace.offset_of(fld.data());
545 ParseCpuFreq(timestamp, ftrace.slice(fld_off, fld.size()));
546 break;
547 }
Hector Dearman7b794cc2018-11-30 14:35:30 +0000548 case protos::FtraceEvent::kCpuIdle: {
549 PERFETTO_DCHECK(timestamp > 0);
550 const size_t fld_off = ftrace.offset_of(fld.data());
551 ParseCpuIdle(timestamp, ftrace.slice(fld_off, fld.size()));
552 break;
553 }
Hector Dearman947f12a2018-09-11 16:50:36 +0100554 case protos::FtraceEvent::kPrintFieldNumber: {
555 PERFETTO_DCHECK(timestamp > 0);
556 const size_t fld_off = ftrace.offset_of(fld.data());
Lalit Magantide6267f2018-11-08 12:35:34 +0000557 ParsePrint(cpu, timestamp, pid, ftrace.slice(fld_off, fld.size()));
Hector Dearman947f12a2018-09-11 16:50:36 +0100558 break;
559 }
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100560 case protos::FtraceEvent::kRssStatFieldNumber: {
561 PERFETTO_DCHECK(timestamp > 0);
562 const size_t fld_off = ftrace.offset_of(fld.data());
563 ParseRssStat(timestamp, pid, ftrace.slice(fld_off, fld.size()));
564 break;
565 }
566 case protos::FtraceEvent::kIonHeapGrow: {
567 PERFETTO_DCHECK(timestamp > 0);
568 const size_t fld_off = ftrace.offset_of(fld.data());
569 ParseIonHeapGrow(timestamp, pid, ftrace.slice(fld_off, fld.size()));
570 break;
571 }
572 case protos::FtraceEvent::kIonHeapShrink: {
573 PERFETTO_DCHECK(timestamp > 0);
574 const size_t fld_off = ftrace.offset_of(fld.data());
575 ParseIonHeapShrink(timestamp, pid, ftrace.slice(fld_off, fld.size()));
576 break;
577 }
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000578 case protos::FtraceEvent::kSignalGenerate: {
579 PERFETTO_DCHECK(timestamp > 0);
580 const size_t fld_off = ftrace.offset_of(fld.data());
581 ParseSignalGenerate(timestamp, ftrace.slice(fld_off, fld.size()));
582 break;
583 }
584 case protos::FtraceEvent::kSignalDeliver: {
585 PERFETTO_DCHECK(timestamp > 0);
586 const size_t fld_off = ftrace.offset_of(fld.data());
587 ParseSignalDeliver(timestamp, pid, ftrace.slice(fld_off, fld.size()));
588 break;
589 }
Primiano Tucci44231042018-12-06 21:34:32 +0000590 case protos::FtraceEvent::kOomScoreAdjUpdate: {
591 PERFETTO_DCHECK(timestamp > 0);
592 const size_t fld_off = ftrace.offset_of(fld.data());
593 ParseOOMScoreAdjUpdate(timestamp, ftrace.slice(fld_off, fld.size()));
594 break;
595 }
Lalit Magantidf3e9262018-06-04 17:45:00 +0100596 default:
597 break;
598 }
599 }
600 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
601}
602
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000603void ProtoTraceParser::ParseSignalDeliver(int64_t timestamp,
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000604 uint32_t pid,
605 TraceBlobView view) {
606 ProtoDecoder decoder(view.data(), view.length());
607 uint32_t sig = 0;
608 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
609 switch (fld.id) {
610 case protos::SignalDeliverFtraceEvent::kSigFieldNumber:
611 sig = fld.as_uint32();
612 break;
613 }
614 }
615 auto* instants = context_->storage->mutable_instants();
616 UniqueTid utid = context_->process_tracker->UpdateThread(timestamp, pid, 0);
617 instants->AddInstantEvent(timestamp, signal_deliver_id_, sig, utid,
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000618 RefType::kRefUtid);
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000619}
620
Isabelle Taylor0996dbf2018-11-07 11:33:38 +0000621// This event has both the pid of the thread that sent the signal and the
622// destination of the signal. Currently storing the pid of the destination.
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000623void ProtoTraceParser::ParseSignalGenerate(int64_t timestamp,
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000624 TraceBlobView view) {
625 ProtoDecoder decoder(view.data(), view.length());
626 uint32_t pid = 0;
627 uint32_t sig = 0;
628 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
629 switch (fld.id) {
630 case protos::SignalGenerateFtraceEvent::kPidFieldNumber:
631 pid = fld.as_uint32();
632 break;
633 case protos::SignalGenerateFtraceEvent::kSigFieldNumber:
634 sig = fld.as_uint32();
635 break;
636 }
637 }
638 auto* instants = context_->storage->mutable_instants();
639 UniqueTid utid = context_->process_tracker->UpdateThread(timestamp, pid, 0);
640 instants->AddInstantEvent(timestamp, signal_generate_id_, sig, utid,
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000641 RefType::kRefUtid);
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000642}
643
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000644void ProtoTraceParser::ParseLowmemoryKill(int64_t timestamp,
Isabelle Taylor0996dbf2018-11-07 11:33:38 +0000645 TraceBlobView view) {
646 // TODO(taylori): Store the pagecache_size, pagecache_limit and free fields
647 // in an args table
648 ProtoDecoder decoder(view.data(), view.length());
649 uint32_t pid = 0;
650 base::StringView comm;
651 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
652 switch (fld.id) {
653 case protos::LowmemoryKillFtraceEvent::kPidFieldNumber:
654 pid = fld.as_uint32();
655 break;
656 case protos::LowmemoryKillFtraceEvent::kCommFieldNumber:
657 comm = fld.as_string();
658 break;
659 }
660 }
661 // TODO(taylori): Move the comm to the args table once it exists.
662 StringId name = context_->storage->InternString(
663 base::StringView("mem.lmk." + comm.ToStdString()));
664 auto* instants = context_->storage->mutable_instants();
665 // Storing the pid of the event that is lmk-ed.
666 UniqueTid utid = context_->process_tracker->UpdateThread(timestamp, pid, 0);
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000667 instants->AddInstantEvent(timestamp, 0, name, utid, RefType::kRefUtid);
Isabelle Taylor0996dbf2018-11-07 11:33:38 +0000668}
669
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000670void ProtoTraceParser::ParseRssStat(int64_t timestamp,
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100671 uint32_t pid,
672 TraceBlobView view) {
673 ProtoDecoder decoder(view.data(), view.length());
Primiano Tuccibc560992018-12-06 19:11:45 +0000674 const auto kRssStatUnknown = static_cast<uint32_t>(rss_members_.size()) - 1;
675 uint32_t member = kRssStatUnknown;
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100676 uint32_t size = 0;
677 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
678 switch (fld.id) {
679 case protos::RssStatFtraceEvent::kMemberFieldNumber:
680 member = fld.as_uint32();
681 break;
682 case protos::RssStatFtraceEvent::kSizeFieldNumber:
683 size = fld.as_uint32();
684 break;
685 }
686 }
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700687 if (member >= rss_members_.size()) {
Primiano Tuccibc560992018-12-06 19:11:45 +0000688 // TODO(lalitm): this import error should be exposed in the stats.
689 member = kRssStatUnknown;
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700690 }
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100691 UniqueTid utid = context_->process_tracker->UpdateThread(timestamp, pid, 0);
Lalit Maganti6d2edf62018-11-08 16:36:35 +0000692
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100693 context_->event_tracker->PushCounter(timestamp, size, rss_members_[member],
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000694 utid, RefType::kRefUtidLookupUpid);
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100695 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
696}
697
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000698void ProtoTraceParser::ParseIonHeapGrow(int64_t timestamp,
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100699 uint32_t pid,
700 TraceBlobView view) {
701 ProtoDecoder decoder(view.data(), view.length());
702 uint32_t value = 0;
703 // TODO(b/118300811): The heap name pointer cannot be read. Read once it
704 // has been fixed.
705 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
706 switch (fld.id) {
707 case protos::IonHeapGrowFtraceEvent::kTotalAllocatedFieldNumber:
708 value = fld.as_uint32();
709 break;
710 }
711 }
712 UniqueTid utid = context_->process_tracker->UpdateThread(timestamp, pid, 0);
713 context_->event_tracker->PushCounter(timestamp, value, ion_heap_grow_id_,
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000714 utid, RefType::kRefUtid);
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100715 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
716}
717
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000718void ProtoTraceParser::ParseIonHeapShrink(int64_t timestamp,
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100719 uint32_t pid,
720 TraceBlobView view) {
721 ProtoDecoder decoder(view.data(), view.length());
722 uint32_t value = 0;
723 // TODO(b/118300811): The heap name pointer cannot be read. Read once it
724 // has been fixed.
725 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
726 switch (fld.id) {
727 case protos::IonHeapShrinkFtraceEvent::kTotalAllocatedFieldNumber:
728 value = fld.as_uint32();
729 break;
730 }
731 }
732 UniqueTid utid = context_->process_tracker->UpdateThread(timestamp, pid, 0);
733 context_->event_tracker->PushCounter(timestamp, value, ion_heap_shrink_id_,
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000734 utid, RefType::kRefUtid);
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100735 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
736}
737
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000738void ProtoTraceParser::ParseCpuFreq(int64_t timestamp, TraceBlobView view) {
Isabelle Taylor14674d42018-09-07 11:33:11 +0100739 ProtoDecoder decoder(view.data(), view.length());
740
Isabelle Taylor15314ea2018-09-19 11:35:19 +0100741 uint32_t cpu_affected = 0;
Isabelle Taylor14674d42018-09-07 11:33:11 +0100742 uint32_t new_freq = 0;
743 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
744 switch (fld.id) {
745 case protos::CpuFrequencyFtraceEvent::kCpuIdFieldNumber:
Isabelle Taylor15314ea2018-09-19 11:35:19 +0100746 cpu_affected = fld.as_uint32();
Isabelle Taylor14674d42018-09-07 11:33:11 +0100747 break;
748 case protos::CpuFrequencyFtraceEvent::kStateFieldNumber:
749 new_freq = fld.as_uint32();
750 break;
751 }
752 }
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100753 context_->event_tracker->PushCounter(timestamp, new_freq, cpu_freq_name_id_,
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000754 cpu_affected, RefType::kRefCpuId);
Isabelle Taylor14674d42018-09-07 11:33:11 +0100755 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
756}
757
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000758void ProtoTraceParser::ParseCpuIdle(int64_t timestamp, TraceBlobView view) {
Hector Dearman7b794cc2018-11-30 14:35:30 +0000759 ProtoDecoder decoder(view.data(), view.length());
760
761 uint32_t cpu_affected = 0;
762 uint32_t new_state = 0;
763 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
764 switch (fld.id) {
765 case protos::CpuIdleFtraceEvent::kCpuIdFieldNumber:
766 cpu_affected = fld.as_uint32();
767 break;
768 case protos::CpuIdleFtraceEvent::kStateFieldNumber:
769 new_state = fld.as_uint32();
770 break;
771 }
772 }
773 context_->event_tracker->PushCounter(timestamp, new_state, cpu_idle_name_id_,
774 cpu_affected, RefType::kRefCpuId);
775 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
776}
777
Primiano Tucci7e330292018-08-24 19:10:52 +0200778void ProtoTraceParser::ParseSchedSwitch(uint32_t cpu,
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000779 int64_t timestamp,
Primiano Tuccid933d912018-09-04 09:15:07 +0100780 TraceBlobView sswitch) {
781 ProtoDecoder decoder(sswitch.data(), sswitch.length());
782
Lalit Magantidf3e9262018-06-04 17:45:00 +0100783 uint32_t prev_pid = 0;
Lalit Maganti35622b72018-06-06 12:03:11 +0100784 uint32_t prev_state = 0;
Lalit Magantifde29042018-10-04 13:28:52 +0100785 base::StringView next_comm;
Lalit Magantidf3e9262018-06-04 17:45:00 +0100786 uint32_t next_pid = 0;
Lalit Magantidf3e9262018-06-04 17:45:00 +0100787 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
788 switch (fld.id) {
789 case protos::SchedSwitchFtraceEvent::kPrevPidFieldNumber:
790 prev_pid = fld.as_uint32();
791 break;
Lalit Maganti35622b72018-06-06 12:03:11 +0100792 case protos::SchedSwitchFtraceEvent::kPrevStateFieldNumber:
793 prev_state = fld.as_uint32();
794 break;
Lalit Magantidf3e9262018-06-04 17:45:00 +0100795 case protos::SchedSwitchFtraceEvent::kNextPidFieldNumber:
796 next_pid = fld.as_uint32();
797 break;
Lalit Magantifde29042018-10-04 13:28:52 +0100798 case protos::SchedSwitchFtraceEvent::kNextCommFieldNumber:
799 next_comm = fld.as_string();
800 break;
Lalit Magantidf3e9262018-06-04 17:45:00 +0100801 default:
802 break;
803 }
804 }
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100805 context_->event_tracker->PushSchedSwitch(cpu, timestamp, prev_pid, prev_state,
Lalit Magantifde29042018-10-04 13:28:52 +0100806 next_pid, next_comm);
Lalit Magantidf3e9262018-06-04 17:45:00 +0100807 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
808}
809
Hector Dearman947f12a2018-09-11 16:50:36 +0100810void ProtoTraceParser::ParsePrint(uint32_t,
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000811 int64_t timestamp,
Lalit Magantide6267f2018-11-08 12:35:34 +0000812 uint32_t pid,
Hector Dearman947f12a2018-09-11 16:50:36 +0100813 TraceBlobView print) {
814 ProtoDecoder decoder(print.data(), print.length());
815
816 base::StringView buf{};
817 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
818 if (fld.id == protos::PrintFtraceEvent::kBufFieldNumber) {
819 buf = fld.as_string();
820 break;
821 }
822 }
823
824 SystraceTracePoint point{};
825 if (!ParseSystraceTracePoint(buf, &point))
826 return;
827
Hector Dearman947f12a2018-09-11 16:50:36 +0100828 switch (point.phase) {
829 case 'B': {
830 StringId name_id = context_->storage->InternString(point.name);
Lalit Magantide6267f2018-11-08 12:35:34 +0000831 context_->slice_tracker->BeginAndroid(timestamp, pid, point.tid,
832 0 /*cat_id*/, name_id);
Hector Dearman947f12a2018-09-11 16:50:36 +0100833 break;
834 }
835
836 case 'E': {
Lalit Magantide6267f2018-11-08 12:35:34 +0000837 context_->slice_tracker->EndAndroid(timestamp, pid, point.tid);
Hector Dearman947f12a2018-09-11 16:50:36 +0100838 break;
839 }
Isabelle Taylor31e04402018-09-19 12:13:25 +0100840
841 case 'C': {
Lalit Magantide6267f2018-11-08 12:35:34 +0000842 UniqueTid utid =
843 context_->process_tracker->UpdateThread(timestamp, point.tid, 0);
Isabelle Taylor31e04402018-09-19 12:13:25 +0100844 StringId name_id = context_->storage->InternString(point.name);
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100845 context_->event_tracker->PushCounter(timestamp, point.value, name_id,
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000846 utid, RefType::kRefUtid);
Isabelle Taylor31e04402018-09-19 12:13:25 +0100847 }
Hector Dearman947f12a2018-09-11 16:50:36 +0100848 }
849 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
850}
851
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000852void ProtoTraceParser::ParseBatteryCounters(int64_t ts, TraceBlobView battery) {
Primiano Tuccib86e9ca2018-12-03 20:20:11 +0100853 ProtoDecoder decoder(battery.data(), battery.length());
854 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
855 switch (fld.id) {
856 case protos::BatteryCounters::kChargeCounterUahFieldNumber:
857 context_->event_tracker->PushCounter(
858 ts, fld.as_int64(), batt_charge_id_, 0, RefType::kRefNoRef);
859 break;
860 case protos::BatteryCounters::kCapacityPercentFieldNumber:
861 context_->event_tracker->PushCounter(
862 ts, static_cast<double>(fld.as_float()), batt_capacity_id_, 0,
863 RefType::kRefNoRef);
864 break;
865 case protos::BatteryCounters::kCurrentUaFieldNumber:
866 context_->event_tracker->PushCounter(
867 ts, fld.as_int64(), batt_current_id_, 0, RefType::kRefNoRef);
868 break;
869 case protos::BatteryCounters::kCurrentAvgUaFieldNumber:
870 context_->event_tracker->PushCounter(
871 ts, fld.as_int64(), batt_current_avg_id_, 0, RefType::kRefNoRef);
872 break;
873 default:
874 break;
875 }
876 }
877 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
878}
879
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000880void ProtoTraceParser::ParseOOMScoreAdjUpdate(int64_t ts,
Primiano Tucci44231042018-12-06 21:34:32 +0000881 TraceBlobView oom_update) {
882 ProtoDecoder decoder(oom_update.data(), oom_update.length());
883 uint32_t pid = 0;
884 int16_t oom_adj = 0;
885
886 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
887 switch (fld.id) {
888 case protos::OomScoreAdjUpdateFtraceEvent::kOomScoreAdjFieldNumber:
889 // TODO(b/120618641): The int16_t static cast is required because of the
890 // linked negative varint encoding bug.
891 oom_adj = static_cast<int16_t>(fld.as_int32());
892 break;
893 case protos::OomScoreAdjUpdateFtraceEvent::kPidFieldNumber:
894 pid = fld.as_uint32();
895 break;
896 case protos::OomScoreAdjUpdateFtraceEvent::kCommFieldNumber:
897 default:
898 break;
899 }
900 }
901 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
902
903 UniquePid upid = context_->process_tracker->UpdateProcess(pid);
904 context_->event_tracker->PushCounter(ts, oom_adj, oom_score_adj_id_, upid,
905 RefType::kRefUpid);
906}
907
Lalit Maganti93b76362018-06-01 03:03:58 +0100908} // namespace trace_processor
909} // namespace perfetto