1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "bytrace_event_parser.h"
17 #include "app_start_filter.h"
18 #include "binder_filter.h"
19 #include "cpu_filter.h"
20 #include "filter_filter.h"
21 #include "irq_filter.h"
22 #include "measure_filter.h"
23 #include "parting_string.h"
24 #include "process_filter.h"
25 #include "slice_filter.h"
26 #include "stat_filter.h"
27 #include "syscall_filter.h"
28 #include "string_to_numerical.h"
29 #include "thread_state_flag.h"
30 #include "ts_common.h"
31 namespace SysTuning {
32 namespace TraceStreamer {
33 namespace {
GetFunctionName(const std::string_view & text,const std::string_view & delimiter)34 std::string GetFunctionName(const std::string_view &text, const std::string_view &delimiter)
35 {
36 std::string str("");
37 if (delimiter.empty()) {
38 return str;
39 }
40
41 std::size_t foundIndex = text.find(delimiter);
42 if (foundIndex != std::string::npos) {
43 std::size_t funIndex = foundIndex + delimiter.size();
44 str = std::string(text.substr(funIndex, text.size() - funIndex));
45 }
46 return str;
47 }
48 } // namespace
49
BytraceEventParser(TraceDataCache * dataCache,const TraceStreamerFilters * filter)50 BytraceEventParser::BytraceEventParser(TraceDataCache *dataCache, const TraceStreamerFilters *filter)
51 : EventParserBase(dataCache, filter), printEventParser_(traceDataCache_, streamFilters_)
52 {
53 printEventParser_.SetTraceType(TRACE_FILETYPE_BY_TRACE);
54 eventToFunctionMap_ = {
55 {config_.eventNameMap_.at(TRACE_EVENT_TASK_RENAME),
56 bind(&BytraceEventParser::TaskRenameEvent, this, std::placeholders::_1, std::placeholders::_2)},
57 {config_.eventNameMap_.at(TRACE_EVENT_TASK_NEWTASK),
58 bind(&BytraceEventParser::TaskNewtaskEvent, this, std::placeholders::_1, std::placeholders::_2)},
59 {config_.eventNameMap_.at(TRACE_EVENT_SCHED_SWITCH),
60 bind(&BytraceEventParser::SchedSwitchEvent, this, std::placeholders::_1, std::placeholders::_2)},
61 {config_.eventNameMap_.at(TRACE_EVENT_SCHED_BLOCKED_REASON),
62 bind(&BytraceEventParser::BlockedReason, this, std::placeholders::_1, std::placeholders::_2)},
63 {config_.eventNameMap_.at(TRACE_EVENT_SCHED_WAKEUP),
64 bind(&BytraceEventParser::SchedWakeupEvent, this, std::placeholders::_1, std::placeholders::_2)},
65 {config_.eventNameMap_.at(TRACE_EVENT_SCHED_WAKING),
66 bind(&BytraceEventParser::SchedWakingEvent, this, std::placeholders::_1, std::placeholders::_2)},
67 {config_.eventNameMap_.at(TRACE_EVENT_SCHED_WAKEUP_NEW),
68 bind(&BytraceEventParser::SchedWakeupEvent, this, std::placeholders::_1, std::placeholders::_2)},
69 {config_.eventNameMap_.at(TRACE_EVENT_PROCESS_EXIT),
70 bind(&BytraceEventParser::ProcessExitEvent, this, std::placeholders::_1, std::placeholders::_2)},
71 {config_.eventNameMap_.at(TRACE_EVENT_IPI_ENTRY),
72 bind(&BytraceEventParser::IpiEntryEvent, this, std::placeholders::_1, std::placeholders::_2)},
73 {config_.eventNameMap_.at(TRACE_EVENT_IPI_EXIT),
74 bind(&BytraceEventParser::IpiExitEvent, this, std::placeholders::_1, std::placeholders::_2)},
75 {config_.eventNameMap_.at(TRACE_EVENT_SYS_ENTRY),
76 bind(&BytraceEventParser::SysEnterEvent, this, std::placeholders::_1, std::placeholders::_2)},
77 {config_.eventNameMap_.at(TRACE_EVENT_SYS_EXIT),
78 bind(&BytraceEventParser::SysExitEvent, this, std::placeholders::_1, std::placeholders::_2)},
79 };
80 InterruptEventInitialization();
81 ClockEventInitialization();
82 CpuEventInitialization();
83 RegulatorEventInitialization();
84 BinderEventInitialization();
85 StackEventsInitialization();
86 eventList_.reserve(maxBuffSize_);
87 }
88
InterruptEventInitialization()89 void BytraceEventParser::InterruptEventInitialization()
90 {
91 // Interrupt and soft interrupt event initialization
92 eventToFunctionMap_.emplace(
93 config_.eventNameMap_.at(TRACE_EVENT_IRQ_HANDLER_ENTRY),
94 bind(&BytraceEventParser::IrqHandlerEntryEvent, this, std::placeholders::_1, std::placeholders::_2));
95 eventToFunctionMap_.emplace(
96 config_.eventNameMap_.at(TRACE_EVENT_IRQ_HANDLER_EXIT),
97 bind(&BytraceEventParser::IrqHandlerExitEvent, this, std::placeholders::_1, std::placeholders::_2));
98 eventToFunctionMap_.emplace(
99 config_.eventNameMap_.at(TRACE_EVENT_SOFTIRQ_RAISE),
100 bind(&BytraceEventParser::SoftIrqRaiseEvent, this, std::placeholders::_1, std::placeholders::_2));
101 eventToFunctionMap_.emplace(
102 config_.eventNameMap_.at(TRACE_EVENT_SOFTIRQ_ENTRY),
103 bind(&BytraceEventParser::SoftIrqEntryEvent, this, std::placeholders::_1, std::placeholders::_2));
104 eventToFunctionMap_.emplace(
105 config_.eventNameMap_.at(TRACE_EVENT_SOFTIRQ_EXIT),
106 bind(&BytraceEventParser::SoftIrqExitEvent, this, std::placeholders::_1, std::placeholders::_2));
107 eventToFunctionMap_.emplace(
108 config_.eventNameMap_.at(TRACE_EVENT_DMA_FENCE_INIT),
109 bind(&BytraceEventParser::DmaFenceEvent, this, std::placeholders::_1, std::placeholders::_2));
110 eventToFunctionMap_.emplace(
111 config_.eventNameMap_.at(TRACE_EVENT_DMA_FENCE_DESTROY),
112 bind(&BytraceEventParser::DmaFenceEvent, this, std::placeholders::_1, std::placeholders::_2));
113 eventToFunctionMap_.emplace(
114 config_.eventNameMap_.at(TRACE_EVENT_DMA_FENCE_ENABLE),
115 bind(&BytraceEventParser::DmaFenceEvent, this, std::placeholders::_1, std::placeholders::_2));
116 eventToFunctionMap_.emplace(
117 config_.eventNameMap_.at(TRACE_EVENT_DMA_FENCE_SIGNALED),
118 bind(&BytraceEventParser::DmaFenceEvent, this, std::placeholders::_1, std::placeholders::_2));
119 }
120
ClockEventInitialization()121 void BytraceEventParser::ClockEventInitialization()
122 {
123 // Clock event initialization
124 eventToFunctionMap_.emplace(
125 config_.eventNameMap_.at(TRACE_EVENT_CLOCK_SET_RATE),
126 bind(&BytraceEventParser::SetRateEvent, this, std::placeholders::_1, std::placeholders::_2));
127 eventToFunctionMap_.emplace(
128 config_.eventNameMap_.at(TRACE_EVENT_CLOCK_ENABLE),
129 bind(&BytraceEventParser::ClockEnableEvent, this, std::placeholders::_1, std::placeholders::_2));
130 eventToFunctionMap_.emplace(
131 config_.eventNameMap_.at(TRACE_EVENT_CLOCK_DISABLE),
132 bind(&BytraceEventParser::ClockDisableEvent, this, std::placeholders::_1, std::placeholders::_2));
133 }
134
CpuEventInitialization()135 void BytraceEventParser::CpuEventInitialization()
136 {
137 eventToFunctionMap_.emplace(
138 config_.eventNameMap_.at(TRACE_EVENT_CPU_IDLE),
139 bind(&BytraceEventParser::CpuIdleEvent, this, std::placeholders::_1, std::placeholders::_2));
140 eventToFunctionMap_.emplace(
141 config_.eventNameMap_.at(TRACE_EVENT_CPU_FREQUENCY),
142 bind(&BytraceEventParser::CpuFrequencyEvent, this, std::placeholders::_1, std::placeholders::_2));
143 eventToFunctionMap_.emplace(
144 config_.eventNameMap_.at(TRACE_EVENT_CPU_FREQUENCY_LIMITS),
145 bind(&BytraceEventParser::CpuFrequencyLimitsEvent, this, std::placeholders::_1, std::placeholders::_2));
146 }
147
RegulatorEventInitialization()148 void BytraceEventParser::RegulatorEventInitialization()
149 {
150 // Initialize regulator related events
151 eventToFunctionMap_.emplace(
152 config_.eventNameMap_.at(TRACE_EVENT_REGULATOR_SET_VOLTAGE),
153 bind(&BytraceEventParser::RegulatorSetVoltageEvent, this, std::placeholders::_1, std::placeholders::_2));
154 eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_REGULATOR_SET_VOLTAGE_COMPLETE),
155 bind(&BytraceEventParser::RegulatorSetVoltageCompleteEvent, this, std::placeholders::_1,
156 std::placeholders::_2));
157 eventToFunctionMap_.emplace(
158 config_.eventNameMap_.at(TRACE_EVENT_REGULATOR_DISABLE),
159 bind(&BytraceEventParser::RegulatorDisableEvent, this, std::placeholders::_1, std::placeholders::_2));
160 eventToFunctionMap_.emplace(
161 config_.eventNameMap_.at(TRACE_EVENT_REGULATOR_DISABLE_COMPLETE),
162 bind(&BytraceEventParser::RegulatorDisableCompleteEvent, this, std::placeholders::_1, std::placeholders::_2));
163 }
164
BinderEventInitialization()165 void BytraceEventParser::BinderEventInitialization()
166 {
167 // Binder event initialization
168 eventToFunctionMap_.emplace(
169 config_.eventNameMap_.at(TRACE_EVENT_BINDER_TRANSACTION),
170 bind(&BytraceEventParser::BinderTransaction, this, std::placeholders::_1, std::placeholders::_2));
171 eventToFunctionMap_.emplace(
172 config_.eventNameMap_.at(TRACE_EVENT_BINDER_TRANSACTION_RECEIVED),
173 bind(&BytraceEventParser::BinderTransactionReceived, this, std::placeholders::_1, std::placeholders::_2));
174 eventToFunctionMap_.emplace(
175 config_.eventNameMap_.at(TRACE_EVENT_BINDER_TRANSACTION_ALLOC_BUF),
176 bind(&BytraceEventParser::BinderTransactionAllocBufEvent, this, std::placeholders::_1, std::placeholders::_2));
177 }
178
StackEventsInitialization()179 void BytraceEventParser::StackEventsInitialization()
180 {
181 // Call stack Events
182 eventToFunctionMap_.emplace(
183 config_.eventNameMap_.at(TRACE_EVENT_TRACING_MARK_WRITE),
184 bind(&BytraceEventParser::TracingMarkWriteOrPrintEvent, this, std::placeholders::_1, std::placeholders::_2));
185 eventToFunctionMap_.emplace(
186 config_.eventNameMap_.at(TRACE_EVENT_PRINT),
187 bind(&BytraceEventParser::TracingMarkWriteOrPrintEvent, this, std::placeholders::_1, std::placeholders::_2));
188 eventToFunctionMap_.emplace(
189 config_.eventNameMap_.at(TRACE_EVENT_WORKQUEUE_EXECUTE_START),
190 bind(&BytraceEventParser::WorkqueueExecuteStartEvent, this, std::placeholders::_1, std::placeholders::_2));
191 eventToFunctionMap_.emplace(
192 config_.eventNameMap_.at(TRACE_EVENT_WORKQUEUE_EXECUTE_END),
193 bind(&BytraceEventParser::WorkqueueExecuteEndEvent, this, std::placeholders::_1, std::placeholders::_2));
194 }
195
SysEnterEvent(const ArgsMap & args,const BytraceLine & line)196 bool BytraceEventParser::SysEnterEvent(const ArgsMap &args, const BytraceLine &line)
197 {
198 if (streamFilters_->configFilter_->GetSwitchConfig().SyscallsTsSet().empty()) {
199 return true;
200 }
201 Unused(args);
202 std::string sysEnterStr = base::Strip(line.argsStr);
203 if (sysEnterStr.empty()) {
204 TS_LOGD("SysEnterEvent: Empty args string for sysEnterStr, skipping.");
205 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SYS_ENTRY, STAT_EVENT_DATA_INVALID);
206 return true;
207 }
208
209 auto firstSpacePos = sysEnterStr.find(" ");
210 if (firstSpacePos == std::string::npos) {
211 TS_LOGD("SysEnterEvent: No space found in sysEnterStr: '%s', skipping.", sysEnterStr.c_str());
212 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SYS_ENTRY, STAT_EVENT_DATA_INVALID);
213 return true;
214 }
215
216 // eg:NR 240 (f73bfb0c, 80, 2, f73bfab8, 5f5d907, 0)
217 DataIndex argsDataIndex = INVALID_UINT64;
218 auto secondSpacePos = sysEnterStr.find(" ", firstSpacePos + 1);
219 if (secondSpacePos != std::string::npos) {
220 std::string argsStr = sysEnterStr.substr(secondSpacePos + 1);
221 argsDataIndex = traceDataCache_->GetDataIndex(argsStr);
222 } else {
223 secondSpacePos = sysEnterStr.length();
224 }
225
226 uint32_t syscallNumber = std::atoi(sysEnterStr.substr(firstSpacePos, secondSpacePos).c_str());
227 SyscallInfoRow syscallInfoRow;
228 syscallInfoRow.ts = line.ts;
229 syscallInfoRow.itid = line.pid;
230 syscallInfoRow.args = argsDataIndex;
231 syscallInfoRow.number = syscallNumber;
232 streamFilters_->syscallFilter_->UpdataSyscallEnterExitMap(syscallInfoRow);
233 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SYS_ENTRY, STAT_EVENT_RECEIVED);
234 return true;
235 }
236
SysExitEvent(const ArgsMap & args,const BytraceLine & line)237 bool BytraceEventParser::SysExitEvent(const ArgsMap &args, const BytraceLine &line)
238 {
239 if (streamFilters_->configFilter_->GetSwitchConfig().SyscallsTsSet().empty()) {
240 return true;
241 }
242 Unused(args);
243 std::string sysExitStr = base::Strip(line.argsStr);
244 if (sysExitStr.empty()) {
245 TS_LOGD("SysExitEvent: Empty args string for sysExitStr, skipping.");
246 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SYS_EXIT, STAT_EVENT_DATA_INVALID);
247 return true;
248 }
249
250 auto firstSpacePos = sysExitStr.find(" ");
251 if (firstSpacePos == std::string::npos) {
252 TS_LOGD("SysExitEvent: No space found in sysExitStr: '%s', skipping.", sysExitStr.c_str());
253 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SYS_EXIT, STAT_EVENT_DATA_INVALID);
254 return true;
255 }
256
257 // eg:NR 85 = -22
258 int64_t ret = INVALID_INT64;
259 auto secondSpacePos = sysExitStr.find("= ");
260 if (secondSpacePos != std::string::npos) {
261 ret = std::atoi(sysExitStr.substr(secondSpacePos + 2).c_str());
262 } else {
263 secondSpacePos = sysExitStr.length();
264 }
265
266 uint32_t sysExitId = std::atoi(sysExitStr.substr(firstSpacePos, secondSpacePos).c_str());
267 streamFilters_->syscallFilter_->AppendSysCallInfo(line.pid, sysExitId, line.ts, ret);
268 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SYS_ENTRY, STAT_EVENT_RECEIVED);
269 return true;
270 }
271
SchedSwitchEvent(const ArgsMap & args,const BytraceLine & line) const272 bool BytraceEventParser::SchedSwitchEvent(const ArgsMap &args, const BytraceLine &line) const
273 {
274 if (args.empty() || args.size() < MIN_SCHED_SWITCH_ARGS_COUNT) {
275 TS_LOGW("Failed to parse sched_switch event, no args or args size < 6, argsStr=%s.", line.argsStr.data());
276 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_SWITCH, STAT_EVENT_DATA_INVALID);
277 return false;
278 }
279 auto prevCommStr = std::string_view(args.at("prev_comm"));
280 auto nextCommStr = std::string_view(args.at("next_comm"));
281 auto prevPrioValue = base::StrToInt<int32_t>(args.at("prev_prio"));
282 auto nextPrioValue = base::StrToInt<int32_t>(args.at("next_prio"));
283 auto prevPidValue = base::StrToInt<uint32_t>(args.at("prev_pid"));
284 auto nextPidValue = base::StrToInt<uint32_t>(args.at("next_pid"));
285 DataIndex nextInfo = INVALID_DATAINDEX;
286 auto nextInfoIt = args.find("next_info");
287 if (nextInfoIt != args.end()) {
288 nextInfo = traceDataCache_->GetDataIndex(std::string_view(args.at("next_info")));
289 }
290 if (!(prevPidValue.has_value() && prevPrioValue.has_value() && nextPidValue.has_value() &&
291 nextPrioValue.has_value())) {
292 TS_LOGD("Failed to parse sched_switch event");
293 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_SWITCH, STAT_EVENT_DATA_INVALID);
294 return false;
295 }
296 auto prevStateStr = args.at("prev_state");
297 auto threadState = ThreadStateFlag(prevStateStr.c_str());
298 uint64_t prevState = threadState.State();
299 if (threadState.IsInvalid()) {
300 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_SWITCH, STAT_EVENT_DATA_INVALID);
301 }
302 uint32_t nextInternalTid = 0;
303 uint32_t uprevtid = 0;
304 nextInternalTid =
305 streamFilters_->processFilter_->UpdateOrCreateThreadWithName(line.ts, nextPidValue.value(), nextCommStr);
306
307 if (!prevCommStr.empty()) {
308 uprevtid =
309 streamFilters_->processFilter_->UpdateOrCreateThreadWithName(line.ts, prevPidValue.value(), prevCommStr);
310 } else {
311 uprevtid = streamFilters_->processFilter_->UpdateOrCreateThread(line.ts, prevPidValue.value());
312 }
313 streamFilters_->cpuFilter_->InsertSwitchEvent(line.ts, line.cpu, uprevtid, prevPrioValue.value(), prevState,
314 nextInternalTid, nextPrioValue.value(), nextInfo);
315 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_SWITCH, STAT_EVENT_RECEIVED);
316 return true;
317 }
BlockedReason(const ArgsMap & args,const BytraceLine & line) const318 bool BytraceEventParser::BlockedReason(const ArgsMap &args, const BytraceLine &line) const
319 {
320 if (args.empty() || args.size() < MIN_BLOCKED_REASON_ARGS_COUNT) {
321 TS_LOGD("Failed to parse blocked_reason event, no args or args size < %d", MIN_BLOCKED_REASON_ARGS_COUNT);
322 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_BLOCKED_REASON, STAT_EVENT_DATA_INVALID);
323 return false;
324 }
325 auto tid = base::StrToInt<int32_t>(args.at("pid"));
326 auto iowaitIt = args.find("iowait");
327 if (iowaitIt == args.end()) {
328 iowaitIt = args.find("io_wait");
329 }
330 auto iowait = base::StrToInt<int32_t>(iowaitIt->second);
331 uint32_t delayValue = INVALID_UINT32;
332 if (args.find("delay") != args.end()) {
333 auto delay = base::StrToInt<int32_t>(args.at("delay"));
334 delayValue = delay.has_value() ? delay.value() : INVALID_UINT32;
335 }
336 auto caller = traceDataCache_->GetDataIndex(std::string_view(args.at("caller")));
337 if (!(tid.has_value() && iowait.has_value())) {
338 TS_LOGD("Failed to parse blocked_reason event");
339 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_BLOCKED_REASON, STAT_EVENT_DATA_INVALID);
340 return false;
341 }
342 auto iTid = streamFilters_->processFilter_->UpdateOrCreateThread(line.ts, tid.value());
343 if (streamFilters_->cpuFilter_->InsertBlockedReasonEvent(line.cpu, iTid, iowait.value(), caller, delayValue)) {
344 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_BLOCKED_REASON, STAT_EVENT_RECEIVED);
345 } else {
346 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_BLOCKED_REASON, STAT_EVENT_NOTMATCH);
347 }
348 return true;
349 }
350
TaskRenameEvent(const ArgsMap & args,const BytraceLine & line) const351 bool BytraceEventParser::TaskRenameEvent(const ArgsMap &args, const BytraceLine &line) const
352 {
353 if (args.empty() || args.size() < MIN_TASK_RENAME_ARGS_COUNT) {
354 TS_LOGD("Failed to parse task_rename event, no args or args size < 2");
355 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_TASK_RENAME, STAT_EVENT_DATA_INVALID);
356 return false;
357 }
358 auto prevCommStr = std::string_view(args.at("newcomm"));
359 auto pidValue = base::StrToInt<uint32_t>(args.at("pid"));
360 streamFilters_->processFilter_->UpdateOrCreateThreadWithName(line.ts, pidValue.value(), prevCommStr);
361 return true;
362 }
363
TaskNewtaskEvent(const ArgsMap & args,const BytraceLine & line) const364 bool BytraceEventParser::TaskNewtaskEvent(const ArgsMap &args, const BytraceLine &line) const
365 {
366 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_TASK_NEWTASK, STAT_EVENT_RECEIVED);
367 // the clone flag from txt trace from kernel original is HEX, but when it is converted from proto
368 // based trace, it will be OCT number, it is not stable, so we decide to ignore it
369 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_TASK_NEWTASK, STAT_EVENT_NOTSUPPORTED);
370 return true;
371 }
372
TracingMarkWriteOrPrintEvent(const ArgsMap & args,const BytraceLine & line)373 bool BytraceEventParser::TracingMarkWriteOrPrintEvent(const ArgsMap &args, const BytraceLine &line)
374 {
375 Unused(args);
376 return printEventParser_.ParsePrintEvent(line.task, line.ts, line.pid, line.argsStr.c_str(), line);
377 }
378 // prefer to use waking, unless no waking, can use wakeup
SchedWakeupEvent(const ArgsMap & args,const BytraceLine & line) const379 bool BytraceEventParser::SchedWakeupEvent(const ArgsMap &args, const BytraceLine &line) const
380 {
381 if (args.size() < MIN_SCHED_WAKEUP_ARGS_COUNT) {
382 TS_LOGD("Failed to parse SchedWakeupEvent event, no args or args size < 2");
383 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_WAKEUP, STAT_EVENT_DATA_INVALID);
384 return false;
385 }
386 std::optional<uint32_t> wakePidValue = base::StrToInt<uint32_t>(args.at("pid"));
387 if (!wakePidValue.has_value()) {
388 TS_LOGD("Failed to convert wake_pid");
389 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_WAKEUP, STAT_EVENT_DATA_INVALID);
390 return false;
391 }
392 auto instants = traceDataCache_->GetInstantsData();
393 InternalTid internalTid = streamFilters_->processFilter_->UpdateOrCreateThread(line.ts, wakePidValue.value_or(0));
394 streamFilters_->cpuFilter_->InsertWakeupEvent(line.ts, internalTid);
395
396 InternalTid wakeupFromPid = streamFilters_->processFilter_->UpdateOrCreateThread(line.ts, line.pid);
397
398 instants->AppendInstantEventData(line.ts, schedWakeupName_, internalTid, wakeupFromPid);
399 std::optional<uint32_t> targetCpu = base::StrToInt<uint32_t>(args.at("target_cpu"));
400 if (targetCpu.has_value()) {
401 traceDataCache_->GetRawData()->AppendRawData(line.ts, RAW_SCHED_WAKEUP, targetCpu.value(), wakeupFromPid);
402 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_WAKEUP, STAT_EVENT_RECEIVED);
403 }
404 return true;
405 }
406
SchedWakingEvent(const ArgsMap & args,const BytraceLine & line) const407 bool BytraceEventParser::SchedWakingEvent(const ArgsMap &args, const BytraceLine &line) const
408 {
409 if (args.empty() || args.size() < MIN_SCHED_WAKING_ARGS_COUNT) {
410 TS_LOGD("Failed to parse sched_waking event, no args or args size < 4");
411 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_WAKING, STAT_EVENT_DATA_INVALID);
412 return false;
413 }
414 std::optional<uint32_t> wakePidValue = base::StrToInt<uint32_t>(args.at("pid"));
415 if (!wakePidValue.has_value()) {
416 TS_LOGD("Failed to convert wake_pid");
417 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_WAKING, STAT_EVENT_DATA_INVALID);
418 return false;
419 }
420 auto instants = traceDataCache_->GetInstantsData();
421 InternalTid internalTid = streamFilters_->processFilter_->UpdateOrCreateThread(line.ts, wakePidValue.value());
422 DataIndex wakeByPidStrIndex = traceDataCache_->GetDataIndex(line.task);
423 InternalTid internalTidWakeup =
424 streamFilters_->processFilter_->UpdateOrCreateThreadWithNameIndex(line.ts, line.pid, wakeByPidStrIndex);
425 InternalTid wakeupFromPid = streamFilters_->processFilter_->UpdateOrCreateThread(line.ts, line.pid);
426 streamFilters_->cpuFilter_->InsertWakeupEvent(line.ts, internalTid, true);
427 instants->AppendInstantEventData(line.ts, schedWakingName_, internalTid, wakeupFromPid);
428 std::optional<uint32_t> targetCpu = base::StrToInt<uint32_t>(args.at("target_cpu"));
429 if (targetCpu.has_value()) {
430 traceDataCache_->GetRawData()->AppendRawData(line.ts, RAW_SCHED_WAKING, targetCpu.value(), internalTidWakeup);
431 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_WAKING, STAT_EVENT_RECEIVED);
432 }
433
434 return true;
435 }
436
CpuIdleEvent(const ArgsMap & args,const BytraceLine & line) const437 bool BytraceEventParser::CpuIdleEvent(const ArgsMap &args, const BytraceLine &line) const
438 {
439 if (args.empty() || args.size() < MIN_CPU_IDLE_ARGS_COUNT) {
440 TS_LOGD("Failed to parse cpu_idle event, no args or args size < 2");
441 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_IDLE, STAT_EVENT_DATA_INVALID);
442 return false;
443 }
444 std::optional<uint32_t> eventCpuValue = base::StrToInt<uint32_t>(args.at("cpu_id"));
445 std::optional<int64_t> newStateValue = base::StrToInt<int64_t>(args.at("state"));
446 if (!eventCpuValue.has_value()) {
447 TS_LOGD("Failed to convert event cpu");
448 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_IDLE, STAT_EVENT_DATA_INVALID);
449 return false;
450 }
451 if (!newStateValue.has_value()) {
452 TS_LOGD("Failed to convert state");
453 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_IDLE, STAT_EVENT_DATA_INVALID);
454 return false;
455 }
456 // Add cpu_idle event to raw_data_table
457 auto cpuidleNameIndex = traceDataCache_->GetDataIndex(line.eventName.c_str());
458 streamFilters_->measureFilter_->AppendNewMeasureData(EnumMeasureFilter::CPU, eventCpuValue.value(),
459 cpuidleNameIndex, line.ts,
460 config_.GetStateValue(newStateValue.value()));
461 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_IDLE, STAT_EVENT_RECEIVED);
462 return true;
463 }
464
CpuFrequencyEvent(const ArgsMap & args,const BytraceLine & line) const465 bool BytraceEventParser::CpuFrequencyEvent(const ArgsMap &args, const BytraceLine &line) const
466 {
467 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_FREQUENCY, STAT_EVENT_RECEIVED);
468 if (args.empty() || args.size() < MIN_CPU_FREQUENCY_ARGS_COUNT) {
469 TS_LOGD("Failed to parse cpu_frequency event, no args or args size < 2");
470 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_FREQUENCY, STAT_EVENT_DATA_INVALID);
471 return false;
472 }
473 std::optional<uint32_t> eventCpuValue = base::StrToInt<uint32_t>(args.at("cpu_id"));
474 std::optional<int64_t> newStateValue = base::StrToInt<int64_t>(args.at("state"));
475
476 if (!newStateValue.has_value()) {
477 TS_LOGD("Failed to convert state");
478 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_FREQUENCY, STAT_EVENT_DATA_INVALID);
479 return false;
480 }
481 if (!eventCpuValue.has_value()) {
482 TS_LOGD("Failed to convert event cpu");
483 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_FREQUENCY, STAT_EVENT_DATA_INVALID);
484 return false;
485 }
486
487 auto cpuidleNameIndex = traceDataCache_->GetDataIndex(line.eventName.c_str());
488 streamFilters_->measureFilter_->AppendNewMeasureData(EnumMeasureFilter::CPU, eventCpuValue.value(),
489 cpuidleNameIndex, line.ts, newStateValue.value());
490 return true;
491 }
CpuFrequencyLimitsEvent(const ArgsMap & args,const BytraceLine & line) const492 bool BytraceEventParser::CpuFrequencyLimitsEvent(const ArgsMap &args, const BytraceLine &line) const
493 {
494 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_FREQUENCY_LIMITS, STAT_EVENT_RECEIVED);
495 if (args.empty() || args.size() < MIN_CPU_FREQUENCY_ARGS_COUNT) {
496 TS_LOGD("Failed to parse cpu_frequency event, no args or args size < 2");
497 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_FREQUENCY_LIMITS, STAT_EVENT_DATA_INVALID);
498 return false;
499 }
500 std::optional<uint32_t> eventCpuValue = base::StrToInt<uint32_t>(args.at("cpu_id"));
501
502 auto minIt = args.find("min");
503 if (minIt == args.end()) {
504 minIt = args.find("min_freq");
505 }
506 auto maxIt = args.find("max");
507 if (maxIt == args.end()) {
508 maxIt = args.find("max_freq");
509 }
510 std::optional<int64_t> minValue = base::StrToInt<int64_t>(minIt->second);
511 std::optional<int64_t> maxValue = base::StrToInt<int64_t>(maxIt->second);
512
513 if (!minValue.has_value()) {
514 TS_LOGD("Failed to get frequency minValue");
515 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_FREQUENCY_LIMITS, STAT_EVENT_DATA_INVALID);
516 return false;
517 }
518 if (!maxValue.has_value()) {
519 TS_LOGD("Failed to get frequency maxValue");
520 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_FREQUENCY_LIMITS, STAT_EVENT_DATA_INVALID);
521 return false;
522 }
523 if (!eventCpuValue.has_value()) {
524 TS_LOGD("Failed to get frequency cpu");
525 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_FREQUENCY_LIMITS, STAT_EVENT_DATA_INVALID);
526 return false;
527 }
528
529 streamFilters_->measureFilter_->AppendNewMeasureData(EnumMeasureFilter::CPU, eventCpuValue.value(),
530 cpuFrequencyLimitMaxNameId, line.ts, maxValue.value());
531 streamFilters_->measureFilter_->AppendNewMeasureData(EnumMeasureFilter::CPU, eventCpuValue.value(),
532 cpuFrequencyLimitMinNameId, line.ts, minValue.value());
533 return true;
534 }
535
WorkqueueExecuteStartEvent(const ArgsMap & args,const BytraceLine & line) const536 bool BytraceEventParser::WorkqueueExecuteStartEvent(const ArgsMap &args, const BytraceLine &line) const
537 {
538 Unused(args);
539 auto splitStr = GetFunctionName(line.argsStr, "function ");
540 auto splitStrIndex = traceDataCache_->GetDataIndex(splitStr);
541 size_t result =
542 streamFilters_->sliceFilter_->BeginSlice(line.task, line.ts, line.pid, 0, workQueueId_, splitStrIndex);
543 traceDataCache_->GetInternalSlicesData()->AppendDistributeInfo();
544 if (result != INVALID_UINT32) {
545 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_WORKQUEUE_EXECUTE_START, STAT_EVENT_RECEIVED);
546 return true;
547 } else {
548 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_WORKQUEUE_EXECUTE_START, STAT_EVENT_DATA_LOST);
549 return false;
550 }
551 }
552
WorkqueueExecuteEndEvent(const ArgsMap & args,const BytraceLine & line) const553 bool BytraceEventParser::WorkqueueExecuteEndEvent(const ArgsMap &args, const BytraceLine &line) const
554 {
555 Unused(args);
556 if (streamFilters_->sliceFilter_->EndSlice(line.ts, line.pid, 0, workQueueId_)) {
557 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_WORKQUEUE_EXECUTE_END, STAT_EVENT_RECEIVED);
558 return true;
559 } else {
560 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_WORKQUEUE_EXECUTE_END, STAT_EVENT_NOTMATCH);
561 return false;
562 }
563 }
564
ProcessExitEvent(const ArgsMap & args,const BytraceLine & line) const565 bool BytraceEventParser::ProcessExitEvent(const ArgsMap &args, const BytraceLine &line) const
566 {
567 if (args.empty() || args.size() < MIN_PROCESS_EXIT_ARGS_COUNT) {
568 TS_LOGD("Failed to parse process_exit event, no args or args size < 2");
569 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_PROCESS_EXIT, STAT_EVENT_DATA_INVALID);
570 return false;
571 }
572 auto comm = std::string_view(args.at("comm"));
573 auto pid = base::StrToInt<uint32_t>(args.at("pid"));
574 if (!pid.has_value()) {
575 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_PROCESS_EXIT, STAT_EVENT_DATA_INVALID);
576 return false;
577 }
578 auto itid = streamFilters_->processFilter_->UpdateOrCreateThreadWithName(line.ts, pid.value(), comm);
579 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_PROCESS_EXIT, STAT_EVENT_RECEIVED);
580 if (streamFilters_->cpuFilter_->InsertProcessExitEvent(line.ts, line.cpu, itid)) {
581 return true;
582 } else {
583 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_PROCESS_EXIT, STAT_EVENT_NOTMATCH);
584 return false;
585 }
586 }
587
SetRateEvent(const ArgsMap & args,const BytraceLine & line) const588 bool BytraceEventParser::SetRateEvent(const ArgsMap &args, const BytraceLine &line) const
589 {
590 if (args.empty() || args.size() < MIN_CLOCK_SET_RATE_ARGS_COUNT) {
591 TS_LOGD("Failed to parse clock_set_rate event, no args or args size < 3");
592 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CLOCK_SET_RATE, STAT_EVENT_DATA_INVALID);
593 return false;
594 }
595 auto name = std::string_view(args.at("name"));
596 auto state = base::StrToInt<int64_t>(args.at("state"));
597 uint64_t cpu = 0;
598 DataIndex nameIndex = traceDataCache_->GetDataIndex(name);
599 streamFilters_->measureFilter_->AppendNewMeasureData(EnumMeasureFilter::CLOCK_RATE, cpu, nameIndex, line.ts,
600 state.value());
601 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CLOCK_SET_RATE, STAT_EVENT_RECEIVED);
602 return true;
603 }
604
ClockEnableEvent(const ArgsMap & args,const BytraceLine & line) const605 bool BytraceEventParser::ClockEnableEvent(const ArgsMap &args, const BytraceLine &line) const
606 {
607 if (args.empty() || args.size() < MIN_CLOCK_ENABLE_ARGS_COUNT) {
608 TS_LOGD("Failed to parse clock_enable event, no args or args size < 3");
609 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CLOCK_ENABLE, STAT_EVENT_DATA_INVALID);
610 return false;
611 }
612 auto name = std::string_view(args.at("name"));
613 auto state = base::StrToInt<int64_t>(args.at("state"));
614 auto cpuId = base::StrToInt<uint64_t>(args.at("cpu_id"));
615 DataIndex nameIndex = traceDataCache_->GetDataIndex(name);
616 streamFilters_->measureFilter_->AppendNewMeasureData(EnumMeasureFilter::CLOCK_ENABLE, cpuId.value(), nameIndex,
617 line.ts, state.value());
618 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CLOCK_ENABLE, STAT_EVENT_RECEIVED);
619 return true;
620 }
ClockDisableEvent(const ArgsMap & args,const BytraceLine & line) const621 bool BytraceEventParser::ClockDisableEvent(const ArgsMap &args, const BytraceLine &line) const
622 {
623 if (args.empty() || args.size() < MIN_CLOCK_DISABLE_ARGS_COUNT) {
624 TS_LOGD("Failed to parse clock_disable event, no args or args size < 3");
625 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CLOCK_DISABLE, STAT_EVENT_DATA_INVALID);
626 return false;
627 }
628 auto name = std::string_view(args.at("name"));
629 auto state = base::StrToInt<int64_t>(args.at("state"));
630 auto cpuId = base::StrToInt<uint64_t>(args.at("cpu_id"));
631 DataIndex nameIndex = traceDataCache_->GetDataIndex(name);
632 streamFilters_->measureFilter_->AppendNewMeasureData(EnumMeasureFilter::CLOCK_DISABLE, cpuId.value(), nameIndex,
633 line.ts, state.value());
634 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CLOCK_DISABLE, STAT_EVENT_RECEIVED);
635 return true;
636 }
637
RegulatorSetVoltageEvent(const ArgsMap & args,const BytraceLine & line) const638 bool BytraceEventParser::RegulatorSetVoltageEvent(const ArgsMap &args, const BytraceLine &line) const
639 {
640 Unused(args);
641 Unused(line);
642 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_REGULATOR_SET_VOLTAGE, STAT_EVENT_RECEIVED);
643 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_REGULATOR_SET_VOLTAGE, STAT_EVENT_NOTSUPPORTED);
644 return true;
645 }
RegulatorSetVoltageCompleteEvent(const ArgsMap & args,const BytraceLine & line) const646 bool BytraceEventParser::RegulatorSetVoltageCompleteEvent(const ArgsMap &args, const BytraceLine &line) const
647 {
648 Unused(args);
649 Unused(line);
650 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_REGULATOR_SET_VOLTAGE_COMPLETE, STAT_EVENT_RECEIVED);
651 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_REGULATOR_SET_VOLTAGE_COMPLETE,
652 STAT_EVENT_NOTSUPPORTED);
653 return true;
654 }
RegulatorDisableEvent(const ArgsMap & args,const BytraceLine & line) const655 bool BytraceEventParser::RegulatorDisableEvent(const ArgsMap &args, const BytraceLine &line) const
656 {
657 Unused(args);
658 Unused(line);
659 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_REGULATOR_DISABLE, STAT_EVENT_RECEIVED);
660 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_REGULATOR_DISABLE, STAT_EVENT_NOTSUPPORTED);
661 return true;
662 }
RegulatorDisableCompleteEvent(const ArgsMap & args,const BytraceLine & line) const663 bool BytraceEventParser::RegulatorDisableCompleteEvent(const ArgsMap &args, const BytraceLine &line) const
664 {
665 Unused(args);
666 Unused(line);
667 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_REGULATOR_DISABLE_COMPLETE, STAT_EVENT_RECEIVED);
668 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_REGULATOR_DISABLE_COMPLETE, STAT_EVENT_NOTSUPPORTED);
669 return true;
670 }
671
IpiEntryEvent(const ArgsMap & args,const BytraceLine & line) const672 bool BytraceEventParser::IpiEntryEvent(const ArgsMap &args, const BytraceLine &line) const
673 {
674 Unused(args);
675 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_IPI_ENTRY, STAT_EVENT_RECEIVED);
676 streamFilters_->irqFilter_->IpiHandlerEntry(line.ts, line.cpu, traceDataCache_->GetDataIndex(line.argsStr));
677 return true;
678 }
IpiExitEvent(const ArgsMap & args,const BytraceLine & line) const679 bool BytraceEventParser::IpiExitEvent(const ArgsMap &args, const BytraceLine &line) const
680 {
681 Unused(args);
682 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_IPI_EXIT, STAT_EVENT_RECEIVED);
683 streamFilters_->irqFilter_->IpiHandlerExit(line.ts, line.cpu);
684 return true;
685 }
IrqHandlerEntryEvent(const ArgsMap & args,const BytraceLine & line) const686 bool BytraceEventParser::IrqHandlerEntryEvent(const ArgsMap &args, const BytraceLine &line) const
687 {
688 if (args.empty() || args.size() < MIN_IRQ_HANDLER_ENTRY_ARGS_COUNT) {
689 TS_LOGD("Failed to parse irq_handler_entry event, no args or args size < 2");
690 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_IRQ_HANDLER_ENTRY, STAT_EVENT_DATA_INVALID);
691 return false;
692 }
693 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_IRQ_HANDLER_ENTRY, STAT_EVENT_RECEIVED);
694 auto name = std::string_view(args.at("name"));
695 streamFilters_->irqFilter_->IrqHandlerEntry(line.ts, line.cpu, traceDataCache_->GetDataIndex(name));
696 return true;
697 }
IrqHandlerExitEvent(const ArgsMap & args,const BytraceLine & line) const698 bool BytraceEventParser::IrqHandlerExitEvent(const ArgsMap &args, const BytraceLine &line) const
699 {
700 if (args.empty() || args.size() < MIN_IRQ_HANDLER_EXIT_ARGS_COUNT) {
701 TS_LOGD("Failed to parse irq_handler_exit event, no args or args size < 2");
702 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_IRQ_HANDLER_EXIT, STAT_EVENT_DATA_INVALID);
703 return false;
704 }
705 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_IRQ_HANDLER_EXIT, STAT_EVENT_RECEIVED);
706 uint32_t ret = (args.at("ret") == "handled") ? 1 : 0;
707 auto irq = base::StrToInt<uint32_t>(args.at("irq"));
708 streamFilters_->irqFilter_->IrqHandlerExit(line.ts, line.cpu, irq.value(), ret);
709 return true;
710 }
SoftIrqRaiseEvent(const ArgsMap & args,const BytraceLine & line) const711 bool BytraceEventParser::SoftIrqRaiseEvent(const ArgsMap &args, const BytraceLine &line) const
712 {
713 Unused(args);
714 Unused(line);
715 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_SOFTIRQ_RAISE, STAT_EVENT_RECEIVED);
716 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_SOFTIRQ_RAISE, STAT_EVENT_NOTSUPPORTED);
717 return true;
718 }
SoftIrqEntryEvent(const ArgsMap & args,const BytraceLine & line) const719 bool BytraceEventParser::SoftIrqEntryEvent(const ArgsMap &args, const BytraceLine &line) const
720 {
721 if (args.empty() || args.size() < MIN_SOFTIRQ_ENTRY_ARGS_COUNT) {
722 TS_LOGD("Failed to parse softirq_entry event, no args or args size < 2");
723 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SOFTIRQ_ENTRY, STAT_EVENT_DATA_INVALID);
724 return false;
725 }
726 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_SOFTIRQ_ENTRY, STAT_EVENT_RECEIVED);
727 auto vec = base::StrToInt<uint32_t>(args.at("vec"));
728 streamFilters_->irqFilter_->SoftIrqEntry(line.ts, line.cpu, vec.value());
729 return true;
730 }
SoftIrqExitEvent(const ArgsMap & args,const BytraceLine & line) const731 bool BytraceEventParser::SoftIrqExitEvent(const ArgsMap &args, const BytraceLine &line) const
732 {
733 if (args.empty() || args.size() < MIN_SOFTIRQ_EXIT_ARGS_COUNT) {
734 TS_LOGD("Failed to parse softirq_exit event, no args or args size < 2");
735 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SOFTIRQ_EXIT, STAT_EVENT_DATA_INVALID);
736 return false;
737 }
738 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_SOFTIRQ_EXIT, STAT_EVENT_RECEIVED);
739 auto vec = base::StrToInt<uint32_t>(args.at("vec"));
740 streamFilters_->irqFilter_->SoftIrqExit(line.ts, line.cpu, vec.value());
741 return true;
742 }
DmaFenceEvent(const ArgsMap & args,const BytraceLine & line) const743 bool BytraceEventParser::DmaFenceEvent(const ArgsMap &args, const BytraceLine &line) const
744 {
745 if (args.empty() || args.size() < MIN_DMA_FENCE_ARGS_COUNT) {
746 TS_LOGD("Failed to dma fence event,no args or args size <4");
747 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_DMA_FENCE, STAT_EVENT_DATA_INVALID);
748 return false;
749 }
750 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_DMA_FENCE, STAT_EVENT_RECEIVED);
751 auto driverStr = std::string_view(args.at("driver"));
752 auto timelineStr = std::string_view(args.at("timeline"));
753 auto context = base::StrToInt<uint32_t>(args.at("context"));
754 auto seqno = base::StrToInt<uint32_t>(args.at("seqno"));
755 if (timelineStr.empty() || !(context.has_value()) || !(seqno.has_value())) {
756 TS_LOGD("Failed to dma fence event,timelineStr or context or seqno is empty");
757 return false;
758 }
759 DmaFenceRow dmaFenceRow = {line.ts,
760 0,
761 traceDataCache_->GetDataIndex(line.eventName),
762 traceDataCache_->GetDataIndex(driverStr),
763 traceDataCache_->GetDataIndex(timelineStr),
764 context.value(),
765 seqno.value()};
766 streamFilters_->sliceFilter_->DmaFence(dmaFenceRow);
767 return true;
768 }
BinderTransaction(const ArgsMap & args,const BytraceLine & line) const769 bool BytraceEventParser::BinderTransaction(const ArgsMap &args, const BytraceLine &line) const
770 {
771 if (args.empty() || args.size() < MIN_BINDER_TRANSACTION_ARGS_COUNT) {
772 TS_LOGD("Failed to parse binder_transaction event, no args or args size < 7");
773 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_BINDER_TRANSACTION, STAT_EVENT_DATA_INVALID);
774 return false;
775 }
776 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_BINDER_TRANSACTION, STAT_EVENT_RECEIVED);
777 auto transactionId = base::StrToInt<int64_t>(args.at("transaction"));
778 auto destNode = base::StrToInt<uint32_t>(args.at("dest_node"));
779 auto destProc = base::StrToInt<uint32_t>(args.at("dest_proc"));
780 auto destThread = base::StrToInt<uint32_t>(args.at("dest_thread"));
781 auto isReply = base::StrToInt<uint32_t>(args.at("reply"));
782 auto flags = base::StrToInt<uint32_t>(args.at("flags"), base::INTEGER_RADIX_TYPE_HEX);
783 auto codeStr = base::StrToInt<uint32_t>(args.at("code"), base::INTEGER_RADIX_TYPE_HEX);
784 TS_LOGD("ts:%" PRIu64 ", pid:%u, destNode:%u, destTgid:%u, destTid:%u, transactionId:%" PRIu64
785 ", isReply:%u flags:%u, code:%u",
786 line.ts, line.pid, destNode.value(), destProc.value(), destThread.value(), transactionId.value(),
787 isReply.value(), flags.value(), codeStr.value());
788 streamFilters_->binderFilter_->SendTraction(line.ts, line.pid, transactionId.value(), destNode.value(),
789 destProc.value(), destThread.value(), isReply.value(), flags.value(),
790 codeStr.value());
791 if (streamFilters_->configFilter_->GetSwitchConfig().BinderRunnableConfigEnabled() && transactionId.has_value() &&
792 flags.has_value() && !streamFilters_->binderFilter_->IsAsync(flags.value())) {
793 streamFilters_->cpuFilter_->InsertRunnableBinderEvent(transactionId.value(),
794 streamFilters_->processFilter_->GetInternalTid(line.pid));
795 }
796 return true;
797 }
BinderTransactionReceived(const ArgsMap & args,const BytraceLine & line) const798 bool BytraceEventParser::BinderTransactionReceived(const ArgsMap &args, const BytraceLine &line) const
799 {
800 if (args.empty() || args.size() < MIN_BINDER_TRANSACTION_RECEIVED_ARGS_COUNT) {
801 TS_LOGD("Failed to parse binder_transaction_received event, no args or args size < 1");
802 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_BINDER_TRANSACTION_RECEIVED, STAT_EVENT_DATA_INVALID);
803 return false;
804 }
805 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_BINDER_TRANSACTION_RECEIVED, STAT_EVENT_RECEIVED);
806 auto transactionId = base::StrToInt<int64_t>(args.at("transaction"));
807 streamFilters_->binderFilter_->ReceiveTraction(line.ts, line.pid, transactionId.value());
808 if (streamFilters_->configFilter_->GetSwitchConfig().BinderRunnableConfigEnabled() && transactionId.has_value()) {
809 streamFilters_->cpuFilter_->InsertRunnableBinderRecvEvent(
810 transactionId.value(), streamFilters_->processFilter_->GetInternalTid(line.pid));
811 }
812 TS_LOGD("ts:%" PRIu64 ", pid:%u, transactionId:%" PRIu64 "", line.ts, line.pid, transactionId.value());
813 return true;
814 }
BinderTransactionAllocBufEvent(const ArgsMap & args,const BytraceLine & line) const815 bool BytraceEventParser::BinderTransactionAllocBufEvent(const ArgsMap &args, const BytraceLine &line) const
816 {
817 if (args.empty() || args.size() < MIN_BINDER_TRANSACTION_ALLOC_BUF_ARGS_COUNT) {
818 TS_LOGD("Failed to parse binder_transaction_alloc_buf event, no args or args size < 3");
819 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_BINDER_TRANSACTION_ALLOC_BUF, STAT_EVENT_DATA_INVALID);
820 return false;
821 }
822 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_BINDER_TRANSACTION_ALLOC_BUF, STAT_EVENT_RECEIVED);
823 auto dataSize = base::StrToInt<uint64_t>(args.at("data_size"));
824 auto offsetsSize = base::StrToInt<uint64_t>(args.at("offsets_size"));
825 streamFilters_->binderFilter_->TransactionAllocBuf(line.ts, line.pid, dataSize.value(), offsetsSize.value());
826 TS_LOGD("dataSize:%" PRIu64 ", offsetSize:%" PRIu64 "", dataSize.value(), offsetsSize.value());
827 return true;
828 }
ParseDataItem(const BytraceLine & line)829 void BytraceEventParser::ParseDataItem(const BytraceLine &line)
830 {
831 eventList_.emplace_back(std::make_unique<EventInfo>(line.ts, line));
832 size_t maxQueue = 2;
833 if (eventList_.size() < maxBuffSize_ * maxQueue) {
834 return;
835 }
836 auto cmp = [](const std::unique_ptr<EventInfo> &a, const std::unique_ptr<EventInfo> &b) {
837 return a->eventTimestamp < b->eventTimestamp;
838 };
839 std::stable_sort(eventList_.begin(), eventList_.end(), cmp);
840 auto endOfList = eventList_.begin() + maxBuffSize_;
841 for (auto itor = eventList_.begin(); itor != endOfList; itor++) {
842 EventInfo *event = itor->get();
843 BeginFilterEvents(event);
844 itor->reset();
845 }
846 eventList_.erase(eventList_.begin(), endOfList);
847 }
848
GetDataSegArgs(const BytraceLine & bufLine,ArgsMap & args) const849 void BytraceEventParser::GetDataSegArgs(const BytraceLine &bufLine, ArgsMap &args) const
850 {
851 int32_t len = bufLine.argsStr.size();
852 int32_t first = -1;
853 int32_t second = -1;
854 for (int32_t i = 0; i < len; i++) {
855 if (bufLine.argsStr[i] == ' ') {
856 if (first == -1) {
857 continue;
858 }
859 if (second != -1) {
860 args.emplace(bufLine.argsStr.substr(first, second - 1 - first),
861 bufLine.argsStr.substr(second, i - second));
862 second = -1;
863 } else {
864 args.emplace("name", bufLine.argsStr.substr(first, i - first));
865 }
866 first = -1;
867 } else {
868 if (first == -1) {
869 first = i;
870 }
871 if (bufLine.argsStr[i] == '=' && second == -1) {
872 second = i + 1;
873 }
874 }
875 }
876 if (second != -1) {
877 args.emplace(bufLine.argsStr.substr(first, second - 1 - first), bufLine.argsStr.substr(second, len - second));
878 return;
879 }
880 if (first != -1) {
881 args.emplace("name", bufLine.argsStr.substr(first, len - first));
882 }
883 }
884
FilterAllEvents()885 void BytraceEventParser::FilterAllEvents()
886 {
887 auto cmp = [](const std::unique_ptr<EventInfo> &a, const std::unique_ptr<EventInfo> &b) {
888 return a->eventTimestamp < b->eventTimestamp;
889 };
890 std::stable_sort(eventList_.begin(), eventList_.end(), cmp);
891 while (eventList_.size()) {
892 int32_t size = std::min(maxBuffSize_, eventList_.size());
893 auto endOfList = eventList_.begin() + size;
894 for (auto itor = eventList_.begin(); itor != endOfList; itor++) {
895 EventInfo *event = itor->get();
896 BeginFilterEvents(event);
897 itor->reset();
898 }
899 eventList_.erase(eventList_.begin(), endOfList);
900 }
901 eventList_.clear();
902 streamFilters_->cpuFilter_->Finish();
903 traceDataCache_->dataDict_.Finish();
904 traceDataCache_->UpdataZeroThreadInfo();
905 if (streamFilters_->configFilter_->GetSwitchConfig().AppConfigEnabled()) {
906 streamFilters_->appStartupFilter_->FilterAllAPPStartupData();
907 }
908 traceDataCache_->GetThreadStateData()->SortAllRowByTs();
909 }
910
BeginFilterEvents(EventInfo * event)911 void BytraceEventParser::BeginFilterEvents(EventInfo *event)
912 {
913 auto it = eventToFunctionMap_.find(event->line.eventName);
914 if (it != eventToFunctionMap_.end()) {
915 uint32_t tgid = event->line.tgid;
916 ArgsMap args;
917 GetDataSegArgs(event->line, args);
918 if (tgid) {
919 streamFilters_->processFilter_->UpdateOrCreateThreadWithPidAndName(event->line.pid, tgid, event->line.task);
920 } else {
921 // When tgid is zero, only use tid create thread
922 streamFilters_->processFilter_->GetOrCreateThreadWithPid(event->line.pid, tgid);
923 }
924 if (it->second(args, event->line)) {
925 traceDataCache_->UpdateTraceTime(event->line.ts);
926 }
927 } else {
928 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_OTHER, STAT_EVENT_NOTSUPPORTED);
929 TS_LOGD("UnRecognizable event name:%s", event->line.eventName.c_str());
930 }
931 }
932
Clear()933 void BytraceEventParser::Clear()
934 {
935 const_cast<TraceStreamerFilters *>(streamFilters_)->FilterClear();
936 printEventParser_.Finish();
937 }
938 } // namespace TraceStreamer
939 } // namespace SysTuning
940