• 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 "cpu_detail_parser.h"
17 #include <cinttypes>
18 #include <string_view>
19 #include "app_start_filter.h"
20 #include "binder_filter.h"
21 #include "common_types.h"
22 #include "cpu_filter.h"
23 #include "irq_filter.h"
24 #include "measure_filter.h"
25 #include "process_filter.h"
26 #include "slice_filter.h"
27 #include "stat_filter.h"
28 #include "system_event_measure_filter.h"
29 #include "ftrace_event_processor.h"
30 #include "string_to_numerical.h"
31 
32 namespace SysTuning {
33 namespace TraceStreamer {
CpuDetailParser(TraceDataCache * dataCache,const TraceStreamerFilters * ctx)34 CpuDetailParser::CpuDetailParser(TraceDataCache *dataCache, const TraceStreamerFilters *ctx)
35     : streamFilters_(ctx), traceDataCache_(dataCache), printEventParser_(dataCache, ctx)
36 {
37     standAloneCpuEventList_.resize(CPU_CORE_MAX);
38     printEventParser_.SetTraceType(TRACE_FILETYPE_RAW_TRACE);
39     printEventParser_.SetTraceClockId(clock_);
40     eventToFunctionMap_ = {
41         {config_.eventNameMap_.at(TRACE_EVENT_TASK_RENAME),
42          std::bind(&CpuDetailParser::TaskRenameEvent, this, std::placeholders::_1)},
43         {config_.eventNameMap_.at(TRACE_EVENT_TASK_NEWTASK),
44          std::bind(&CpuDetailParser::TaskNewtaskEvent, this, std::placeholders::_1)},
45         {config_.eventNameMap_.at(TRACE_EVENT_SCHED_SWITCH),
46          std::bind(&CpuDetailParser::SchedSwitchEvent, this, std::placeholders::_1)},
47         {config_.eventNameMap_.at(TRACE_EVENT_SCHED_BLOCKED_REASON),
48          std::bind(&CpuDetailParser::SchedBlockReasonEvent, this, std::placeholders::_1)},
49         {config_.eventNameMap_.at(TRACE_EVENT_SCHED_WAKEUP),
50          std::bind(&CpuDetailParser::SchedWakeupEvent, this, std::placeholders::_1)},
51         {config_.eventNameMap_.at(TRACE_EVENT_SCHED_WAKING),
52          std::bind(&CpuDetailParser::SchedWakingEvent, this, std::placeholders::_1)},
53         {config_.eventNameMap_.at(TRACE_EVENT_SCHED_WAKEUP_NEW),
54          std::bind(&CpuDetailParser::SchedWakeupNewEvent, this, std::placeholders::_1)},
55         {config_.eventNameMap_.at(TRACE_EVENT_PROCESS_EXIT),
56          std::bind(&CpuDetailParser::ProcessExitEvent, this, std::placeholders::_1)},
57         {config_.eventNameMap_.at(TRACE_EVENT_IPI_ENTRY),
58          std::bind(&CpuDetailParser::IpiHandlerEntryEvent, this, std::placeholders::_1)},
59         {config_.eventNameMap_.at(TRACE_EVENT_IPI_EXIT),
60          std::bind(&CpuDetailParser::IpiHandlerExitEvent, this, std::placeholders::_1)},
61         {config_.eventNameMap_.at(TRACE_EVENT_PROCESS_FREE),
62          std::bind(&CpuDetailParser::ProcessFreeEvent, this, std::placeholders::_1)},
63         {config_.eventNameMap_.at(TRACE_EVENT_SUSPEND_RESUME),
64          std::bind(&CpuDetailParser::SuspendResumeEvent, this, std::placeholders::_1)},
65         {config_.eventNameMap_.at(TRACE_EVENT_TRACING_MARK_WRITE),
66          std::bind(&CpuDetailParser::ParseTracingMarkWriteOrPrintEvent, this, std::placeholders::_1)},
67     };
68     InterruptEventInitialization();
69     ClockEventInitialization();
70     CpuEventInitialization();
71     LockEventInitialization();
72     BinderEventInitialization();
73     StackEventsInitialization();
74     VoltageEventInitialization();
75 }
76 
InterruptEventInitialization()77 void CpuDetailParser::InterruptEventInitialization()
78 {
79     eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_IRQ_HANDLER_ENTRY),
80                                 std::bind(&CpuDetailParser::IrqHandlerEntryEvent, this, std::placeholders::_1));
81     eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_IRQ_HANDLER_EXIT),
82                                 std::bind(&CpuDetailParser::IrqHandlerExitEvent, this, std::placeholders::_1));
83     eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_SOFTIRQ_RAISE),
84                                 std::bind(&CpuDetailParser::SoftIrqRaiseEvent, this, std::placeholders::_1));
85     eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_SOFTIRQ_ENTRY),
86                                 std::bind(&CpuDetailParser::SoftIrqEntryEvent, this, std::placeholders::_1));
87     eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_SOFTIRQ_EXIT),
88                                 std::bind(&CpuDetailParser::SoftIrqExitEvent, this, std::placeholders::_1));
89 }
ClockEventInitialization()90 void CpuDetailParser::ClockEventInitialization()
91 {
92     eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_CLOCK_SET_RATE),
93                                 std::bind(&CpuDetailParser::SetRateEvent, this, std::placeholders::_1));
94     eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_CLOCK_ENABLE),
95                                 std::bind(&CpuDetailParser::ClockEnableEvent, this, std::placeholders::_1));
96     eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_CLOCK_DISABLE),
97                                 std::bind(&CpuDetailParser::ClockDisableEvent, this, std::placeholders::_1));
98 }
CpuEventInitialization()99 void CpuDetailParser::CpuEventInitialization()
100 {
101     eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_CPU_IDLE),
102                                 std::bind(&CpuDetailParser::CpuIdleEvent, this, std::placeholders::_1));
103     eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_CPU_FREQUENCY),
104                                 std::bind(&CpuDetailParser::CpuFrequencyEvent, this, std::placeholders::_1));
105     eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_CPU_FREQUENCY_LIMITS),
106                                 std::bind(&CpuDetailParser::CpuFrequencyLimitsEvent, this, std::placeholders::_1));
107 }
LockEventInitialization()108 void CpuDetailParser::LockEventInitialization()
109 {
110     eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_BINDER_TRANSACTION_LOCK),
111                                 std::bind(&CpuDetailParser::BinderTractionLockEvent, this, std::placeholders::_1));
112     eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_BINDER_TRANSACTION_LOCKED),
113                                 std::bind(&CpuDetailParser::BinderTractionLockedEvent, this, std::placeholders::_1));
114     eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_BINDER_TRANSACTION_UNLOCK),
115                                 std::bind(&CpuDetailParser::BinderTractionUnLockEvent, this, std::placeholders::_1));
116 }
BinderEventInitialization()117 void CpuDetailParser::BinderEventInitialization()
118 {
119     eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_BINDER_TRANSACTION),
120                                 std::bind(&CpuDetailParser::BinderTractionEvent, this, std::placeholders::_1));
121     eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_BINDER_TRANSACTION_RECEIVED),
122                                 std::bind(&CpuDetailParser::BinderTractionReceivedEvent, this, std::placeholders::_1));
123     eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_BINDER_TRANSACTION_ALLOC_BUF),
124                                 std::bind(&CpuDetailParser::BinderTractionAllocBufEvent, this, std::placeholders::_1));
125 }
StackEventsInitialization()126 void CpuDetailParser::StackEventsInitialization()
127 {
128     eventToFunctionMap_.emplace(
129         config_.eventNameMap_.at(TRACE_EVENT_PRINT),
130         std::bind(&CpuDetailParser::ParseTracingMarkWriteOrPrintEvent, this, std::placeholders::_1));
131     eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_WORKQUEUE_EXECUTE_START),
132                                 std::bind(&CpuDetailParser::WorkqueueExecuteStartEvent, this, std::placeholders::_1));
133     eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_WORKQUEUE_EXECUTE_END),
134                                 std::bind(&CpuDetailParser::WorkqueueExecuteEndEvent, this, std::placeholders::_1));
135 }
VoltageEventInitialization()136 void CpuDetailParser::VoltageEventInitialization()
137 {
138     eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_REGULATOR_SET_VOLTAGE),
139                                 std::bind(&CpuDetailParser::RegulatorSetVoltageEvent, this, std::placeholders::_1));
140     eventToFunctionMap_.emplace(
141         config_.eventNameMap_.at(TRACE_EVENT_REGULATOR_SET_VOLTAGE_COMPLETE),
142         std::bind(&CpuDetailParser::RegulatorSetVoltageCompleteEvent, this, std::placeholders::_1));
143     eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_REGULATOR_DISABLE),
144                                 std::bind(&CpuDetailParser::RegulatorDisableEvent, this, std::placeholders::_1));
145     eventToFunctionMap_.emplace(
146         config_.eventNameMap_.at(TRACE_EVENT_REGULATOR_DISABLE_COMPLETE),
147         std::bind(&CpuDetailParser::RegulatorDisableCompleteEvent, this, std::placeholders::_1));
148 }
EventAppend(std::shared_ptr<RawTraceEventInfo> event)149 void CpuDetailParser::EventAppend(std::shared_ptr<RawTraceEventInfo> event)
150 {
151     standAloneCpuEventList_[event->cpuId].emplace(std::move(event));
152     curRawTraceEventNum_++;
153 }
ResizeStandAloneCpuEventList(uint32_t cpuNum)154 void CpuDetailParser::ResizeStandAloneCpuEventList(uint32_t cpuNum)
155 {
156     cpuCoreMax_ = cpuNum;
157     standAloneCpuEventList_.resize(cpuNum);
158 }
SortStandAloneCpuEventList(bool isFinished)159 bool CpuDetailParser::SortStandAloneCpuEventList(bool isFinished)
160 {
161     while (curRawTraceEventNum_ > 0) {
162         uint32_t minTimeCpuId = INVALID_UINT32;
163         uint64_t curMinTs = INVALID_UINT64;
164         // select a min time from one of the cpu caches
165         for (int curCpuId = 0; curCpuId < cpuCoreMax_; curCpuId++) {
166             if (!isFinished && standAloneCpuEventList_[curCpuId].empty()) {
167                 return true;
168             } else if (standAloneCpuEventList_[curCpuId].empty()) {
169                 continue;
170             }
171             uint64_t ts = standAloneCpuEventList_[curCpuId].front()->msgPtr->timestamp();
172             if (ts < curMinTs) {
173                 curMinTs = ts;
174                 minTimeCpuId = curCpuId;
175             }
176         }
177         if (INVALID_UINT32 == minTimeCpuId) {
178             break;
179         }
180         rawTraceEventList_.emplace_back(std::move(standAloneCpuEventList_[minTimeCpuId].front()));
181         standAloneCpuEventList_[minTimeCpuId].pop();
182         curRawTraceEventNum_--;
183         if (!isFinished && standAloneCpuEventList_[minTimeCpuId].empty()) {
184             break;
185         }
186     }
187     return true;
188 }
UpdateCpuOverwrite(FtraceCpuDetailMsg & cpuDetail)189 void CpuDetailParser::UpdateCpuOverwrite(FtraceCpuDetailMsg &cpuDetail)
190 {
191     if (cpuDetail.overwrite()) {
192         if (!lastOverwrite_) {
193             lastOverwrite_ = cpuDetail.overwrite();
194         }
195         if (lastOverwrite_ != cpuDetail.overwrite()) {
196             TS_LOGW("lost events:%" PRIu64 "", cpuDetail.overwrite() - lastOverwrite_);
197             lastOverwrite_ = cpuDetail.overwrite();
198         }
199         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_OTHER, STAT_EVENT_DATA_LOST);
200     }
201 }
FilterAllEvents(FtraceCpuDetailMsg & cpuDetail,bool isFinished)202 bool CpuDetailParser::FilterAllEvents(FtraceCpuDetailMsg &cpuDetail, bool isFinished)
203 {
204     UpdateCpuOverwrite(cpuDetail);
205     SortStandAloneCpuEventList(isFinished);
206     TS_CHECK_TRUE_RET(!rawTraceEventList_.empty(), true);
207     traceDataCache_->UpdateTraceTime(rawTraceEventList_.front()->msgPtr->timestamp());
208     traceDataCache_->UpdateTraceTime(rawTraceEventList_.back()->msgPtr->timestamp());
209     for (size_t i = 0; i < rawTraceEventList_.size(); i++) {
210         eventPid_ = rawTraceEventList_[i]->msgPtr->tgid();
211         if (eventPid_ != INVALID_INT32) {
212             streamFilters_->processFilter_->GetOrCreateThreadWithPid(eventPid_, eventPid_);
213         }
214         DealEvent(*rawTraceEventList_[i].get());
215         rawTraceEventList_[i].reset();
216     }
217     TS_LOGI("deal rawTraceEventList_.size=%zu", rawTraceEventList_.size());
218     rawTraceEventList_.clear();
219     cpuDetail.Clear();
220     return true;
221 }
Clear()222 void CpuDetailParser::Clear()
223 {
224     cpuCoreMax_ = CPU_CORE_MAX;
225     const_cast<TraceStreamerFilters *>(streamFilters_)->FilterClear();
226     streamFilters_->sysEventMemMeasureFilter_->Clear();
227     streamFilters_->sysEventVMemMeasureFilter_->Clear();
228     printEventParser_.Finish();
229 }
FinishCpuDetailParser()230 void CpuDetailParser::FinishCpuDetailParser()
231 {
232     streamFilters_->cpuFilter_->Finish();
233     traceDataCache_->dataDict_.Finish();
234     traceDataCache_->UpdataZeroThreadInfo();
235     if (traceDataCache_->AppStartTraceEnabled()) {
236         streamFilters_->appStartupFilter_->FilterAllAPPStartupData();
237     }
238     Clear();
239     traceDataCache_->GetThreadStateData()->SortAllRowByTs();
240 }
DealEvent(const RawTraceEventInfo & event)241 void CpuDetailParser::DealEvent(const RawTraceEventInfo &event)
242 {
243     eventTid_ = event.msgPtr->common_fields().pid();
244     if (eventTid_ != INVALID_INT32) {
245         streamFilters_->processFilter_->UpdateOrCreateThread(event.msgPtr->timestamp(), eventTid_);
246     }
247     if (eventTid_ != INVALID_INT32 && eventPid_ != INVALID_INT32) {
248         streamFilters_->processFilter_->GetOrCreateThreadWithPid(eventTid_, eventPid_);
249     }
250     const auto &eventName = FtraceEventProcessor::GetInstance().GetEventNameById(event.eventId);
251     auto iter = eventToFunctionMap_.find(eventName);
252     if (iter != eventToFunctionMap_.end()) {
253         iter->second(event);
254     } else {
255         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_OTHER, STAT_EVENT_NOTSUPPORTED);
256     }
257 }
SchedSwitchEvent(const RawTraceEventInfo & event)258 bool CpuDetailParser::SchedSwitchEvent(const RawTraceEventInfo &event)
259 {
260     auto schedSwitchMsg = event.msgPtr->sched_switch_format();
261     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_SWITCH, STAT_EVENT_RECEIVED);
262 
263     auto schedSwitchPrevState = schedSwitchMsg.prev_state();
264     auto nextInternalTid = streamFilters_->processFilter_->UpdateOrCreateThreadWithName(
265         event.msgPtr->timestamp(), schedSwitchMsg.next_pid(), schedSwitchMsg.next_comm());
266     auto uprevtid = streamFilters_->processFilter_->UpdateOrCreateThreadWithName(
267         event.msgPtr->timestamp(), schedSwitchMsg.prev_pid(), schedSwitchMsg.prev_comm());
268 
269     streamFilters_->cpuFilter_->InsertSwitchEvent(event.msgPtr->timestamp(), event.cpuId, uprevtid,
270                                                   schedSwitchMsg.prev_prio(), schedSwitchPrevState, nextInternalTid,
271                                                   schedSwitchMsg.next_prio(), INVALID_DATAINDEX);
272     return true;
273 }
SchedBlockReasonEvent(const RawTraceEventInfo & event)274 bool CpuDetailParser::SchedBlockReasonEvent(const RawTraceEventInfo &event)
275 {
276     auto reasonMsg = event.msgPtr->sched_blocked_reason_format();
277     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_BLOCKED_REASON, STAT_EVENT_RECEIVED);
278     auto caller = traceDataCache_->GetDataIndex(
279         std::string_view("0x" + SysTuning::base::number(reasonMsg.caller(), SysTuning::base::INTEGER_RADIX_TYPE_HEX)));
280     auto itid = streamFilters_->processFilter_->UpdateOrCreateThread(event.msgPtr->timestamp(), reasonMsg.pid());
281     if (streamFilters_->cpuFilter_->InsertBlockedReasonEvent(event.cpuId, itid, reasonMsg.io_wait(), caller,
282                                                              INVALID_UINT32)) {
283         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_BLOCKED_REASON, STAT_EVENT_RECEIVED);
284     } else {
285         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_BLOCKED_REASON, STAT_EVENT_NOTMATCH);
286     }
287     return true;
288 }
SchedWakeupEvent(const RawTraceEventInfo & event) const289 bool CpuDetailParser::SchedWakeupEvent(const RawTraceEventInfo &event) const
290 {
291     auto wakeupMsg = event.msgPtr->sched_wakeup_format();
292     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_WAKEUP, STAT_EVENT_RECEIVED);
293     auto instants = traceDataCache_->GetInstantsData();
294 
295     InternalTid internalTid =
296         streamFilters_->processFilter_->UpdateOrCreateThread(event.msgPtr->timestamp(), wakeupMsg.pid());
297     InternalTid wakeupFromPid =
298         streamFilters_->processFilter_->UpdateOrCreateThread(event.msgPtr->timestamp(), eventTid_);
299     instants->AppendInstantEventData(event.msgPtr->timestamp(), schedWakeupIndex_, internalTid, wakeupFromPid);
300     streamFilters_->cpuFilter_->InsertWakeupEvent(event.msgPtr->timestamp(), internalTid);
301     traceDataCache_->GetRawData()->AppendRawData(event.msgPtr->timestamp(), RAW_SCHED_WAKEUP, wakeupMsg.target_cpu(),
302                                                  internalTid);
303     return true;
304 }
SchedWakingEvent(const RawTraceEventInfo & event) const305 bool CpuDetailParser::SchedWakingEvent(const RawTraceEventInfo &event) const
306 {
307     auto wakeingMsg = event.msgPtr->sched_waking_format();
308     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_WAKING, STAT_EVENT_RECEIVED);
309     auto instants = traceDataCache_->GetInstantsData();
310     auto internalTid =
311         streamFilters_->processFilter_->UpdateOrCreateThread(event.msgPtr->timestamp(), wakeingMsg.pid());
312     auto wakeupFromPid = streamFilters_->processFilter_->UpdateOrCreateThread(event.msgPtr->timestamp(), eventTid_);
313     streamFilters_->cpuFilter_->InsertWakeupEvent(event.msgPtr->timestamp(), internalTid, true);
314     instants->AppendInstantEventData(event.msgPtr->timestamp(), schedWakingIndex_, internalTid, wakeupFromPid);
315     traceDataCache_->GetRawData()->AppendRawData(event.msgPtr->timestamp(), RAW_SCHED_WAKING, wakeingMsg.target_cpu(),
316                                                  wakeupFromPid);
317     return true;
318 }
SchedWakeupNewEvent(const RawTraceEventInfo & event) const319 bool CpuDetailParser::SchedWakeupNewEvent(const RawTraceEventInfo &event) const
320 {
321     auto wakeupNewMsg = event.msgPtr->sched_wakeup_new_format();
322     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_WAKEUP_NEW, STAT_EVENT_RECEIVED);
323     auto instants = traceDataCache_->GetInstantsData();
324     auto internalTid =
325         streamFilters_->processFilter_->UpdateOrCreateThread(event.msgPtr->timestamp(), wakeupNewMsg.pid());
326     auto wakeupFromPid = streamFilters_->processFilter_->UpdateOrCreateThread(event.msgPtr->timestamp(), eventTid_);
327     instants->AppendInstantEventData(event.msgPtr->timestamp(), schedWakeupNewIndex_, internalTid, wakeupFromPid);
328     streamFilters_->cpuFilter_->InsertWakeupEvent(event.msgPtr->timestamp(), internalTid);
329     traceDataCache_->GetRawData()->AppendRawData(event.msgPtr->timestamp(), RAW_SCHED_WAKEUP, wakeupNewMsg.target_cpu(),
330                                                  internalTid);
331     return true;
332 }
ProcessExitEvent(const RawTraceEventInfo & event) const333 bool CpuDetailParser::ProcessExitEvent(const RawTraceEventInfo &event) const
334 {
335     auto procExitMsg = event.msgPtr->sched_process_exit_format();
336     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_PROCESS_EXIT, STAT_EVENT_RECEIVED);
337     uint32_t pidValue = procExitMsg.pid();
338     // The tostdstring() here cannot use temporary variables, which will cause occasional garbled characters under wasm
339     auto iTid = streamFilters_->processFilter_->UpdateOrCreateThreadWithName(event.msgPtr->timestamp(), pidValue,
340                                                                              procExitMsg.comm());
341     if (streamFilters_->cpuFilter_->InsertProcessExitEvent(event.msgPtr->timestamp(), event.cpuId, iTid)) {
342         return true;
343     } else {
344         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_PROCESS_EXIT, STAT_EVENT_NOTMATCH);
345         return false;
346     }
347 }
ProcessFreeEvent(const RawTraceEventInfo & event) const348 bool CpuDetailParser::ProcessFreeEvent(const RawTraceEventInfo &event) const
349 {
350     auto procFreeMsg = event.msgPtr->sched_process_exit_format();
351     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_PROCESS_FREE, STAT_EVENT_RECEIVED);
352     uint32_t pidValue = procFreeMsg.pid();
353     // The tostdstring() here cannot use temporary variables, which will cause occasional garbled characters under wasm
354     auto iTid = streamFilters_->processFilter_->UpdateOrCreateThreadWithName(event.msgPtr->timestamp(), pidValue,
355                                                                              procFreeMsg.comm());
356     if (streamFilters_->cpuFilter_->InsertProcessFreeEvent(event.msgPtr->timestamp(), iTid)) {
357         return true;
358     } else {
359         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_PROCESS_FREE, STAT_EVENT_NOTMATCH);
360         return false;
361     }
362 }
BinderTractionEvent(const RawTraceEventInfo & event) const363 bool CpuDetailParser::BinderTractionEvent(const RawTraceEventInfo &event) const
364 {
365     auto transactionMsg = event.msgPtr->binder_transaction_format();
366     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_BINDER_TRANSACTION, STAT_EVENT_RECEIVED);
367     int32_t destNode = transactionMsg.target_node();
368     int32_t destTgid = transactionMsg.to_proc();
369     int32_t destTid = transactionMsg.to_thread();
370     int32_t transactionId = transactionMsg.debug_id();
371     bool isReply = transactionMsg.reply() == 1;
372     uint32_t flags = transactionMsg.flags();
373     TS_LOGD("destNode:%d, destTgid:%d, destTid:%d, transactionId:%d, isReply:%d flags:%d, code:%d", destNode, destTgid,
374             destTid, transactionId, isReply, flags, transactionMsg.code());
375     streamFilters_->binderFilter_->SendTraction(event.msgPtr->timestamp(), eventTid_, transactionId, destNode, destTgid,
376                                                 destTid, isReply, flags, transactionMsg.code());
377     return true;
378 }
BinderTractionAllocBufEvent(const RawTraceEventInfo & event) const379 bool CpuDetailParser::BinderTractionAllocBufEvent(const RawTraceEventInfo &event) const
380 {
381     auto allocBufMsg = event.msgPtr->binder_transaction_alloc_buf_format();
382     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_BINDER_TRANSACTION_ALLOC_BUF, STAT_EVENT_RECEIVED);
383     streamFilters_->binderFilter_->TransactionAllocBuf(event.msgPtr->timestamp(), eventTid_, allocBufMsg.data_size(),
384                                                        allocBufMsg.offsets_size());
385     TS_LOGD("dataSize:%" PRIu64 ", offsetSize:%" PRIu64 "", allocBufMsg.data_size(), allocBufMsg.offsets_size());
386     return true;
387 }
BinderTractionReceivedEvent(const RawTraceEventInfo & event) const388 bool CpuDetailParser::BinderTractionReceivedEvent(const RawTraceEventInfo &event) const
389 {
390     auto recvedMsg = event.msgPtr->binder_transaction_received_format();
391     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_BINDER_TRANSACTION_RECEIVED, STAT_EVENT_RECEIVED);
392     int32_t transactionId = recvedMsg.debug_id();
393     streamFilters_->binderFilter_->ReceiveTraction(event.msgPtr->timestamp(), eventTid_, transactionId);
394     TS_LOGD("transactionId:%d", transactionId);
395     return true;
396 }
BinderTractionLockEvent(const RawTraceEventInfo & event) const397 bool CpuDetailParser::BinderTractionLockEvent(const RawTraceEventInfo &event) const
398 {
399     auto lockMsg = event.msgPtr->binder_lock_format();
400     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_BINDER_TRANSACTION_LOCK, STAT_EVENT_RECEIVED);
401     streamFilters_->binderFilter_->TractionLock(event.msgPtr->timestamp(), eventTid_, lockMsg.tag());
402     TS_LOGD("tag:%s", lockMsg.tag().c_str());
403     return true;
404 }
BinderTractionLockedEvent(const RawTraceEventInfo & event) const405 bool CpuDetailParser::BinderTractionLockedEvent(const RawTraceEventInfo &event) const
406 {
407     auto lockedMsg = event.msgPtr->binder_locked_format();
408     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_BINDER_TRANSACTION_LOCKED, STAT_EVENT_RECEIVED);
409     streamFilters_->binderFilter_->TractionLocked(event.msgPtr->timestamp(), eventTid_, lockedMsg.tag());
410     return true;
411 }
BinderTractionUnLockEvent(const RawTraceEventInfo & event) const412 bool CpuDetailParser::BinderTractionUnLockEvent(const RawTraceEventInfo &event) const
413 {
414     auto unlockMsg = event.msgPtr->binder_unlock_format();
415     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_BINDER_TRANSACTION_UNLOCK, STAT_EVENT_RECEIVED);
416     streamFilters_->binderFilter_->TractionUnlock(event.msgPtr->timestamp(), eventTid_, unlockMsg.tag());
417     return true;
418 }
TaskRenameEvent(const RawTraceEventInfo & event) const419 bool CpuDetailParser::TaskRenameEvent(const RawTraceEventInfo &event) const
420 {
421     auto renameMsg = event.msgPtr->task_rename_format();
422     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_TASK_RENAME, STAT_EVENT_RECEIVED);
423     streamFilters_->processFilter_->UpdateOrCreateThreadWithName(event.msgPtr->timestamp(), renameMsg.pid(),
424                                                                  renameMsg.newcomm());
425     return true;
426 }
TaskNewtaskEvent(const RawTraceEventInfo & event) const427 bool CpuDetailParser::TaskNewtaskEvent(const RawTraceEventInfo &event) const
428 {
429     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_TASK_NEWTASK, STAT_EVENT_RECEIVED);
430     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_TASK_NEWTASK, STAT_EVENT_NOTSUPPORTED);
431     return true;
432 }
ParseTracingMarkWriteOrPrintEvent(const RawTraceEventInfo & event)433 bool CpuDetailParser::ParseTracingMarkWriteOrPrintEvent(const RawTraceEventInfo &event)
434 {
435     auto printMsg = event.msgPtr->print_format();
436     BytraceLine line;
437     line.tgid = eventPid_;
438     line.pid = eventTid_;
439     line.ts = event.msgPtr->timestamp();
440     printEventParser_.ParsePrintEvent(event.msgPtr->comm(), line.ts, eventTid_, printMsg.buf(), line);
441     return true;
442 }
CpuIdleEvent(const RawTraceEventInfo & event) const443 bool CpuDetailParser::CpuIdleEvent(const RawTraceEventInfo &event) const
444 {
445     auto idleMsg = event.msgPtr->cpu_idle_format();
446     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_IDLE, STAT_EVENT_RECEIVED);
447     std::optional<uint32_t> eventCpu = idleMsg.cpu_id();
448     std::optional<uint64_t> newState = idleMsg.state();
449     if (!eventCpu.has_value()) {
450         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_IDLE, STAT_EVENT_DATA_INVALID);
451         TS_LOGW("Convert event cpu Failed");
452         return false;
453     }
454     if (!newState.has_value()) {
455         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_IDLE, STAT_EVENT_DATA_INVALID);
456         TS_LOGW("Convert event state Failed");
457         return false;
458     }
459 
460     streamFilters_->cpuMeasureFilter_->AppendNewMeasureData(eventCpu.value(), cpuIdleIndex_, event.msgPtr->timestamp(),
461                                                             config_.GetStateValue(newState.value()));
462 
463     // Add cpu_idle event to raw_data_table
464     traceDataCache_->GetRawData()->AppendRawData(event.msgPtr->timestamp(), RAW_CPU_IDLE, eventCpu.value(), 0);
465     return true;
466 }
CpuFrequencyEvent(const RawTraceEventInfo & event) const467 bool CpuDetailParser::CpuFrequencyEvent(const RawTraceEventInfo &event) const
468 {
469     auto frequencyMsg = event.msgPtr->cpu_frequency_format();
470     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_FREQUENCY, STAT_EVENT_RECEIVED);
471     std::optional<uint64_t> newState = frequencyMsg.state();
472     std::optional<uint32_t> eventCpu = frequencyMsg.cpu_id();
473 
474     if (!newState.has_value()) {
475         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_FREQUENCY, STAT_EVENT_DATA_INVALID);
476         TS_LOGW("Convert event state Failed");
477         return false;
478     }
479     if (!eventCpu.has_value()) {
480         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_FREQUENCY, STAT_EVENT_DATA_INVALID);
481         TS_LOGW("Convert event cpu Failed");
482         return false;
483     }
484 
485     streamFilters_->cpuMeasureFilter_->AppendNewMeasureData(eventCpu.value(), cpuFrequencyIndex_,
486                                                             event.msgPtr->timestamp(), newState.value());
487     return true;
488 }
CpuFrequencyLimitsEvent(const RawTraceEventInfo & event) const489 bool CpuDetailParser::CpuFrequencyLimitsEvent(const RawTraceEventInfo &event) const
490 {
491     auto limitsMsg = event.msgPtr->cpu_frequency_limits_format();
492     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_FREQUENCY_LIMITS, STAT_EVENT_RECEIVED);
493     streamFilters_->cpuMeasureFilter_->AppendNewMeasureData(limitsMsg.cpu_id(), cpuFrequencyLimitMaxIndex_,
494                                                             event.msgPtr->timestamp(), limitsMsg.max_freq());
495     streamFilters_->cpuMeasureFilter_->AppendNewMeasureData(limitsMsg.cpu_id(), cpuFrequencyLimitMinIndex_,
496                                                             event.msgPtr->timestamp(), limitsMsg.min_freq());
497     return true;
498 }
SuspendResumeEvent(const RawTraceEventInfo & event) const499 bool CpuDetailParser::SuspendResumeEvent(const RawTraceEventInfo &event) const
500 {
501     auto resumeMsg = event.msgPtr->suspend_resume_format();
502     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SUSPEND_RESUME, STAT_EVENT_RECEIVED);
503     int32_t val = resumeMsg.val();
504     uint32_t start = resumeMsg.start();
505     std::string action = resumeMsg.action();
506     Unused(val);
507     Unused(start);
508     Unused(action);
509     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SUSPEND_RESUME, STAT_EVENT_NOTSUPPORTED);
510     return true;
511 }
WorkqueueExecuteStartEvent(const RawTraceEventInfo & event) const512 bool CpuDetailParser::WorkqueueExecuteStartEvent(const RawTraceEventInfo &event) const
513 {
514     auto executeStartMsg = event.msgPtr->workqueue_execute_start_format();
515     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_WORKQUEUE_EXECUTE_START, STAT_EVENT_RECEIVED);
516     auto funcNameIndex = traceDataCache_->GetSymbolsData()->GetFunc(executeStartMsg.function());
517     size_t result = INVALID_UINT32;
518     if (funcNameIndex == INVALID_UINT64) {
519         std::string addrStr = "0x" + base::number(executeStartMsg.function(), base::INTEGER_RADIX_TYPE_HEX);
520         auto addStrIndex = traceDataCache_->GetDataIndex(addrStr);
521         result = streamFilters_->sliceFilter_->BeginSlice(event.msgPtr->comm(), event.msgPtr->timestamp(), eventPid_,
522                                                           eventPid_, workQueueIndex_, addStrIndex);
523     } else {
524         result = streamFilters_->sliceFilter_->BeginSlice(event.msgPtr->comm(), event.msgPtr->timestamp(), eventPid_,
525                                                           eventPid_, workQueueIndex_, funcNameIndex);
526     }
527 
528     traceDataCache_->GetInternalSlicesData()->AppendDistributeInfo();
529     if (result == INVALID_UINT32) {
530         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_WORKQUEUE_EXECUTE_START, STAT_EVENT_DATA_LOST);
531     }
532     return true;
533 }
WorkqueueExecuteEndEvent(const RawTraceEventInfo & event) const534 bool CpuDetailParser::WorkqueueExecuteEndEvent(const RawTraceEventInfo &event) const
535 {
536     auto executeEndMsg = event.msgPtr->workqueue_execute_end_format();
537     if (!streamFilters_->sliceFilter_->EndSlice(event.msgPtr->timestamp(), eventPid_, eventPid_, workQueueIndex_)) {
538         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_WORKQUEUE_EXECUTE_END, STAT_EVENT_NOTMATCH);
539         return false;
540     }
541     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_WORKQUEUE_EXECUTE_END, STAT_EVENT_RECEIVED);
542     return true;
543 }
IrqHandlerEntryEvent(const RawTraceEventInfo & event) const544 bool CpuDetailParser::IrqHandlerEntryEvent(const RawTraceEventInfo &event) const
545 {
546     auto irqEntryMsg = event.msgPtr->irq_handler_entry_format();
547     traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_IRQ_HANDLER_ENTRY, STAT_EVENT_RECEIVED);
548     // The tostdstring() here cannot use temporary variables, which will cause occasional garbled characters under wasm
549     streamFilters_->irqFilter_->IrqHandlerEntry(event.msgPtr->timestamp(), event.cpuId,
550                                                 traceDataCache_->GetDataIndex(irqEntryMsg.name()));
551     return true;
552 }
IrqHandlerExitEvent(const RawTraceEventInfo & event) const553 bool CpuDetailParser::IrqHandlerExitEvent(const RawTraceEventInfo &event) const
554 {
555     auto irqExitMsg = event.msgPtr->irq_handler_exit_format();
556     traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_IRQ_HANDLER_EXIT, STAT_EVENT_RECEIVED);
557     streamFilters_->irqFilter_->IrqHandlerExit(event.msgPtr->timestamp(), event.cpuId, irqExitMsg.irq(),
558                                                static_cast<uint32_t>(irqExitMsg.ret()));
559     return true;
560 }
IpiHandlerEntryEvent(const RawTraceEventInfo & event) const561 bool CpuDetailParser::IpiHandlerEntryEvent(const RawTraceEventInfo &event) const
562 {
563     auto ipiEntryMsg = event.msgPtr->ipi_entry_format();
564     traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_IPI_ENTRY, STAT_EVENT_RECEIVED);
565     streamFilters_->irqFilter_->IpiHandlerEntry(event.msgPtr->timestamp(), event.cpuId,
566                                                 traceDataCache_->GetDataIndex(ipiEntryMsg.reason()));
567     return true;
568 }
IpiHandlerExitEvent(const RawTraceEventInfo & event) const569 bool CpuDetailParser::IpiHandlerExitEvent(const RawTraceEventInfo &event) const
570 {
571     traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_IPI_EXIT, STAT_EVENT_RECEIVED);
572     streamFilters_->irqFilter_->IpiHandlerExit(event.msgPtr->timestamp(), event.cpuId);
573     return true;
574 }
SoftIrqEntryEvent(const RawTraceEventInfo & event) const575 bool CpuDetailParser::SoftIrqEntryEvent(const RawTraceEventInfo &event) const
576 {
577     auto softIrqEntryMsg = event.msgPtr->softirq_entry_format();
578     traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_SOFTIRQ_ENTRY, STAT_EVENT_RECEIVED);
579     streamFilters_->irqFilter_->SoftIrqEntry(event.msgPtr->timestamp(), event.cpuId,
580                                              static_cast<uint32_t>(softIrqEntryMsg.vec()));
581     return true;
582 }
SoftIrqRaiseEvent(const RawTraceEventInfo & event) const583 bool CpuDetailParser::SoftIrqRaiseEvent(const RawTraceEventInfo &event) const
584 {
585     traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_SOFTIRQ_RAISE, STAT_EVENT_RECEIVED);
586     traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_SOFTIRQ_RAISE, STAT_EVENT_NOTSUPPORTED);
587     return true;
588 }
SoftIrqExitEvent(const RawTraceEventInfo & event) const589 bool CpuDetailParser::SoftIrqExitEvent(const RawTraceEventInfo &event) const
590 {
591     auto softIrqExitMsg = event.msgPtr->softirq_exit_format();
592     traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_SOFTIRQ_EXIT, STAT_EVENT_RECEIVED);
593     streamFilters_->irqFilter_->SoftIrqExit(event.msgPtr->timestamp(), event.cpuId,
594                                             static_cast<uint32_t>(softIrqExitMsg.vec()));
595     return true;
596 }
SetRateEvent(const RawTraceEventInfo & event) const597 bool CpuDetailParser::SetRateEvent(const RawTraceEventInfo &event) const
598 {
599     auto clockSetRateMsg = event.msgPtr->clock_set_rate_format();
600     DataIndex nameIndex = traceDataCache_->GetDataIndex(clockSetRateMsg.name());
601     streamFilters_->clockRateFilter_->AppendNewMeasureData(clockSetRateMsg.cpu_id(), nameIndex,
602                                                            event.msgPtr->timestamp(), clockSetRateMsg.state());
603     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CLOCK_SET_RATE, STAT_EVENT_RECEIVED);
604     return true;
605 }
ClockEnableEvent(const RawTraceEventInfo & event) const606 bool CpuDetailParser::ClockEnableEvent(const RawTraceEventInfo &event) const
607 {
608     auto clockEnableMsg = event.msgPtr->clock_enable_format();
609     DataIndex nameIndex = traceDataCache_->GetDataIndex(clockEnableMsg.name());
610     streamFilters_->clockEnableFilter_->AppendNewMeasureData(clockEnableMsg.cpu_id(), nameIndex,
611                                                              event.msgPtr->timestamp(), clockEnableMsg.state());
612     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CLOCK_ENABLE, STAT_EVENT_RECEIVED);
613     return true;
614 }
ClockDisableEvent(const RawTraceEventInfo & event) const615 bool CpuDetailParser::ClockDisableEvent(const RawTraceEventInfo &event) const
616 {
617     auto clockDisableMsg = event.msgPtr->clock_disable_format();
618     DataIndex nameIndex = traceDataCache_->GetDataIndex(clockDisableMsg.name());
619     streamFilters_->clockDisableFilter_->AppendNewMeasureData(clockDisableMsg.cpu_id(), nameIndex,
620                                                               event.msgPtr->timestamp(), clockDisableMsg.state());
621     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CLOCK_DISABLE, STAT_EVENT_RECEIVED);
622     return true;
623 }
RegulatorSetVoltageEvent(const RawTraceEventInfo & event) const624 bool CpuDetailParser::RegulatorSetVoltageEvent(const RawTraceEventInfo &event) const
625 {
626     Unused(event);
627     traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_REGULATOR_SET_VOLTAGE, STAT_EVENT_NOTSUPPORTED);
628     traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_REGULATOR_SET_VOLTAGE, STAT_EVENT_RECEIVED);
629     return true;
630 }
RegulatorSetVoltageCompleteEvent(const RawTraceEventInfo & event) const631 bool CpuDetailParser::RegulatorSetVoltageCompleteEvent(const RawTraceEventInfo &event) const
632 {
633     Unused(event);
634     traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_REGULATOR_SET_VOLTAGE_COMPLETE,
635                                                     STAT_EVENT_NOTSUPPORTED);
636     traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_REGULATOR_SET_VOLTAGE_COMPLETE, STAT_EVENT_RECEIVED);
637     return true;
638 }
RegulatorDisableEvent(const RawTraceEventInfo & event) const639 bool CpuDetailParser::RegulatorDisableEvent(const RawTraceEventInfo &event) const
640 {
641     Unused(event);
642     traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_REGULATOR_DISABLE, STAT_EVENT_NOTSUPPORTED);
643     traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_REGULATOR_DISABLE, STAT_EVENT_RECEIVED);
644     return true;
645 }
RegulatorDisableCompleteEvent(const RawTraceEventInfo & event) const646 bool CpuDetailParser::RegulatorDisableCompleteEvent(const RawTraceEventInfo &event) const
647 {
648     Unused(event);
649     traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_REGULATOR_DISABLE_COMPLETE, STAT_EVENT_NOTSUPPORTED);
650     traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_REGULATOR_DISABLE_COMPLETE, STAT_EVENT_RECEIVED);
651     return true;
652 }
653 } // namespace TraceStreamer
654 } // namespace SysTuning
655