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