• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
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 #include "htrace_event_parser.h"
16 #include <cinttypes>
17 #include <string>
18 #include "app_start_filter.h"
19 #include "binder_filter.h"
20 #include "binder.pbreader.h"
21 #include "clk.pbreader.h"
22 #include "clock_filter_ex.h"
23 #include "cpu_filter.h"
24 #include "ftrace.pbreader.h"
25 #include "ftrace_event.pbreader.h"
26 #include "sched.pbreader.h"
27 #include "ipi.pbreader.h"
28 #include "irq_filter.h"
29 #include "irq.pbreader.h"
30 #include "log.h"
31 #include "measure_filter.h"
32 #include "oom.pbreader.h"
33 #include "power.pbreader.h"
34 #include "process_filter.h"
35 #include "raw_syscalls.pbreader.h"
36 #include "signal.pbreader.h"
37 #include "slice_filter.h"
38 #include "stat_filter.h"
39 #include "system_event_measure_filter.h"
40 #include "task.pbreader.h"
41 #include "thread_state_flag.h"
42 #include "trace_plugin_result.pbreader.h"
43 #include "workqueue.pbreader.h"
44 namespace SysTuning {
45 namespace TraceStreamer {
46 static constexpr uint8_t MIN_DATA_AREA = 10;
47 static constexpr uint8_t DATA_AREA_START = 1;
48 static constexpr uint8_t DATA_AREA_END = 11;
49 static constexpr size_t MAX_BUFF_SIZE = 1000 * 1000;
50 static constexpr size_t MAX_DATA_CACHE = 2 * MAX_BUFF_SIZE;
51 
HtraceEventParser(TraceDataCache * dataCache,const TraceStreamerFilters * filter)52 HtraceEventParser::HtraceEventParser(TraceDataCache* dataCache, const TraceStreamerFilters* filter)
53     : EventParserBase(dataCache, filter),
54       workQueueId_(dataCache->dataDict_.GetStringIndex("workqueue")),
55       printEventParser_(traceDataCache_, streamFilters_)
56 {
57     eventToFunctionMap_ = {
58         {TRACE_EVENT_TASK_RENAME, std::bind(&HtraceEventParser::TaskRenameEvent, this, std::placeholders::_1)},
59         {TRACE_EVENT_TASK_NEWTASK, std::bind(&HtraceEventParser::TaskNewtaskEvent, this, std::placeholders::_1)},
60         {TRACE_EVENT_SCHED_SWITCH, std::bind(&HtraceEventParser::SchedSwitchEvent, this, std::placeholders::_1)},
61         {TRACE_EVENT_SCHED_BLOCKED_REASON,
62          std::bind(&HtraceEventParser::SchedBlockReasonEvent, this, std::placeholders::_1)},
63         {TRACE_EVENT_SCHED_WAKEUP, std::bind(&HtraceEventParser::SchedWakeupEvent, this, std::placeholders::_1)},
64         {TRACE_EVENT_SCHED_WAKING, std::bind(&HtraceEventParser::SchedWakingEvent, this, std::placeholders::_1)},
65         {TRACE_EVENT_SCHED_WAKEUP_NEW, std::bind(&HtraceEventParser::SchedWakeupNewEvent, this, std::placeholders::_1)},
66         {TRACE_EVENT_PROCESS_EXIT, std::bind(&HtraceEventParser::ProcessExitEvent, this, std::placeholders::_1)},
67         {TRACE_EVENT_IPI_ENTRY, std::bind(&HtraceEventParser::IpiHandlerEntryEvent, this, std::placeholders::_1)},
68         {TRACE_EVENT_IPI_EXIT, std::bind(&HtraceEventParser::IpiHandlerExitEvent, this, std::placeholders::_1)},
69         {TRACE_EVENT_PROCESS_FREE, std::bind(&HtraceEventParser::ProcessFreeEvent, this, std::placeholders::_1)},
70         {TRACE_EVENT_SUSPEND_RESUME, std::bind(&HtraceEventParser::SuspendResumeEvent, this, std::placeholders::_1)},
71         {TRACE_EVENT_SYS_ENTRY, std::bind(&HtraceEventParser::SysEnterEvent, this, std::placeholders::_1)},
72         {TRACE_EVENT_SYS_EXIT, std::bind(&HtraceEventParser::SysExitEvent, this, std::placeholders::_1)},
73         {TRACE_EVENT_OOM_SCORE_ADJ_UPDATE,
74          std::bind(&HtraceEventParser::OomScoreAdjUpdate, this, std::placeholders::_1)}};
75     InterruptEventInitialization();
76     ClockEventInitialization();
77     CpuEventInitialization();
78     LockEventInitialization();
79     BinderEventInitialization();
80     StackEventsInitialization();
81 }
82 
InterruptEventInitialization()83 void HtraceEventParser::InterruptEventInitialization()
84 {
85     // Interrupt and soft interrupt event initialization
86     eventToFunctionMap_.emplace(TRACE_EVENT_IRQ_HANDLER_ENTRY,
87                                 std::bind(&HtraceEventParser::IrqHandlerEntryEvent, this, std::placeholders::_1));
88     eventToFunctionMap_.emplace(TRACE_EVENT_IRQ_HANDLER_EXIT,
89                                 std::bind(&HtraceEventParser::IrqHandlerExitEvent, this, std::placeholders::_1));
90     eventToFunctionMap_.emplace(TRACE_EVENT_SOFTIRQ_RAISE,
91                                 std::bind(&HtraceEventParser::SoftIrqRaiseEvent, this, std::placeholders::_1));
92     eventToFunctionMap_.emplace(TRACE_EVENT_SOFTIRQ_ENTRY,
93                                 std::bind(&HtraceEventParser::SoftIrqEntryEvent, this, std::placeholders::_1));
94     eventToFunctionMap_.emplace(TRACE_EVENT_SOFTIRQ_EXIT,
95                                 std::bind(&HtraceEventParser::SoftIrqExitEvent, this, std::placeholders::_1));
96 }
97 
ClockEventInitialization()98 void HtraceEventParser::ClockEventInitialization()
99 {
100     // Clock event initialization
101     eventToFunctionMap_.emplace(TRACE_EVENT_CLOCK_SET_RATE,
102                                 std::bind(&HtraceEventParser::ClockSetRateEvent, this, std::placeholders::_1));
103     eventToFunctionMap_.emplace(TRACE_EVENT_CLOCK_ENABLE,
104                                 std::bind(&HtraceEventParser::ClockEnableEvent, this, std::placeholders::_1));
105     eventToFunctionMap_.emplace(TRACE_EVENT_CLOCK_DISABLE,
106                                 std::bind(&HtraceEventParser::ClockDisableEvent, this, std::placeholders::_1));
107     eventToFunctionMap_.emplace(TRACE_EVENT_CLK_SET_RATE,
108                                 std::bind(&HtraceEventParser::ClkSetRateEvent, this, std::placeholders::_1));
109     eventToFunctionMap_.emplace(TRACE_EVENT_CLK_ENABLE,
110                                 std::bind(&HtraceEventParser::ClkEnableEvent, this, std::placeholders::_1));
111     eventToFunctionMap_.emplace(TRACE_EVENT_CLK_DISABLE,
112                                 std::bind(&HtraceEventParser::ClkDisableEvent, this, std::placeholders::_1));
113 }
114 
CpuEventInitialization()115 void HtraceEventParser::CpuEventInitialization()
116 {
117     eventToFunctionMap_.emplace(TRACE_EVENT_CPU_IDLE,
118                                 std::bind(&HtraceEventParser::CpuIdleEvent, this, std::placeholders::_1));
119     eventToFunctionMap_.emplace(TRACE_EVENT_CPU_FREQUENCY,
120                                 std::bind(&HtraceEventParser::CpuFrequencyEvent, this, std::placeholders::_1));
121     eventToFunctionMap_.emplace(TRACE_EVENT_CPU_FREQUENCY_LIMITS,
122                                 std::bind(&HtraceEventParser::CpuFrequencyLimitsEvent, this, std::placeholders::_1));
123 }
124 
LockEventInitialization()125 void HtraceEventParser::LockEventInitialization()
126 {
127     // Initialize lock events
128     eventToFunctionMap_.emplace(TRACE_EVENT_BINDER_TRANSACTION_LOCK,
129                                 std::bind(&HtraceEventParser::BinderTractionLockEvent, this, std::placeholders::_1));
130     eventToFunctionMap_.emplace(TRACE_EVENT_BINDER_TRANSACTION_LOCKED,
131                                 std::bind(&HtraceEventParser::BinderTractionLockedEvent, this, std::placeholders::_1));
132     eventToFunctionMap_.emplace(TRACE_EVENT_BINDER_TRANSACTION_UNLOCK,
133                                 std::bind(&HtraceEventParser::BinderTractionUnLockEvent, this, std::placeholders::_1));
134 }
135 
BinderEventInitialization()136 void HtraceEventParser::BinderEventInitialization()
137 {
138     // Binder event initialization
139     eventToFunctionMap_.emplace(TRACE_EVENT_BINDER_TRANSACTION,
140                                 std::bind(&HtraceEventParser::BinderTractionEvent, this, std::placeholders::_1));
141     eventToFunctionMap_.emplace(
142         TRACE_EVENT_BINDER_TRANSACTION_RECEIVED,
143         std::bind(&HtraceEventParser::BinderTractionReceivedEvent, this, std::placeholders::_1));
144     eventToFunctionMap_.emplace(
145         TRACE_EVENT_BINDER_TRANSACTION_ALLOC_BUF,
146         std::bind(&HtraceEventParser::BinderTractionAllocBufEvent, this, std::placeholders::_1));
147 }
148 
StackEventsInitialization()149 void HtraceEventParser::StackEventsInitialization()
150 {
151     eventToFunctionMap_.emplace(TRACE_EVENT_PRINT,
152                                 std::bind(&HtraceEventParser::ParsePrintEvent, this, std::placeholders::_1));
153     eventToFunctionMap_.emplace(TRACE_EVENT_WORKQUEUE_EXECUTE_START,
154                                 std::bind(&HtraceEventParser::WorkqueueExecuteStartEvent, this, std::placeholders::_1));
155     eventToFunctionMap_.emplace(TRACE_EVENT_WORKQUEUE_EXECUTE_END,
156                                 std::bind(&HtraceEventParser::WorkqueueExecuteEndEvent, this, std::placeholders::_1));
157 }
158 
~HtraceEventParser()159 HtraceEventParser::~HtraceEventParser()
160 {
161     TS_LOGI("thread count:%u", static_cast<uint32_t>(tids_.size()));
162     TS_LOGI("process count:%u", static_cast<uint32_t>(pids_.size()));
163     TS_LOGI("ftrace ts MIN:%llu, MAX:%llu", static_cast<unsigned long long>(ftraceStartTime_),
164             static_cast<unsigned long long>(ftraceEndTime_));
165     TS_LOGI("ftrace origin ts MIN:%llu, MAX:%llu", static_cast<unsigned long long>(ftraceOriginStartTime_),
166             static_cast<unsigned long long>(ftraceOriginEndTime_));
167 }
168 
ParserCpuEvent(HtraceDataSegment & tracePacket,SysTuning::ProtoReader::FtraceCpuDetailMsg_Reader & msg,bool & haveSplitSeg)169 void HtraceEventParser::ParserCpuEvent(HtraceDataSegment& tracePacket,
170                                        SysTuning::ProtoReader::FtraceCpuDetailMsg_Reader& msg,
171                                        bool& haveSplitSeg)
172 {
173     // parser cpu event
174     for (auto eventItor = msg.event(); eventItor; eventItor++) {
175         ProtoReader::FtraceEvent_Reader ftraceEvent(eventItor->Data(), eventItor->Size());
176         std::unique_ptr<EventInfo> eventInfo = std::make_unique<EventInfo>();
177         ProtoReader::BytesView detaiBytesView;
178         if (!SetEventType(ftraceEvent, *eventInfo, detaiBytesView)) {
179             continue;
180         }
181         ftraceOriginStartTime_ = std::min(ftraceOriginStartTime_.load(), ftraceEvent.timestamp());
182         ftraceOriginEndTime_ = std::max(ftraceOriginEndTime_.load(), ftraceEvent.timestamp());
183         eventInfo->timeStamp_ =
184             streamFilters_->clockFilter_->ToPrimaryTraceTime(tracePacket.clockId, ftraceEvent.timestamp());
185         ftraceStartTime_ = std::min(ftraceStartTime_.load(), eventInfo->timeStamp_);
186         ftraceEndTime_ = std::max(ftraceEndTime_.load(), eventInfo->timeStamp_);
187         traceDataCache_->UpdateTraceTime(eventInfo->timeStamp_);
188         if (traceDataCache_->isSplitFile_) {
189             if (eventInfo->timeStamp_ >= traceDataCache_->SplitFileMinTime() &&
190                 eventInfo->timeStamp_ <= traceDataCache_->SplitFileMaxTime()) {
191                 haveSplitSeg = true;
192                 return;
193             }
194             continue;
195         }
196         ProtoReader::FtraceEvent_CommonFileds_Reader commFileds(ftraceEvent.common_fields().data_,
197                                                                 ftraceEvent.common_fields().size_);
198         eventInfo->pid_ = commFileds.pid();
199         eventInfo->tgid_ = ftraceEvent.tgid();
200         eventInfo->cpu_ = msg.cpu();
201         auto pos = (const char*)detaiBytesView.Data() - tracePacket.seg->data();
202         eventInfo->detail_ = std::move(tracePacket.seg->substr(pos, detaiBytesView.Size()));
203 #ifdef SUPPORTTHREAD
204         std::lock_guard<std::mutex> muxLockGuard(mutex_);
205 #endif
206         eventInfo->taskNameIndex_ = traceDataCache_->GetDataIndex(ftraceEvent.comm().ToStdString());
207         htraceEventList_.emplace_back(std::move(eventInfo));
208     }
209 }
210 
ParseDataItem(HtraceDataSegment & tracePacket,ProtoReader::TracePluginResult_Reader & tracePluginResult,bool & haveSplitSeg)211 void HtraceEventParser::ParseDataItem(HtraceDataSegment& tracePacket,
212                                       ProtoReader::TracePluginResult_Reader& tracePluginResult,
213                                       bool& haveSplitSeg)
214 {
215     if (tracePacket.clockId != clock_) {
216         clock_ = tracePacket.clockId.load();
217 #ifdef SUPPORTTHREAD
218         std::lock_guard<std::mutex> muxLockGuard(mutex_);
219 #endif
220         printEventParser_.SetTraceType(TRACE_FILETYPE_H_TRACE);
221         printEventParser_.SetTraceClockId(tracePacket.clockId);
222     }
223     for (auto it = tracePluginResult.ftrace_cpu_detail(); it; ++it) {
224         ProtoReader::FtraceCpuDetailMsg_Reader msg(it->ToBytes());
225         if (!msg.has_event()) {
226             return;
227         }
228         if (msg.overwrite()) {
229             if (!lastOverwrite_) {
230                 lastOverwrite_ = msg.overwrite();
231             }
232             if (lastOverwrite_ != msg.overwrite()) {
233                 TS_LOGW("lost events:%" PRIu64 "", msg.overwrite() - lastOverwrite_);
234                 lastOverwrite_ = msg.overwrite();
235             }
236             streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_OTHER, STAT_EVENT_DATA_LOST);
237         }
238         // parser cpu event
239         ParserCpuEvent(tracePacket, msg, haveSplitSeg);
240     }
241 }
242 
BytesViewEventInfo(ProtoReader::BytesView & bytesView,ProtoReader::BytesView bytesViewChange,EventInfo & eventInfo,const SupportedTraceEventType & enumerationClass)243 bool HtraceEventParser::BytesViewEventInfo(ProtoReader::BytesView& bytesView,
244                                            ProtoReader::BytesView bytesViewChange,
245                                            EventInfo& eventInfo,
246                                            const SupportedTraceEventType& enumerationClass)
247 {
248     bytesView = bytesViewChange;
249     eventInfo.eventType_ = enumerationClass;
250     return true;
251 }
252 
ConstructEventSet(const ProtoReader::FtraceEvent_Reader & event,EventInfo & eventInfo,ProtoReader::BytesView & bytesView)253 bool HtraceEventParser::ConstructEventSet(const ProtoReader::FtraceEvent_Reader& event,
254                                           EventInfo& eventInfo,
255                                           ProtoReader::BytesView& bytesView)
256 {
257     // Construct Set the corresponding byte view and event type based on the event type
258     bool judgment = false;
259     if (event.has_task_rename_format()) {
260         judgment = BytesViewEventInfo(bytesView, event.task_rename_format(), eventInfo, TRACE_EVENT_TASK_RENAME);
261     } else if (event.has_task_newtask_format()) {
262         judgment = BytesViewEventInfo(bytesView, event.task_newtask_format(), eventInfo, TRACE_EVENT_TASK_NEWTASK);
263     } else if (event.has_binder_alloc_lru_end_format()) {
264         judgment = BytesViewEventInfo(bytesView, event.wakeup_format(), eventInfo, TRACE_EVENT_SCHED_SWITCH);
265     } else if (event.has_sched_switch_format()) {
266         judgment = BytesViewEventInfo(bytesView, event.sched_switch_format(), eventInfo, TRACE_EVENT_SCHED_SWITCH);
267     } else if (event.has_sched_blocked_reason_format()) {
268         judgment = BytesViewEventInfo(bytesView, event.sched_blocked_reason_format(), eventInfo,
269                                       TRACE_EVENT_SCHED_BLOCKED_REASON);
270     } else if (event.has_wakeup_format()) {
271         judgment = BytesViewEventInfo(bytesView, event.wakeup_format(), eventInfo, TRACE_EVENT_SCHED_WAKEUP);
272     } else if (event.has_sched_wakeup_format()) {
273         judgment = BytesViewEventInfo(bytesView, event.sched_wakeup_format(), eventInfo, TRACE_EVENT_SCHED_WAKEUP);
274     } else if (event.has_sched_wakeup_new_format()) {
275         judgment = BytesViewEventInfo(bytesView, event.sched_wakeup_new_format(), eventInfo, TRACE_EVENT_SCHED_WAKEUP);
276     } else if (event.has_sched_waking_format()) {
277         judgment = BytesViewEventInfo(bytesView, event.sched_waking_format(), eventInfo, TRACE_EVENT_SCHED_WAKING);
278     } else if (event.has_sched_process_exit_format()) {
279         judgment =
280             BytesViewEventInfo(bytesView, event.sched_process_exit_format(), eventInfo, TRACE_EVENT_PROCESS_EXIT);
281     } else if (event.has_sched_process_free_format()) {
282         judgment =
283             BytesViewEventInfo(bytesView, event.sched_process_free_format(), eventInfo, TRACE_EVENT_PROCESS_FREE);
284     } else if (event.has_suspend_resume_format()) {
285         judgment = BytesViewEventInfo(bytesView, event.suspend_resume_format(), eventInfo, TRACE_EVENT_SUSPEND_RESUME);
286     } else if (event.has_sys_enter_format()) {
287         judgment = BytesViewEventInfo(bytesView, event.sys_enter_format(), eventInfo, TRACE_EVENT_SYS_ENTRY);
288     } else if (event.has_sys_exit_format()) {
289         judgment = BytesViewEventInfo(bytesView, event.sys_exit_format(), eventInfo, TRACE_EVENT_SYS_EXIT);
290     } else if (event.has_oom_score_adj_update_format()) {
291         judgment = BytesViewEventInfo(bytesView, event.oom_score_adj_update_format(), eventInfo,
292                                       TRACE_EVENT_OOM_SCORE_ADJ_UPDATE);
293     }
294     return judgment;
295 }
296 
InterruptEventSet(const ProtoReader::FtraceEvent_Reader & event,EventInfo & eventInfo,ProtoReader::BytesView & bytesView)297 bool HtraceEventParser::InterruptEventSet(const ProtoReader::FtraceEvent_Reader& event,
298                                           EventInfo& eventInfo,
299                                           ProtoReader::BytesView& bytesView)
300 {
301     // Interrupt Set the corresponding byte view and event type based on the event type
302     bool judgment = false;
303     if (event.has_irq_handler_entry_format()) {
304         judgment =
305             BytesViewEventInfo(bytesView, event.irq_handler_entry_format(), eventInfo, TRACE_EVENT_IRQ_HANDLER_ENTRY);
306     } else if (event.has_irq_handler_exit_format()) {
307         judgment =
308             BytesViewEventInfo(bytesView, event.irq_handler_exit_format(), eventInfo, TRACE_EVENT_IRQ_HANDLER_EXIT);
309     } else if (event.has_softirq_exit_format()) {
310         judgment = BytesViewEventInfo(bytesView, event.softirq_exit_format(), eventInfo, TRACE_EVENT_SOFTIRQ_EXIT);
311     } else if (event.has_softirq_entry_format()) {
312         judgment = BytesViewEventInfo(bytesView, event.softirq_entry_format(), eventInfo, TRACE_EVENT_SOFTIRQ_ENTRY);
313     }
314 
315     return judgment;
316 }
317 
ClockEventSet(const ProtoReader::FtraceEvent_Reader & event,EventInfo & eventInfo,ProtoReader::BytesView & bytesView)318 bool HtraceEventParser::ClockEventSet(const ProtoReader::FtraceEvent_Reader& event,
319                                       EventInfo& eventInfo,
320                                       ProtoReader::BytesView& bytesView)
321 {
322     // Clock Set the corresponding byte view and event type based on the event type
323     bool judgment = false;
324     if (event.has_clock_set_rate_format()) {
325         judgment = BytesViewEventInfo(bytesView, event.clock_set_rate_format(), eventInfo, TRACE_EVENT_CLOCK_SET_RATE);
326     } else if (event.has_clock_enable_format()) {
327         judgment = BytesViewEventInfo(bytesView, event.clock_enable_format(), eventInfo, TRACE_EVENT_CLOCK_ENABLE);
328     } else if (event.has_clock_disable_format()) {
329         judgment = BytesViewEventInfo(bytesView, event.clock_disable_format(), eventInfo, TRACE_EVENT_CLOCK_DISABLE);
330     } else if (event.has_clk_set_rate_format()) {
331         judgment = BytesViewEventInfo(bytesView, event.clk_set_rate_format(), eventInfo, TRACE_EVENT_CLK_SET_RATE);
332     } else if (event.has_clk_enable_format()) {
333         judgment = BytesViewEventInfo(bytesView, event.clk_enable_format(), eventInfo, TRACE_EVENT_CLK_ENABLE);
334     } else if (event.has_clk_disable_format()) {
335         judgment = BytesViewEventInfo(bytesView, event.clk_disable_format(), eventInfo, TRACE_EVENT_CLK_DISABLE);
336     }
337 
338     return judgment;
339 }
340 
CpuEventSet(const ProtoReader::FtraceEvent_Reader & event,EventInfo & eventInfo,ProtoReader::BytesView & bytesView)341 bool HtraceEventParser::CpuEventSet(const ProtoReader::FtraceEvent_Reader& event,
342                                     EventInfo& eventInfo,
343                                     ProtoReader::BytesView& bytesView)
344 {
345     bool judgment = false;
346     if (event.has_cpu_idle_format()) {
347         judgment = BytesViewEventInfo(bytesView, event.cpu_idle_format(), eventInfo, TRACE_EVENT_CPU_IDLE);
348     } else if (event.has_cpu_frequency_format()) {
349         judgment = BytesViewEventInfo(bytesView, event.cpu_frequency_format(), eventInfo, TRACE_EVENT_CPU_FREQUENCY);
350     } else if (event.has_cpu_frequency_limits_format()) {
351         judgment = BytesViewEventInfo(bytesView, event.cpu_frequency_limits_format(), eventInfo,
352                                       TRACE_EVENT_CPU_FREQUENCY_LIMITS);
353     }
354 
355     return judgment;
356 }
357 
LockEventSet(const ProtoReader::FtraceEvent_Reader & event,EventInfo & eventInfo,ProtoReader::BytesView & bytesView)358 bool HtraceEventParser::LockEventSet(const ProtoReader::FtraceEvent_Reader& event,
359                                      EventInfo& eventInfo,
360                                      ProtoReader::BytesView& bytesView)
361 {
362     bool judgment = false;
363 
364     if (event.has_binder_lock_format()) {
365         judgment =
366             BytesViewEventInfo(bytesView, event.binder_lock_format(), eventInfo, TRACE_EVENT_BINDER_TRANSACTION_LOCK);
367     } else if (event.has_binder_locked_format()) {
368         judgment = BytesViewEventInfo(bytesView, event.binder_locked_format(), eventInfo,
369                                       TRACE_EVENT_BINDER_TRANSACTION_LOCKED);
370     } else if (event.has_binder_unlock_format()) {
371         judgment = BytesViewEventInfo(bytesView, event.binder_unlock_format(), eventInfo,
372                                       TRACE_EVENT_BINDER_TRANSACTION_UNLOCK);
373     }
374 
375     return judgment;
376 }
377 
BinderEventSet(const ProtoReader::FtraceEvent_Reader & event,EventInfo & eventInfo,ProtoReader::BytesView & bytesView)378 bool HtraceEventParser::BinderEventSet(const ProtoReader::FtraceEvent_Reader& event,
379                                        EventInfo& eventInfo,
380                                        ProtoReader::BytesView& bytesView)
381 {
382     bool judgment = false;
383 
384     if (event.has_binder_transaction_format()) {
385         judgment =
386             BytesViewEventInfo(bytesView, event.binder_transaction_format(), eventInfo, TRACE_EVENT_BINDER_TRANSACTION);
387     } else if (event.has_binder_transaction_received_format()) {
388         judgment = BytesViewEventInfo(bytesView, event.binder_transaction_received_format(), eventInfo,
389                                       TRACE_EVENT_BINDER_TRANSACTION_RECEIVED);
390     } else if (event.has_binder_transaction_alloc_buf_format()) {
391         judgment = BytesViewEventInfo(bytesView, event.binder_transaction_alloc_buf_format(), eventInfo,
392                                       TRACE_EVENT_BINDER_TRANSACTION_ALLOC_BUF);
393     }
394 
395     return judgment;
396 }
397 
StackEventSet(const ProtoReader::FtraceEvent_Reader & event,EventInfo & eventInfo,ProtoReader::BytesView & bytesView)398 bool HtraceEventParser::StackEventSet(const ProtoReader::FtraceEvent_Reader& event,
399                                       EventInfo& eventInfo,
400                                       ProtoReader::BytesView& bytesView)
401 {
402     bool judgment = false;
403 
404     if (event.has_print_format()) {
405         judgment = BytesViewEventInfo(bytesView, event.print_format(), eventInfo, TRACE_EVENT_PRINT);
406     } else if (event.has_workqueue_execute_start_format()) {
407         judgment = BytesViewEventInfo(bytesView, event.workqueue_execute_start_format(), eventInfo,
408                                       TRACE_EVENT_WORKQUEUE_EXECUTE_START);
409     } else if (event.has_workqueue_execute_end_format()) {
410         judgment = BytesViewEventInfo(bytesView, event.workqueue_execute_end_format(), eventInfo,
411                                       TRACE_EVENT_WORKQUEUE_EXECUTE_END);
412     }
413 
414     return judgment;
415 }
416 
SetEventType(const ProtoReader::FtraceEvent_Reader & event,EventInfo & eventInfo,ProtoReader::BytesView & bytesView)417 bool HtraceEventParser::SetEventType(const ProtoReader::FtraceEvent_Reader& event,
418                                      EventInfo& eventInfo,
419                                      ProtoReader::BytesView& bytesView)
420 {
421     // If all conditions are false, execute the data in else
422     if (ConstructEventSet(event, eventInfo, bytesView) || InterruptEventSet(event, eventInfo, bytesView) ||
423         ClockEventSet(event, eventInfo, bytesView) || CpuEventSet(event, eventInfo, bytesView) ||
424         LockEventSet(event, eventInfo, bytesView) || BinderEventSet(event, eventInfo, bytesView) ||
425         StackEventSet(event, eventInfo, bytesView)) {
426         return true;
427     }
428 
429     // Tracking event signal generation and transmission
430     if (event.has_signal_generate_format()) {
431         bytesView = event.signal_generate_format();
432         eventInfo.eventType_ = TRACE_EVENT_SIGNAL_GENERATE;
433     } else if (event.has_signal_deliver_format()) {
434         bytesView = event.signal_deliver_format();
435         eventInfo.eventType_ = TRACE_EVENT_SIGNAL_DELIVER;
436     } else {
437         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_OTHER, STAT_EVENT_NOTSUPPORTED);
438         return false;
439     }
440 
441     return true;
442 }
BinderTractionAllocBufEvent(const EventInfo & event) const443 bool HtraceEventParser::BinderTractionAllocBufEvent(const EventInfo& event) const
444 {
445     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_BINDER_TRANSACTION_ALLOC_BUF, STAT_EVENT_RECEIVED);
446     ProtoReader::BinderTransactionAllocBufFormat_Reader msg(event.detail_);
447     uint64_t dataSize = msg.data_size();
448     uint64_t offsetsSize = msg.offsets_size();
449     streamFilters_->binderFilter_->TransactionAllocBuf(event.timeStamp_, event.pid_, dataSize, offsetsSize);
450     TS_LOGD("dataSize:%lu, offsetSize:%lu", dataSize, offsetsSize);
451     return true;
452 }
BinderTractionEvent(const EventInfo & event) const453 bool HtraceEventParser::BinderTractionEvent(const EventInfo& event) const
454 {
455     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_BINDER_TRANSACTION, STAT_EVENT_RECEIVED);
456     ProtoReader::BinderTransactionFormat_Reader msg(event.detail_);
457     int32_t destNode = msg.target_node();
458     int32_t destTgid = msg.to_proc();
459     int32_t destTid = msg.to_thread();
460     int32_t transactionId = msg.debug_id();
461     bool isReply = msg.reply() == 1;
462     uint32_t flags = msg.flags();
463     TS_LOGD("destNode:%d, destTgid:%d, destTid:%d, transactionId:%d, isReply:%d flags:%d, code:%d", destNode, destTgid,
464             destTid, transactionId, isReply, flags, msg.code());
465     streamFilters_->binderFilter_->SendTraction(event.timeStamp_, event.pid_, transactionId, destNode, destTgid,
466                                                 destTid, isReply, flags, msg.code());
467     if (traceDataCache_->BinderRunnableTraceEnabled() && !streamFilters_->binderFilter_->IsAsync(flags)) {
468         streamFilters_->cpuFilter_->InsertRunnableBinderEvent(
469             transactionId, streamFilters_->processFilter_->GetInternalTid(event.pid_));
470     }
471     return true;
472 }
BinderTractionReceivedEvent(const EventInfo & event) const473 bool HtraceEventParser::BinderTractionReceivedEvent(const EventInfo& event) const
474 {
475     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_BINDER_TRANSACTION_RECEIVED, STAT_EVENT_RECEIVED);
476     ProtoReader::BinderTransactionReceivedFormat_Reader msg(event.detail_);
477     int32_t transactionId = msg.debug_id();
478     streamFilters_->binderFilter_->ReceiveTraction(event.timeStamp_, event.pid_, transactionId);
479     if (traceDataCache_->BinderRunnableTraceEnabled()) {
480         streamFilters_->cpuFilter_->InsertRunnableBinderRecvEvent(
481             transactionId, streamFilters_->processFilter_->GetInternalTid(event.pid_));
482     }
483     TS_LOGD("transactionId:%d", transactionId);
484     return true;
485 }
BinderTractionLockEvent(const EventInfo & event) const486 bool HtraceEventParser::BinderTractionLockEvent(const EventInfo& event) const
487 {
488     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_BINDER_TRANSACTION_LOCK, STAT_EVENT_RECEIVED);
489     ProtoReader::BinderLockFormat_Reader msg(event.detail_);
490     std::string tag = msg.tag().ToStdString();
491     streamFilters_->binderFilter_->TractionLock(event.timeStamp_, event.pid_, tag);
492     TS_LOGD("tag:%s", tag.c_str());
493     return true;
494 }
BinderTractionLockedEvent(const EventInfo & event) const495 bool HtraceEventParser::BinderTractionLockedEvent(const EventInfo& event) const
496 {
497     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_BINDER_TRANSACTION_LOCKED, STAT_EVENT_RECEIVED);
498     ProtoReader::BinderLockedFormat_Reader msg(event.detail_);
499     std::string tag = msg.tag().ToStdString();
500     streamFilters_->binderFilter_->TractionLocked(event.timeStamp_, event.pid_, tag);
501     return true;
502 }
BinderTractionUnLockEvent(const EventInfo & event) const503 bool HtraceEventParser::BinderTractionUnLockEvent(const EventInfo& event) const
504 {
505     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_BINDER_TRANSACTION_UNLOCK, STAT_EVENT_RECEIVED);
506     ProtoReader::BinderUnlockFormat_Reader msg(event.detail_);
507     std::string tag = msg.tag().ToStdString();
508     streamFilters_->binderFilter_->TractionUnlock(event.timeStamp_, event.pid_, tag);
509     return true;
510 }
SchedSwitchEvent(const EventInfo & event)511 bool HtraceEventParser::SchedSwitchEvent(const EventInfo& event)
512 {
513     ProtoReader::SchedSwitchFormat_Reader msg(event.detail_);
514     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_SWITCH, STAT_EVENT_RECEIVED);
515     uint32_t prevPrioValue = msg.prev_prio();
516     uint32_t nextPrioValue = msg.next_prio();
517     uint32_t prevPidValue = msg.prev_pid();
518     uint32_t nextPidValue = msg.next_pid();
519     if (!tids_.count(prevPidValue)) {
520         tids_.insert(prevPidValue);
521     }
522     if (!tids_.count(nextPidValue)) {
523         tids_.insert(nextPidValue);
524     }
525     std::string prevCommStr = msg.prev_comm().ToStdString();
526     std::string nextCommStr = msg.next_comm().ToStdString();
527     auto prevState = msg.prev_state();
528 
529     auto nextInternalTid =
530         streamFilters_->processFilter_->UpdateOrCreateThreadWithName(event.timeStamp_, nextPidValue, nextCommStr);
531     auto uprevtid =
532         streamFilters_->processFilter_->UpdateOrCreateThreadWithName(event.timeStamp_, prevPidValue, prevCommStr);
533     streamFilters_->cpuFilter_->InsertSwitchEvent(event.timeStamp_, event.cpu_, uprevtid,
534                                                   static_cast<uint64_t>(prevPrioValue), prevState, nextInternalTid,
535                                                   static_cast<uint64_t>(nextPrioValue), INVALID_DATAINDEX);
536     return true;
537 }
SchedBlockReasonEvent(const EventInfo & event)538 bool HtraceEventParser::SchedBlockReasonEvent(const EventInfo& event)
539 {
540     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_BLOCKED_REASON, STAT_EVENT_RECEIVED);
541     ProtoReader::SchedBlockedReasonFormat_Reader msg(event.detail_);
542     uint32_t pid = msg.pid();
543     uint32_t ioWait = msg.io_wait();
544     auto caller = traceDataCache_->GetDataIndex(
545         std::string_view("0x" + SysTuning::base::number(msg.caller(), SysTuning::base::INTEGER_RADIX_TYPE_HEX)));
546     auto itid = streamFilters_->processFilter_->UpdateOrCreateThread(event.timeStamp_, pid);
547     if (!streamFilters_->cpuFilter_->InsertBlockedReasonEvent(event.timeStamp_, event.cpu_, itid, ioWait, caller,
548                                                               INVALID_UINT32)) {
549         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_BLOCKED_REASON, STAT_EVENT_NOTMATCH);
550     }
551     return true;
552 }
ProcessExitEvent(const EventInfo & event) const553 bool HtraceEventParser::ProcessExitEvent(const EventInfo& event) const
554 {
555     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_PROCESS_EXIT, STAT_EVENT_RECEIVED);
556     ProtoReader::SchedProcessExitFormat_Reader msg(event.detail_);
557     uint32_t pidValue = msg.pid();
558     // The tostdstring() here cannot use temporary variables, which will cause occasional garbled characters under
559     // wasm
560     auto iTid = streamFilters_->processFilter_->UpdateOrCreateThreadWithName(event.timeStamp_, pidValue,
561                                                                              msg.comm().ToStdString());
562     if (streamFilters_->cpuFilter_->InsertProcessExitEvent(event.timeStamp_, event.cpu_, iTid)) {
563         return true;
564     } else {
565         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_PROCESS_EXIT, STAT_EVENT_NOTMATCH);
566         return false;
567     }
568 }
ProcessFreeEvent(const EventInfo & event) const569 bool HtraceEventParser::ProcessFreeEvent(const EventInfo& event) const
570 {
571     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_PROCESS_FREE, STAT_EVENT_RECEIVED);
572     ProtoReader::SchedProcessFreeFormat_Reader msg(event.detail_);
573     uint32_t pidValue = msg.pid();
574     // The tostdstring() here cannot use temporary variables, which will cause occasional garbled characters under
575     // wasm
576     auto iTid = streamFilters_->processFilter_->UpdateOrCreateThreadWithName(event.timeStamp_, pidValue,
577                                                                              msg.comm().ToStdString());
578     if (streamFilters_->cpuFilter_->InsertProcessFreeEvent(event.timeStamp_, iTid)) {
579         return true;
580     } else {
581         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_PROCESS_FREE, STAT_EVENT_NOTMATCH);
582         return false;
583     }
584 }
TaskRenameEvent(const EventInfo & event) const585 bool HtraceEventParser::TaskRenameEvent(const EventInfo& event) const
586 {
587     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_TASK_RENAME, STAT_EVENT_RECEIVED);
588     ProtoReader::TaskRenameFormat_Reader msg(event.detail_);
589     auto commStr = msg.newcomm();
590     auto pidValue = msg.pid();
591     streamFilters_->processFilter_->UpdateOrCreateThreadWithName(event.timeStamp_, pidValue, commStr.ToStdString());
592     return true;
593 }
TaskNewtaskEvent(const EventInfo & event) const594 bool HtraceEventParser::TaskNewtaskEvent(const EventInfo& event) const
595 {
596     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_TASK_NEWTASK, STAT_EVENT_RECEIVED);
597     // the clone flag from txt trace from kernel original is HEX, but when it is converted from proto
598     // based trace, it will be OCT number, it is not stable, so we decide to ignore it
599     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_TASK_NEWTASK, STAT_EVENT_NOTSUPPORTED);
600     return true;
601 }
ParsePrintEvent(const EventInfo & event)602 bool HtraceEventParser::ParsePrintEvent(const EventInfo& event)
603 {
604     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_PRINT, STAT_EVENT_RECEIVED);
605     ProtoReader::PrintFormat_Reader msg(event.detail_);
606     BytraceLine line;
607     line.tgid = event.tgid_;
608     line.pid = event.pid_;
609     line.ts = event.timeStamp_;
610     const auto& taskName = traceDataCache_->GetDataFromDict(event.taskNameIndex_);
611     printEventParser_.ParsePrintEvent(taskName, event.timeStamp_, event.pid_, msg.buf().ToStdString(), line);
612     if (!tids_.count(event.pid_)) {
613         tids_.insert(event.pid_);
614     }
615     return true;
616 }
SchedWakeupEvent(const EventInfo & event) const617 bool HtraceEventParser::SchedWakeupEvent(const EventInfo& event) const
618 {
619     ProtoReader::SchedWakeupFormat_Reader msg(event.detail_);
620     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_WAKEUP, STAT_EVENT_RECEIVED);
621     auto instants = traceDataCache_->GetInstantsData();
622 
623     InternalTid internalTid = streamFilters_->processFilter_->UpdateOrCreateThread(event.timeStamp_, msg.pid());
624     InternalTid wakeupFromPid = streamFilters_->processFilter_->UpdateOrCreateThread(event.timeStamp_, event.pid_);
625     instants->AppendInstantEventData(event.timeStamp_, schedWakeupName_, internalTid, wakeupFromPid);
626     streamFilters_->cpuFilter_->InsertWakeupEvent(event.timeStamp_, internalTid);
627     uint32_t targetCpu = msg.target_cpu();
628     traceDataCache_->GetRawData()->AppendRawData(event.timeStamp_, RAW_SCHED_WAKEUP, targetCpu, internalTid);
629     return true;
630 }
SchedWakeupNewEvent(const EventInfo & event) const631 bool HtraceEventParser::SchedWakeupNewEvent(const EventInfo& event) const
632 {
633     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_WAKEUP_NEW, STAT_EVENT_RECEIVED);
634     ProtoReader::SchedWakeupNewFormat_Reader msg(event.detail_);
635     auto instants = traceDataCache_->GetInstantsData();
636 
637     auto internalTid = streamFilters_->processFilter_->UpdateOrCreateThread(event.timeStamp_, msg.pid());
638     auto wakeupFromPid = streamFilters_->processFilter_->UpdateOrCreateThread(event.timeStamp_, event.pid_);
639     instants->AppendInstantEventData(event.timeStamp_, schedWakeupNewName_, internalTid, wakeupFromPid);
640     streamFilters_->cpuFilter_->InsertWakeupEvent(event.timeStamp_, internalTid);
641     uint32_t targetCpu = msg.target_cpu();
642     traceDataCache_->GetRawData()->AppendRawData(event.timeStamp_, RAW_SCHED_WAKEUP, targetCpu, internalTid);
643     return true;
644 }
SchedWakingEvent(const EventInfo & event) const645 bool HtraceEventParser::SchedWakingEvent(const EventInfo& event) const
646 {
647     ProtoReader::SchedWakingFormat_Reader msg(event.detail_);
648     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_WAKING, STAT_EVENT_RECEIVED);
649     uint32_t wakePidValue = msg.pid();
650     auto instants = traceDataCache_->GetInstantsData();
651     auto internalTid = streamFilters_->processFilter_->UpdateOrCreateThread(event.timeStamp_, wakePidValue);
652     auto wakeupFromPid = streamFilters_->processFilter_->UpdateOrCreateThread(event.timeStamp_, event.pid_);
653     streamFilters_->cpuFilter_->InsertWakeupEvent(event.timeStamp_, internalTid, true);
654     instants->AppendInstantEventData(event.timeStamp_, schedWakingName_, internalTid, wakeupFromPid);
655     uint32_t targetCpu = msg.target_cpu();
656     traceDataCache_->GetRawData()->AppendRawData(event.timeStamp_, RAW_SCHED_WAKING, targetCpu, wakeupFromPid);
657     return true;
658 }
CpuIdleEvent(const EventInfo & event) const659 bool HtraceEventParser::CpuIdleEvent(const EventInfo& event) const
660 {
661     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_IDLE, STAT_EVENT_RECEIVED);
662     ProtoReader::CpuIdleFormat_Reader msg(event.detail_);
663     std::optional<uint32_t> eventCpuValue = msg.cpu_id();
664     std::optional<uint64_t> newStateValue = msg.state();
665     if (!eventCpuValue.has_value()) {
666         TS_LOGW("Failed to convert event cpu");
667         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_IDLE, STAT_EVENT_DATA_INVALID);
668         return false;
669     }
670     if (!newStateValue.has_value()) {
671         TS_LOGW("Failed to convert state");
672         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_IDLE, STAT_EVENT_DATA_INVALID);
673         return false;
674     }
675 
676     streamFilters_->cpuMeasureFilter_->AppendNewMeasureData(eventCpuValue.value(), cpuIdleName_, event.timeStamp_,
677                                                             config_.GetStateValue(newStateValue.value()));
678 
679     // Add cpu_idle event to raw_data_table
680     traceDataCache_->GetRawData()->AppendRawData(event.timeStamp_, RAW_CPU_IDLE, eventCpuValue.value(), 0);
681     return true;
682 }
CpuFrequencyEvent(const EventInfo & event) const683 bool HtraceEventParser::CpuFrequencyEvent(const EventInfo& event) const
684 {
685     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_FREQUENCY, STAT_EVENT_RECEIVED);
686     ProtoReader::CpuFrequencyFormat_Reader msg(event.detail_);
687     std::optional<uint64_t> newStateValue = msg.state();
688     std::optional<uint32_t> eventCpuValue = msg.cpu_id();
689 
690     if (!newStateValue.has_value()) {
691         TS_LOGW("Failed to convert state");
692         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_FREQUENCY, STAT_EVENT_DATA_INVALID);
693         return false;
694     }
695     if (!eventCpuValue.has_value()) {
696         TS_LOGW("Failed to convert event cpu");
697         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_FREQUENCY, STAT_EVENT_DATA_INVALID);
698         return false;
699     }
700 
701     streamFilters_->cpuMeasureFilter_->AppendNewMeasureData(eventCpuValue.value(), cpuFrequencyName_, event.timeStamp_,
702                                                             newStateValue.value());
703     return true;
704 }
CpuFrequencyLimitsEvent(const EventInfo & event) const705 bool HtraceEventParser::CpuFrequencyLimitsEvent(const EventInfo& event) const
706 {
707     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_FREQUENCY_LIMITS, STAT_EVENT_RECEIVED);
708     ProtoReader::CpuFrequencyLimitsFormat_Reader msg(event.detail_);
709     uint32_t maxFreq = msg.max_freq();
710     uint32_t minFreq = msg.min_freq();
711     uint32_t eventCpuValue = msg.cpu_id();
712     streamFilters_->cpuMeasureFilter_->AppendNewMeasureData(eventCpuValue, cpuFrequencyLimitMaxNameId, event.timeStamp_,
713                                                             maxFreq);
714     streamFilters_->cpuMeasureFilter_->AppendNewMeasureData(eventCpuValue, cpuFrequencyLimitMinNameId, event.timeStamp_,
715                                                             minFreq);
716     return true;
717 }
SuspendResumeEvent(const EventInfo & event) const718 bool HtraceEventParser::SuspendResumeEvent(const EventInfo& event) const
719 {
720     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SUSPEND_RESUME, STAT_EVENT_RECEIVED);
721     ProtoReader::SuspendResumeFormat_Reader msg(event.detail_);
722     int32_t val = msg.val();
723     uint32_t start = msg.start();
724     std::string action = msg.action().ToStdString();
725     Unused(val);
726     Unused(start);
727     Unused(action);
728     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SUSPEND_RESUME, STAT_EVENT_NOTSUPPORTED);
729     return true;
730 }
WorkqueueExecuteStartEvent(const EventInfo & event) const731 bool HtraceEventParser::WorkqueueExecuteStartEvent(const EventInfo& event) const
732 {
733     ProtoReader::WorkqueueExecuteStartFormat_Reader msg(event.detail_);
734     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_WORKQUEUE_EXECUTE_START, STAT_EVENT_RECEIVED);
735     auto funcNameIndex = traceDataCache_->GetSymbolsData()->GetFunc(msg.function());
736     size_t result = INVALID_UINT32;
737     const auto& taskName = traceDataCache_->GetDataFromDict(event.taskNameIndex_);
738     if (funcNameIndex == INVALID_UINT64) {
739         std::string addrStr = "0x" + base::number(msg.function(), base::INTEGER_RADIX_TYPE_HEX);
740         auto addStrIndex = traceDataCache_->GetDataIndex(addrStr);
741         result = streamFilters_->sliceFilter_->BeginSlice(taskName, event.timeStamp_, event.tgid_, event.tgid_,
742                                                           workQueueId_, addStrIndex);
743     } else {
744         result = streamFilters_->sliceFilter_->BeginSlice(taskName, event.timeStamp_, event.tgid_, event.tgid_,
745                                                           workQueueId_, funcNameIndex);
746     }
747 
748     traceDataCache_->GetInternalSlicesData()->AppendDistributeInfo();
749     if (result == INVALID_UINT32) {
750         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_TRACING_MARK_WRITE, STAT_EVENT_DATA_LOST);
751     }
752     return true;
753 }
WorkqueueExecuteEndEvent(const EventInfo & event) const754 bool HtraceEventParser::WorkqueueExecuteEndEvent(const EventInfo& event) const
755 {
756     ProtoReader::WorkqueueExecuteEndFormat_Reader msg(event.detail_);
757     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_WORKQUEUE_EXECUTE_END, STAT_EVENT_RECEIVED);
758     if (streamFilters_->sliceFilter_->EndSlice(event.timeStamp_, event.tgid_, event.tgid_, workQueueId_)) {
759         streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_WORKQUEUE_EXECUTE_END, STAT_EVENT_NOTMATCH);
760     }
761     return true;
762 }
ClockSetRateEvent(const EventInfo & event) const763 bool HtraceEventParser::ClockSetRateEvent(const EventInfo& event) const
764 {
765     ProtoReader::ClockSetRateFormat_Reader msg(event.detail_);
766     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CLOCK_SET_RATE, STAT_EVENT_RECEIVED);
767     DataIndex nameIndex = traceDataCache_->GetDataIndex(msg.name().ToStdString());
768     streamFilters_->clockRateFilter_->AppendNewMeasureData(msg.cpu_id(), nameIndex, event.timeStamp_, msg.state());
769     return true;
770 }
ClockEnableEvent(const EventInfo & event) const771 bool HtraceEventParser::ClockEnableEvent(const EventInfo& event) const
772 {
773     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CLOCK_ENABLE, STAT_EVENT_RECEIVED);
774     ProtoReader::ClockEnableFormat_Reader msg(event.detail_);
775     DataIndex nameIndex = traceDataCache_->GetDataIndex(msg.name().ToStdString());
776     streamFilters_->clockEnableFilter_->AppendNewMeasureData(msg.cpu_id(), nameIndex, event.timeStamp_, msg.state());
777     return true;
778 }
ClockDisableEvent(const EventInfo & event) const779 bool HtraceEventParser::ClockDisableEvent(const EventInfo& event) const
780 {
781     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CLOCK_DISABLE, STAT_EVENT_RECEIVED);
782     ProtoReader::ClockDisableFormat_Reader msg(event.detail_);
783     DataIndex nameIndex = traceDataCache_->GetDataIndex(msg.name().ToStdString());
784     streamFilters_->clockDisableFilter_->AppendNewMeasureData(msg.cpu_id(), nameIndex, event.timeStamp_, msg.state());
785     return true;
786 }
ClkSetRateEvent(const EventInfo & event) const787 bool HtraceEventParser::ClkSetRateEvent(const EventInfo& event) const
788 {
789     ProtoReader::ClkSetRateFormat_Reader msg(event.detail_);
790     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CLK_SET_RATE, STAT_EVENT_RECEIVED);
791     DataIndex nameIndex = traceDataCache_->GetDataIndex(msg.name().ToStdString());
792     streamFilters_->clkRateFilter_->AppendNewMeasureData(event.cpu_, nameIndex, event.timeStamp_, msg.rate());
793     return true;
794 }
ClkEnableEvent(const EventInfo & event) const795 bool HtraceEventParser::ClkEnableEvent(const EventInfo& event) const
796 {
797     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CLK_ENABLE, STAT_EVENT_RECEIVED);
798     ProtoReader::ClkEnableFormat_Reader msg(event.detail_);
799     DataIndex nameIndex = traceDataCache_->GetDataIndex(msg.name().ToStdString());
800     streamFilters_->clkEnableFilter_->AppendNewMeasureData(event.cpu_, nameIndex, event.timeStamp_, 1);
801     return true;
802 }
ClkDisableEvent(const EventInfo & event) const803 bool HtraceEventParser::ClkDisableEvent(const EventInfo& event) const
804 {
805     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CLK_DISABLE, STAT_EVENT_RECEIVED);
806     ProtoReader::ClkDisableFormat_Reader msg(event.detail_);
807     DataIndex nameIndex = traceDataCache_->GetDataIndex(msg.name().ToStdString());
808     streamFilters_->clkDisableFilter_->AppendNewMeasureData(event.cpu_, nameIndex, event.timeStamp_, 0);
809     return true;
810 }
811 
IrqHandlerEntryEvent(const EventInfo & event) const812 bool HtraceEventParser::IrqHandlerEntryEvent(const EventInfo& event) const
813 {
814     traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_IRQ_HANDLER_ENTRY, STAT_EVENT_RECEIVED);
815     ProtoReader::IrqHandlerEntryFormat_Reader msg(event.detail_);
816     // The tostdstring() here cannot use temporary variables, which will cause occasional garbled characters under
817     // wasm
818     streamFilters_->irqFilter_->IrqHandlerEntry(event.timeStamp_, event.cpu_,
819                                                 traceDataCache_->GetDataIndex(msg.name().ToStdString()));
820     return true;
821 }
IrqHandlerExitEvent(const EventInfo & event) const822 bool HtraceEventParser::IrqHandlerExitEvent(const EventInfo& event) const
823 {
824     traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_IRQ_HANDLER_EXIT, STAT_EVENT_RECEIVED);
825     ProtoReader::IrqHandlerExitFormat_Reader msg(event.detail_);
826     streamFilters_->irqFilter_->IrqHandlerExit(event.timeStamp_, event.cpu_, msg.irq(),
827                                                static_cast<uint32_t>(msg.ret()));
828     return true;
829 }
IpiHandlerEntryEvent(const EventInfo & event) const830 bool HtraceEventParser::IpiHandlerEntryEvent(const EventInfo& event) const
831 {
832     traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_IPI_ENTRY, STAT_EVENT_RECEIVED);
833     ProtoReader::IpiEntryFormat_Reader msg(event.detail_);
834     streamFilters_->irqFilter_->IpiHandlerEntry(event.timeStamp_, event.cpu_,
835                                                 traceDataCache_->GetDataIndex(msg.reason().ToStdString()));
836     return true;
837 }
IpiHandlerExitEvent(const EventInfo & event) const838 bool HtraceEventParser::IpiHandlerExitEvent(const EventInfo& event) const
839 {
840     traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_IPI_EXIT, STAT_EVENT_RECEIVED);
841     streamFilters_->irqFilter_->IpiHandlerExit(event.timeStamp_, event.cpu_);
842     return true;
843 }
SoftIrqEntryEvent(const EventInfo & event) const844 bool HtraceEventParser::SoftIrqEntryEvent(const EventInfo& event) const
845 {
846     traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_SOFTIRQ_ENTRY, STAT_EVENT_RECEIVED);
847     ProtoReader::SoftirqEntryFormat_Reader msg(event.detail_);
848     streamFilters_->irqFilter_->SoftIrqEntry(event.timeStamp_, event.cpu_, static_cast<uint32_t>(msg.vec()));
849     return true;
850 }
SoftIrqRaiseEvent(const EventInfo & event) const851 bool HtraceEventParser::SoftIrqRaiseEvent(const EventInfo& event) const
852 {
853     traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_SOFTIRQ_RAISE, STAT_EVENT_RECEIVED);
854     traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_SOFTIRQ_RAISE, STAT_EVENT_NOTSUPPORTED);
855     return true;
856 }
SoftIrqExitEvent(const EventInfo & event) const857 bool HtraceEventParser::SoftIrqExitEvent(const EventInfo& event) const
858 {
859     traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_SOFTIRQ_EXIT, STAT_EVENT_RECEIVED);
860     ProtoReader::SoftirqExitFormat_Reader msg(event.detail_);
861     streamFilters_->irqFilter_->SoftIrqExit(event.timeStamp_, event.cpu_, static_cast<uint32_t>(msg.vec()));
862     return true;
863 }
SysEnterEvent(const EventInfo & event) const864 bool HtraceEventParser::SysEnterEvent(const EventInfo& event) const
865 {
866     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SYS_ENTRY, STAT_EVENT_RECEIVED);
867     ProtoReader::SysEnterFormat_Reader msg(event.detail_);
868     auto ipid = streamFilters_->processFilter_->UpdateOrCreateThread(event.timeStamp_, event.tgid_);
869     traceDataCache_->GetSysCallData()->AppendSysCallData(msg.id(), sysEnterName_, ipid, event.timeStamp_, 0);
870     return true;
871 }
SysExitEvent(const EventInfo & event) const872 bool HtraceEventParser::SysExitEvent(const EventInfo& event) const
873 {
874     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SYS_EXIT, STAT_EVENT_RECEIVED);
875     ProtoReader::SysExitFormat_Reader msg(event.detail_);
876     auto ipid = streamFilters_->processFilter_->UpdateOrCreateThread(event.timeStamp_, event.tgid_);
877     traceDataCache_->GetSysCallData()->AppendSysCallData(msg.id(), sysExitName_, ipid, event.timeStamp_, msg.ret());
878     return true;
879 }
880 
OomScoreAdjUpdate(const EventInfo & event) const881 bool HtraceEventParser::OomScoreAdjUpdate(const EventInfo& event) const
882 {
883     streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_OOM_SCORE_ADJ_UPDATE, STAT_EVENT_RECEIVED);
884     ProtoReader::OomScoreAdjUpdateFormat_Reader msg(event.detail_);
885     streamFilters_->processMeasureFilter_->AppendNewMeasureData(msg.pid(), oomScoreAdjName_, event.timeStamp_,
886                                                                 msg.oom_score_adj());
887     return true;
888 }
889 
FilterAllEventsReader()890 void HtraceEventParser::FilterAllEventsReader()
891 {
892 #ifdef SUPPORTTHREAD
893     std::lock_guard<std::mutex> muxLockGuard(mutex_);
894 #endif
895     if (htraceEventList_.size() < MAX_DATA_CACHE) {
896         return;
897     }
898     auto cmp = [](const std::unique_ptr<EventInfo>& a, const std::unique_ptr<EventInfo>& b) {
899         return a->timeStamp_ < b->timeStamp_;
900     };
901     std::stable_sort(htraceEventList_.begin(), htraceEventList_.end(), cmp);
902 
903     auto endOfList = htraceEventList_.begin() + MAX_BUFF_SIZE;
904     for (auto eventItor = htraceEventList_.begin(); eventItor != endOfList; ++eventItor) {
905         auto event = eventItor->get();
906         if (event->tgid_ != INVALID_INT32) {
907             if (!pids_.count(event->tgid_)) {
908                 pids_.insert(event->tgid_);
909             }
910             streamFilters_->processFilter_->GetOrCreateThreadWithPid(event->tgid_, event->tgid_);
911         }
912         ProtoReaderDealEvent(event);
913         eventItor->reset();
914     }
915     htraceEventList_.erase(htraceEventList_.begin(), endOfList);
916 }
FilterAllEvents()917 void HtraceEventParser::FilterAllEvents()
918 {
919     auto cmp = [](const std::unique_ptr<EventInfo>& a, const std::unique_ptr<EventInfo>& b) {
920         return a->timeStamp_ < b->timeStamp_;
921     };
922 #ifdef SUPPORTTHREAD
923     std::lock_guard<std::mutex> muxLockGuard(mutex_);
924 #endif
925     std::stable_sort(htraceEventList_.begin(), htraceEventList_.end(), cmp);
926     while (htraceEventList_.size()) {
927         int32_t size = std::min(MAX_BUFF_SIZE, htraceEventList_.size());
928         auto endOfList = htraceEventList_.begin() + size;
929         for (auto eventIter = htraceEventList_.begin(); eventIter != endOfList; ++eventIter) {
930             auto event = eventIter->get();
931             if (event->tgid_ != INVALID_INT32) {
932                 if (!pids_.count(event->tgid_)) {
933                     pids_.insert(event->tgid_);
934                 }
935                 streamFilters_->processFilter_->GetOrCreateThreadWithPid(event->tgid_, event->tgid_);
936             }
937             ProtoReaderDealEvent(event);
938             eventIter->reset();
939         }
940         htraceEventList_.erase(htraceEventList_.begin(), endOfList);
941     }
942     htraceEventList_.clear();
943     streamFilters_->cpuFilter_->Finish();
944     traceDataCache_->dataDict_.Finish();
945     traceDataCache_->UpdataZeroThreadInfo();
946     if (traceDataCache_->AppStartTraceEnabled()) {
947         streamFilters_->appStartupFilter_->FilterAllAPPStartupData();
948     }
949     traceDataCache_->GetThreadStateData()->SortAllRowByTs();
950 }
951 
ProtoReaderDealEvent(EventInfo * eventInfo)952 void HtraceEventParser::ProtoReaderDealEvent(EventInfo* eventInfo)
953 {
954     if (eventInfo->pid_ != INVALID_INT32) {
955         if (!tids_.count(eventInfo->pid_)) {
956             tids_.insert(eventInfo->pid_);
957         }
958         streamFilters_->processFilter_->UpdateOrCreateThread(eventInfo->timeStamp_, eventInfo->pid_);
959     }
960     if (eventInfo->pid_ != INVALID_INT32 && eventInfo->tgid_ != INVALID_INT32) {
961         streamFilters_->processFilter_->GetOrCreateThreadWithPid(eventInfo->pid_, eventInfo->tgid_);
962     }
963     auto eventToFuncItor = eventToFunctionMap_.find(eventInfo->eventType_);
964     if (eventToFuncItor != eventToFunctionMap_.end()) {
965         eventToFuncItor->second(*eventInfo);
966     }
967 }
968 
Clear()969 void HtraceEventParser::Clear()
970 {
971     const_cast<TraceStreamerFilters*>(streamFilters_)->FilterClear();
972     streamFilters_->sysEventMemMeasureFilter_->Clear();
973     streamFilters_->sysEventVMemMeasureFilter_->Clear();
974     printEventParser_.Finish();
975 }
976 } // namespace TraceStreamer
977 } // namespace SysTuning
978