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