• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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