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