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