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