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
16 #include "cpu_detail_parser.h"
17 #include <cinttypes>
18 #include <string_view>
19 #include "app_start_filter.h"
20 #include "binder_filter.h"
21 #include "common_types.h"
22 #include "cpu_filter.h"
23 #include "irq_filter.h"
24 #include "measure_filter.h"
25 #include "process_filter.h"
26 #include "slice_filter.h"
27 #include "stat_filter.h"
28 #include "system_event_measure_filter.h"
29 #include "ftrace_event_processor.h"
30 #include "string_to_numerical.h"
31
32 namespace SysTuning {
33 namespace TraceStreamer {
CpuDetailParser(TraceDataCache * dataCache,const TraceStreamerFilters * ctx)34 CpuDetailParser::CpuDetailParser(TraceDataCache *dataCache, const TraceStreamerFilters *ctx)
35 : streamFilters_(ctx), traceDataCache_(dataCache), printEventParser_(dataCache, ctx)
36 {
37 standAloneCpuEventList_.resize(CPU_CORE_MAX);
38 printEventParser_.SetTraceType(TRACE_FILETYPE_RAW_TRACE);
39 printEventParser_.SetTraceClockId(clock_);
40 eventToFunctionMap_ = {
41 {config_.eventNameMap_.at(TRACE_EVENT_TASK_RENAME),
42 std::bind(&CpuDetailParser::TaskRenameEvent, this, std::placeholders::_1)},
43 {config_.eventNameMap_.at(TRACE_EVENT_TASK_NEWTASK),
44 std::bind(&CpuDetailParser::TaskNewtaskEvent, this, std::placeholders::_1)},
45 {config_.eventNameMap_.at(TRACE_EVENT_SCHED_SWITCH),
46 std::bind(&CpuDetailParser::SchedSwitchEvent, this, std::placeholders::_1)},
47 {config_.eventNameMap_.at(TRACE_EVENT_SCHED_BLOCKED_REASON),
48 std::bind(&CpuDetailParser::SchedBlockReasonEvent, this, std::placeholders::_1)},
49 {config_.eventNameMap_.at(TRACE_EVENT_SCHED_WAKEUP),
50 std::bind(&CpuDetailParser::SchedWakeupEvent, this, std::placeholders::_1)},
51 {config_.eventNameMap_.at(TRACE_EVENT_SCHED_WAKING),
52 std::bind(&CpuDetailParser::SchedWakingEvent, this, std::placeholders::_1)},
53 {config_.eventNameMap_.at(TRACE_EVENT_SCHED_WAKEUP_NEW),
54 std::bind(&CpuDetailParser::SchedWakeupNewEvent, this, std::placeholders::_1)},
55 {config_.eventNameMap_.at(TRACE_EVENT_PROCESS_EXIT),
56 std::bind(&CpuDetailParser::ProcessExitEvent, this, std::placeholders::_1)},
57 {config_.eventNameMap_.at(TRACE_EVENT_IPI_ENTRY),
58 std::bind(&CpuDetailParser::IpiHandlerEntryEvent, this, std::placeholders::_1)},
59 {config_.eventNameMap_.at(TRACE_EVENT_IPI_EXIT),
60 std::bind(&CpuDetailParser::IpiHandlerExitEvent, this, std::placeholders::_1)},
61 {config_.eventNameMap_.at(TRACE_EVENT_PROCESS_FREE),
62 std::bind(&CpuDetailParser::ProcessFreeEvent, this, std::placeholders::_1)},
63 {config_.eventNameMap_.at(TRACE_EVENT_SUSPEND_RESUME),
64 std::bind(&CpuDetailParser::SuspendResumeEvent, this, std::placeholders::_1)},
65 {config_.eventNameMap_.at(TRACE_EVENT_TRACING_MARK_WRITE),
66 std::bind(&CpuDetailParser::ParseTracingMarkWriteOrPrintEvent, this, std::placeholders::_1)},
67 };
68 InterruptEventInitialization();
69 ClockEventInitialization();
70 CpuEventInitialization();
71 LockEventInitialization();
72 BinderEventInitialization();
73 StackEventsInitialization();
74 VoltageEventInitialization();
75 }
76
InterruptEventInitialization()77 void CpuDetailParser::InterruptEventInitialization()
78 {
79 eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_IRQ_HANDLER_ENTRY),
80 std::bind(&CpuDetailParser::IrqHandlerEntryEvent, this, std::placeholders::_1));
81 eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_IRQ_HANDLER_EXIT),
82 std::bind(&CpuDetailParser::IrqHandlerExitEvent, this, std::placeholders::_1));
83 eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_SOFTIRQ_RAISE),
84 std::bind(&CpuDetailParser::SoftIrqRaiseEvent, this, std::placeholders::_1));
85 eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_SOFTIRQ_ENTRY),
86 std::bind(&CpuDetailParser::SoftIrqEntryEvent, this, std::placeholders::_1));
87 eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_SOFTIRQ_EXIT),
88 std::bind(&CpuDetailParser::SoftIrqExitEvent, this, std::placeholders::_1));
89 }
ClockEventInitialization()90 void CpuDetailParser::ClockEventInitialization()
91 {
92 eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_CLOCK_SET_RATE),
93 std::bind(&CpuDetailParser::SetRateEvent, this, std::placeholders::_1));
94 eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_CLOCK_ENABLE),
95 std::bind(&CpuDetailParser::ClockEnableEvent, this, std::placeholders::_1));
96 eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_CLOCK_DISABLE),
97 std::bind(&CpuDetailParser::ClockDisableEvent, this, std::placeholders::_1));
98 }
CpuEventInitialization()99 void CpuDetailParser::CpuEventInitialization()
100 {
101 eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_CPU_IDLE),
102 std::bind(&CpuDetailParser::CpuIdleEvent, this, std::placeholders::_1));
103 eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_CPU_FREQUENCY),
104 std::bind(&CpuDetailParser::CpuFrequencyEvent, this, std::placeholders::_1));
105 eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_CPU_FREQUENCY_LIMITS),
106 std::bind(&CpuDetailParser::CpuFrequencyLimitsEvent, this, std::placeholders::_1));
107 }
LockEventInitialization()108 void CpuDetailParser::LockEventInitialization()
109 {
110 eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_BINDER_TRANSACTION_LOCK),
111 std::bind(&CpuDetailParser::BinderTractionLockEvent, this, std::placeholders::_1));
112 eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_BINDER_TRANSACTION_LOCKED),
113 std::bind(&CpuDetailParser::BinderTractionLockedEvent, this, std::placeholders::_1));
114 eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_BINDER_TRANSACTION_UNLOCK),
115 std::bind(&CpuDetailParser::BinderTractionUnLockEvent, this, std::placeholders::_1));
116 }
BinderEventInitialization()117 void CpuDetailParser::BinderEventInitialization()
118 {
119 eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_BINDER_TRANSACTION),
120 std::bind(&CpuDetailParser::BinderTractionEvent, this, std::placeholders::_1));
121 eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_BINDER_TRANSACTION_RECEIVED),
122 std::bind(&CpuDetailParser::BinderTractionReceivedEvent, this, std::placeholders::_1));
123 eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_BINDER_TRANSACTION_ALLOC_BUF),
124 std::bind(&CpuDetailParser::BinderTractionAllocBufEvent, this, std::placeholders::_1));
125 }
StackEventsInitialization()126 void CpuDetailParser::StackEventsInitialization()
127 {
128 eventToFunctionMap_.emplace(
129 config_.eventNameMap_.at(TRACE_EVENT_PRINT),
130 std::bind(&CpuDetailParser::ParseTracingMarkWriteOrPrintEvent, this, std::placeholders::_1));
131 eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_WORKQUEUE_EXECUTE_START),
132 std::bind(&CpuDetailParser::WorkqueueExecuteStartEvent, this, std::placeholders::_1));
133 eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_WORKQUEUE_EXECUTE_END),
134 std::bind(&CpuDetailParser::WorkqueueExecuteEndEvent, this, std::placeholders::_1));
135 }
VoltageEventInitialization()136 void CpuDetailParser::VoltageEventInitialization()
137 {
138 eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_REGULATOR_SET_VOLTAGE),
139 std::bind(&CpuDetailParser::RegulatorSetVoltageEvent, this, std::placeholders::_1));
140 eventToFunctionMap_.emplace(
141 config_.eventNameMap_.at(TRACE_EVENT_REGULATOR_SET_VOLTAGE_COMPLETE),
142 std::bind(&CpuDetailParser::RegulatorSetVoltageCompleteEvent, this, std::placeholders::_1));
143 eventToFunctionMap_.emplace(config_.eventNameMap_.at(TRACE_EVENT_REGULATOR_DISABLE),
144 std::bind(&CpuDetailParser::RegulatorDisableEvent, this, std::placeholders::_1));
145 eventToFunctionMap_.emplace(
146 config_.eventNameMap_.at(TRACE_EVENT_REGULATOR_DISABLE_COMPLETE),
147 std::bind(&CpuDetailParser::RegulatorDisableCompleteEvent, this, std::placeholders::_1));
148 }
EventAppend(std::shared_ptr<RawTraceEventInfo> event)149 void CpuDetailParser::EventAppend(std::shared_ptr<RawTraceEventInfo> event)
150 {
151 standAloneCpuEventList_[event->cpuId].emplace(std::move(event));
152 curRawTraceEventNum_++;
153 }
ResizeStandAloneCpuEventList(uint32_t cpuNum)154 void CpuDetailParser::ResizeStandAloneCpuEventList(uint32_t cpuNum)
155 {
156 cpuCoreMax_ = cpuNum;
157 standAloneCpuEventList_.resize(cpuNum);
158 }
SortStandAloneCpuEventList(bool isFinished)159 bool CpuDetailParser::SortStandAloneCpuEventList(bool isFinished)
160 {
161 while (curRawTraceEventNum_ > 0) {
162 uint32_t minTimeCpuId = INVALID_UINT32;
163 uint64_t curMinTs = INVALID_UINT64;
164 // select a min time from one of the cpu caches
165 for (int curCpuId = 0; curCpuId < cpuCoreMax_; curCpuId++) {
166 if (!isFinished && standAloneCpuEventList_[curCpuId].empty()) {
167 return true;
168 } else if (standAloneCpuEventList_[curCpuId].empty()) {
169 continue;
170 }
171 uint64_t ts = standAloneCpuEventList_[curCpuId].front()->msgPtr->timestamp();
172 if (ts < curMinTs) {
173 curMinTs = ts;
174 minTimeCpuId = curCpuId;
175 }
176 }
177 if (INVALID_UINT32 == minTimeCpuId) {
178 break;
179 }
180 rawTraceEventList_.emplace_back(std::move(standAloneCpuEventList_[minTimeCpuId].front()));
181 standAloneCpuEventList_[minTimeCpuId].pop();
182 curRawTraceEventNum_--;
183 if (!isFinished && standAloneCpuEventList_[minTimeCpuId].empty()) {
184 break;
185 }
186 }
187 return true;
188 }
UpdateCpuOverwrite(FtraceCpuDetailMsg & cpuDetail)189 void CpuDetailParser::UpdateCpuOverwrite(FtraceCpuDetailMsg &cpuDetail)
190 {
191 if (cpuDetail.overwrite()) {
192 if (!lastOverwrite_) {
193 lastOverwrite_ = cpuDetail.overwrite();
194 }
195 if (lastOverwrite_ != cpuDetail.overwrite()) {
196 TS_LOGW("lost events:%" PRIu64 "", cpuDetail.overwrite() - lastOverwrite_);
197 lastOverwrite_ = cpuDetail.overwrite();
198 }
199 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_OTHER, STAT_EVENT_DATA_LOST);
200 }
201 }
FilterAllEvents(FtraceCpuDetailMsg & cpuDetail,bool isFinished)202 bool CpuDetailParser::FilterAllEvents(FtraceCpuDetailMsg &cpuDetail, bool isFinished)
203 {
204 UpdateCpuOverwrite(cpuDetail);
205 SortStandAloneCpuEventList(isFinished);
206 TS_CHECK_TRUE_RET(!rawTraceEventList_.empty(), true);
207 traceDataCache_->UpdateTraceTime(rawTraceEventList_.front()->msgPtr->timestamp());
208 traceDataCache_->UpdateTraceTime(rawTraceEventList_.back()->msgPtr->timestamp());
209 for (size_t i = 0; i < rawTraceEventList_.size(); i++) {
210 eventPid_ = rawTraceEventList_[i]->msgPtr->tgid();
211 if (eventPid_ != INVALID_INT32) {
212 streamFilters_->processFilter_->GetOrCreateThreadWithPid(eventPid_, eventPid_);
213 }
214 DealEvent(*rawTraceEventList_[i].get());
215 rawTraceEventList_[i].reset();
216 }
217 TS_LOGI("deal rawTraceEventList_.size=%zu", rawTraceEventList_.size());
218 rawTraceEventList_.clear();
219 cpuDetail.Clear();
220 return true;
221 }
Clear()222 void CpuDetailParser::Clear()
223 {
224 cpuCoreMax_ = CPU_CORE_MAX;
225 const_cast<TraceStreamerFilters *>(streamFilters_)->FilterClear();
226 streamFilters_->sysEventMemMeasureFilter_->Clear();
227 streamFilters_->sysEventVMemMeasureFilter_->Clear();
228 printEventParser_.Finish();
229 }
FinishCpuDetailParser()230 void CpuDetailParser::FinishCpuDetailParser()
231 {
232 streamFilters_->cpuFilter_->Finish();
233 traceDataCache_->dataDict_.Finish();
234 traceDataCache_->UpdataZeroThreadInfo();
235 if (traceDataCache_->AppStartTraceEnabled()) {
236 streamFilters_->appStartupFilter_->FilterAllAPPStartupData();
237 }
238 Clear();
239 traceDataCache_->GetThreadStateData()->SortAllRowByTs();
240 }
DealEvent(const RawTraceEventInfo & event)241 void CpuDetailParser::DealEvent(const RawTraceEventInfo &event)
242 {
243 eventTid_ = event.msgPtr->common_fields().pid();
244 if (eventTid_ != INVALID_INT32) {
245 streamFilters_->processFilter_->UpdateOrCreateThread(event.msgPtr->timestamp(), eventTid_);
246 }
247 if (eventTid_ != INVALID_INT32 && eventPid_ != INVALID_INT32) {
248 streamFilters_->processFilter_->GetOrCreateThreadWithPid(eventTid_, eventPid_);
249 }
250 const auto &eventName = FtraceEventProcessor::GetInstance().GetEventNameById(event.eventId);
251 auto iter = eventToFunctionMap_.find(eventName);
252 if (iter != eventToFunctionMap_.end()) {
253 iter->second(event);
254 } else {
255 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_OTHER, STAT_EVENT_NOTSUPPORTED);
256 }
257 }
SchedSwitchEvent(const RawTraceEventInfo & event)258 bool CpuDetailParser::SchedSwitchEvent(const RawTraceEventInfo &event)
259 {
260 auto schedSwitchMsg = event.msgPtr->sched_switch_format();
261 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_SWITCH, STAT_EVENT_RECEIVED);
262
263 auto schedSwitchPrevState = schedSwitchMsg.prev_state();
264 auto nextInternalTid = streamFilters_->processFilter_->UpdateOrCreateThreadWithName(
265 event.msgPtr->timestamp(), schedSwitchMsg.next_pid(), schedSwitchMsg.next_comm());
266 auto uprevtid = streamFilters_->processFilter_->UpdateOrCreateThreadWithName(
267 event.msgPtr->timestamp(), schedSwitchMsg.prev_pid(), schedSwitchMsg.prev_comm());
268
269 streamFilters_->cpuFilter_->InsertSwitchEvent(event.msgPtr->timestamp(), event.cpuId, uprevtid,
270 schedSwitchMsg.prev_prio(), schedSwitchPrevState, nextInternalTid,
271 schedSwitchMsg.next_prio(), INVALID_DATAINDEX);
272 return true;
273 }
SchedBlockReasonEvent(const RawTraceEventInfo & event)274 bool CpuDetailParser::SchedBlockReasonEvent(const RawTraceEventInfo &event)
275 {
276 auto reasonMsg = event.msgPtr->sched_blocked_reason_format();
277 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_BLOCKED_REASON, STAT_EVENT_RECEIVED);
278 auto caller = traceDataCache_->GetDataIndex(
279 std::string_view("0x" + SysTuning::base::number(reasonMsg.caller(), SysTuning::base::INTEGER_RADIX_TYPE_HEX)));
280 auto itid = streamFilters_->processFilter_->UpdateOrCreateThread(event.msgPtr->timestamp(), reasonMsg.pid());
281 if (streamFilters_->cpuFilter_->InsertBlockedReasonEvent(event.cpuId, itid, reasonMsg.io_wait(), caller,
282 INVALID_UINT32)) {
283 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_BLOCKED_REASON, STAT_EVENT_RECEIVED);
284 } else {
285 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_BLOCKED_REASON, STAT_EVENT_NOTMATCH);
286 }
287 return true;
288 }
SchedWakeupEvent(const RawTraceEventInfo & event) const289 bool CpuDetailParser::SchedWakeupEvent(const RawTraceEventInfo &event) const
290 {
291 auto wakeupMsg = event.msgPtr->sched_wakeup_format();
292 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_WAKEUP, STAT_EVENT_RECEIVED);
293 auto instants = traceDataCache_->GetInstantsData();
294
295 InternalTid internalTid =
296 streamFilters_->processFilter_->UpdateOrCreateThread(event.msgPtr->timestamp(), wakeupMsg.pid());
297 InternalTid wakeupFromPid =
298 streamFilters_->processFilter_->UpdateOrCreateThread(event.msgPtr->timestamp(), eventTid_);
299 instants->AppendInstantEventData(event.msgPtr->timestamp(), schedWakeupIndex_, internalTid, wakeupFromPid);
300 streamFilters_->cpuFilter_->InsertWakeupEvent(event.msgPtr->timestamp(), internalTid);
301 traceDataCache_->GetRawData()->AppendRawData(event.msgPtr->timestamp(), RAW_SCHED_WAKEUP, wakeupMsg.target_cpu(),
302 internalTid);
303 return true;
304 }
SchedWakingEvent(const RawTraceEventInfo & event) const305 bool CpuDetailParser::SchedWakingEvent(const RawTraceEventInfo &event) const
306 {
307 auto wakeingMsg = event.msgPtr->sched_waking_format();
308 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_WAKING, STAT_EVENT_RECEIVED);
309 auto instants = traceDataCache_->GetInstantsData();
310 auto internalTid =
311 streamFilters_->processFilter_->UpdateOrCreateThread(event.msgPtr->timestamp(), wakeingMsg.pid());
312 auto wakeupFromPid = streamFilters_->processFilter_->UpdateOrCreateThread(event.msgPtr->timestamp(), eventTid_);
313 streamFilters_->cpuFilter_->InsertWakeupEvent(event.msgPtr->timestamp(), internalTid, true);
314 instants->AppendInstantEventData(event.msgPtr->timestamp(), schedWakingIndex_, internalTid, wakeupFromPid);
315 traceDataCache_->GetRawData()->AppendRawData(event.msgPtr->timestamp(), RAW_SCHED_WAKING, wakeingMsg.target_cpu(),
316 wakeupFromPid);
317 return true;
318 }
SchedWakeupNewEvent(const RawTraceEventInfo & event) const319 bool CpuDetailParser::SchedWakeupNewEvent(const RawTraceEventInfo &event) const
320 {
321 auto wakeupNewMsg = event.msgPtr->sched_wakeup_new_format();
322 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SCHED_WAKEUP_NEW, STAT_EVENT_RECEIVED);
323 auto instants = traceDataCache_->GetInstantsData();
324 auto internalTid =
325 streamFilters_->processFilter_->UpdateOrCreateThread(event.msgPtr->timestamp(), wakeupNewMsg.pid());
326 auto wakeupFromPid = streamFilters_->processFilter_->UpdateOrCreateThread(event.msgPtr->timestamp(), eventTid_);
327 instants->AppendInstantEventData(event.msgPtr->timestamp(), schedWakeupNewIndex_, internalTid, wakeupFromPid);
328 streamFilters_->cpuFilter_->InsertWakeupEvent(event.msgPtr->timestamp(), internalTid);
329 traceDataCache_->GetRawData()->AppendRawData(event.msgPtr->timestamp(), RAW_SCHED_WAKEUP, wakeupNewMsg.target_cpu(),
330 internalTid);
331 return true;
332 }
ProcessExitEvent(const RawTraceEventInfo & event) const333 bool CpuDetailParser::ProcessExitEvent(const RawTraceEventInfo &event) const
334 {
335 auto procExitMsg = event.msgPtr->sched_process_exit_format();
336 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_PROCESS_EXIT, STAT_EVENT_RECEIVED);
337 uint32_t pidValue = procExitMsg.pid();
338 // The tostdstring() here cannot use temporary variables, which will cause occasional garbled characters under wasm
339 auto iTid = streamFilters_->processFilter_->UpdateOrCreateThreadWithName(event.msgPtr->timestamp(), pidValue,
340 procExitMsg.comm());
341 if (streamFilters_->cpuFilter_->InsertProcessExitEvent(event.msgPtr->timestamp(), event.cpuId, iTid)) {
342 return true;
343 } else {
344 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_PROCESS_EXIT, STAT_EVENT_NOTMATCH);
345 return false;
346 }
347 }
ProcessFreeEvent(const RawTraceEventInfo & event) const348 bool CpuDetailParser::ProcessFreeEvent(const RawTraceEventInfo &event) const
349 {
350 auto procFreeMsg = event.msgPtr->sched_process_exit_format();
351 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_PROCESS_FREE, STAT_EVENT_RECEIVED);
352 uint32_t pidValue = procFreeMsg.pid();
353 // The tostdstring() here cannot use temporary variables, which will cause occasional garbled characters under wasm
354 auto iTid = streamFilters_->processFilter_->UpdateOrCreateThreadWithName(event.msgPtr->timestamp(), pidValue,
355 procFreeMsg.comm());
356 if (streamFilters_->cpuFilter_->InsertProcessFreeEvent(event.msgPtr->timestamp(), iTid)) {
357 return true;
358 } else {
359 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_PROCESS_FREE, STAT_EVENT_NOTMATCH);
360 return false;
361 }
362 }
BinderTractionEvent(const RawTraceEventInfo & event) const363 bool CpuDetailParser::BinderTractionEvent(const RawTraceEventInfo &event) const
364 {
365 auto transactionMsg = event.msgPtr->binder_transaction_format();
366 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_BINDER_TRANSACTION, STAT_EVENT_RECEIVED);
367 int32_t destNode = transactionMsg.target_node();
368 int32_t destTgid = transactionMsg.to_proc();
369 int32_t destTid = transactionMsg.to_thread();
370 int32_t transactionId = transactionMsg.debug_id();
371 bool isReply = transactionMsg.reply() == 1;
372 uint32_t flags = transactionMsg.flags();
373 TS_LOGD("destNode:%d, destTgid:%d, destTid:%d, transactionId:%d, isReply:%d flags:%d, code:%d", destNode, destTgid,
374 destTid, transactionId, isReply, flags, transactionMsg.code());
375 streamFilters_->binderFilter_->SendTraction(event.msgPtr->timestamp(), eventTid_, transactionId, destNode, destTgid,
376 destTid, isReply, flags, transactionMsg.code());
377 return true;
378 }
BinderTractionAllocBufEvent(const RawTraceEventInfo & event) const379 bool CpuDetailParser::BinderTractionAllocBufEvent(const RawTraceEventInfo &event) const
380 {
381 auto allocBufMsg = event.msgPtr->binder_transaction_alloc_buf_format();
382 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_BINDER_TRANSACTION_ALLOC_BUF, STAT_EVENT_RECEIVED);
383 streamFilters_->binderFilter_->TransactionAllocBuf(event.msgPtr->timestamp(), eventTid_, allocBufMsg.data_size(),
384 allocBufMsg.offsets_size());
385 TS_LOGD("dataSize:%" PRIu64 ", offsetSize:%" PRIu64 "", allocBufMsg.data_size(), allocBufMsg.offsets_size());
386 return true;
387 }
BinderTractionReceivedEvent(const RawTraceEventInfo & event) const388 bool CpuDetailParser::BinderTractionReceivedEvent(const RawTraceEventInfo &event) const
389 {
390 auto recvedMsg = event.msgPtr->binder_transaction_received_format();
391 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_BINDER_TRANSACTION_RECEIVED, STAT_EVENT_RECEIVED);
392 int32_t transactionId = recvedMsg.debug_id();
393 streamFilters_->binderFilter_->ReceiveTraction(event.msgPtr->timestamp(), eventTid_, transactionId);
394 TS_LOGD("transactionId:%d", transactionId);
395 return true;
396 }
BinderTractionLockEvent(const RawTraceEventInfo & event) const397 bool CpuDetailParser::BinderTractionLockEvent(const RawTraceEventInfo &event) const
398 {
399 auto lockMsg = event.msgPtr->binder_lock_format();
400 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_BINDER_TRANSACTION_LOCK, STAT_EVENT_RECEIVED);
401 streamFilters_->binderFilter_->TractionLock(event.msgPtr->timestamp(), eventTid_, lockMsg.tag());
402 TS_LOGD("tag:%s", lockMsg.tag().c_str());
403 return true;
404 }
BinderTractionLockedEvent(const RawTraceEventInfo & event) const405 bool CpuDetailParser::BinderTractionLockedEvent(const RawTraceEventInfo &event) const
406 {
407 auto lockedMsg = event.msgPtr->binder_locked_format();
408 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_BINDER_TRANSACTION_LOCKED, STAT_EVENT_RECEIVED);
409 streamFilters_->binderFilter_->TractionLocked(event.msgPtr->timestamp(), eventTid_, lockedMsg.tag());
410 return true;
411 }
BinderTractionUnLockEvent(const RawTraceEventInfo & event) const412 bool CpuDetailParser::BinderTractionUnLockEvent(const RawTraceEventInfo &event) const
413 {
414 auto unlockMsg = event.msgPtr->binder_unlock_format();
415 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_BINDER_TRANSACTION_UNLOCK, STAT_EVENT_RECEIVED);
416 streamFilters_->binderFilter_->TractionUnlock(event.msgPtr->timestamp(), eventTid_, unlockMsg.tag());
417 return true;
418 }
TaskRenameEvent(const RawTraceEventInfo & event) const419 bool CpuDetailParser::TaskRenameEvent(const RawTraceEventInfo &event) const
420 {
421 auto renameMsg = event.msgPtr->task_rename_format();
422 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_TASK_RENAME, STAT_EVENT_RECEIVED);
423 streamFilters_->processFilter_->UpdateOrCreateThreadWithName(event.msgPtr->timestamp(), renameMsg.pid(),
424 renameMsg.newcomm());
425 return true;
426 }
TaskNewtaskEvent(const RawTraceEventInfo & event) const427 bool CpuDetailParser::TaskNewtaskEvent(const RawTraceEventInfo &event) const
428 {
429 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_TASK_NEWTASK, STAT_EVENT_RECEIVED);
430 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_TASK_NEWTASK, STAT_EVENT_NOTSUPPORTED);
431 return true;
432 }
ParseTracingMarkWriteOrPrintEvent(const RawTraceEventInfo & event)433 bool CpuDetailParser::ParseTracingMarkWriteOrPrintEvent(const RawTraceEventInfo &event)
434 {
435 auto printMsg = event.msgPtr->print_format();
436 BytraceLine line;
437 line.tgid = eventPid_;
438 line.pid = eventTid_;
439 line.ts = event.msgPtr->timestamp();
440 printEventParser_.ParsePrintEvent(event.msgPtr->comm(), line.ts, eventTid_, printMsg.buf(), line);
441 return true;
442 }
CpuIdleEvent(const RawTraceEventInfo & event) const443 bool CpuDetailParser::CpuIdleEvent(const RawTraceEventInfo &event) const
444 {
445 auto idleMsg = event.msgPtr->cpu_idle_format();
446 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_IDLE, STAT_EVENT_RECEIVED);
447 std::optional<uint32_t> eventCpu = idleMsg.cpu_id();
448 std::optional<uint64_t> newState = idleMsg.state();
449 if (!eventCpu.has_value()) {
450 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_IDLE, STAT_EVENT_DATA_INVALID);
451 TS_LOGW("Convert event cpu Failed");
452 return false;
453 }
454 if (!newState.has_value()) {
455 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_IDLE, STAT_EVENT_DATA_INVALID);
456 TS_LOGW("Convert event state Failed");
457 return false;
458 }
459
460 streamFilters_->cpuMeasureFilter_->AppendNewMeasureData(eventCpu.value(), cpuIdleIndex_, event.msgPtr->timestamp(),
461 config_.GetStateValue(newState.value()));
462
463 // Add cpu_idle event to raw_data_table
464 traceDataCache_->GetRawData()->AppendRawData(event.msgPtr->timestamp(), RAW_CPU_IDLE, eventCpu.value(), 0);
465 return true;
466 }
CpuFrequencyEvent(const RawTraceEventInfo & event) const467 bool CpuDetailParser::CpuFrequencyEvent(const RawTraceEventInfo &event) const
468 {
469 auto frequencyMsg = event.msgPtr->cpu_frequency_format();
470 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_FREQUENCY, STAT_EVENT_RECEIVED);
471 std::optional<uint64_t> newState = frequencyMsg.state();
472 std::optional<uint32_t> eventCpu = frequencyMsg.cpu_id();
473
474 if (!newState.has_value()) {
475 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_FREQUENCY, STAT_EVENT_DATA_INVALID);
476 TS_LOGW("Convert event state Failed");
477 return false;
478 }
479 if (!eventCpu.has_value()) {
480 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_FREQUENCY, STAT_EVENT_DATA_INVALID);
481 TS_LOGW("Convert event cpu Failed");
482 return false;
483 }
484
485 streamFilters_->cpuMeasureFilter_->AppendNewMeasureData(eventCpu.value(), cpuFrequencyIndex_,
486 event.msgPtr->timestamp(), newState.value());
487 return true;
488 }
CpuFrequencyLimitsEvent(const RawTraceEventInfo & event) const489 bool CpuDetailParser::CpuFrequencyLimitsEvent(const RawTraceEventInfo &event) const
490 {
491 auto limitsMsg = event.msgPtr->cpu_frequency_limits_format();
492 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CPU_FREQUENCY_LIMITS, STAT_EVENT_RECEIVED);
493 streamFilters_->cpuMeasureFilter_->AppendNewMeasureData(limitsMsg.cpu_id(), cpuFrequencyLimitMaxIndex_,
494 event.msgPtr->timestamp(), limitsMsg.max_freq());
495 streamFilters_->cpuMeasureFilter_->AppendNewMeasureData(limitsMsg.cpu_id(), cpuFrequencyLimitMinIndex_,
496 event.msgPtr->timestamp(), limitsMsg.min_freq());
497 return true;
498 }
SuspendResumeEvent(const RawTraceEventInfo & event) const499 bool CpuDetailParser::SuspendResumeEvent(const RawTraceEventInfo &event) const
500 {
501 auto resumeMsg = event.msgPtr->suspend_resume_format();
502 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SUSPEND_RESUME, STAT_EVENT_RECEIVED);
503 int32_t val = resumeMsg.val();
504 uint32_t start = resumeMsg.start();
505 std::string action = resumeMsg.action();
506 Unused(val);
507 Unused(start);
508 Unused(action);
509 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_SUSPEND_RESUME, STAT_EVENT_NOTSUPPORTED);
510 return true;
511 }
WorkqueueExecuteStartEvent(const RawTraceEventInfo & event) const512 bool CpuDetailParser::WorkqueueExecuteStartEvent(const RawTraceEventInfo &event) const
513 {
514 auto executeStartMsg = event.msgPtr->workqueue_execute_start_format();
515 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_WORKQUEUE_EXECUTE_START, STAT_EVENT_RECEIVED);
516 auto funcNameIndex = traceDataCache_->GetSymbolsData()->GetFunc(executeStartMsg.function());
517 size_t result = INVALID_UINT32;
518 if (funcNameIndex == INVALID_UINT64) {
519 std::string addrStr = "0x" + base::number(executeStartMsg.function(), base::INTEGER_RADIX_TYPE_HEX);
520 auto addStrIndex = traceDataCache_->GetDataIndex(addrStr);
521 result = streamFilters_->sliceFilter_->BeginSlice(event.msgPtr->comm(), event.msgPtr->timestamp(), eventPid_,
522 eventPid_, workQueueIndex_, addStrIndex);
523 } else {
524 result = streamFilters_->sliceFilter_->BeginSlice(event.msgPtr->comm(), event.msgPtr->timestamp(), eventPid_,
525 eventPid_, workQueueIndex_, funcNameIndex);
526 }
527
528 traceDataCache_->GetInternalSlicesData()->AppendDistributeInfo();
529 if (result == INVALID_UINT32) {
530 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_WORKQUEUE_EXECUTE_START, STAT_EVENT_DATA_LOST);
531 }
532 return true;
533 }
WorkqueueExecuteEndEvent(const RawTraceEventInfo & event) const534 bool CpuDetailParser::WorkqueueExecuteEndEvent(const RawTraceEventInfo &event) const
535 {
536 auto executeEndMsg = event.msgPtr->workqueue_execute_end_format();
537 if (!streamFilters_->sliceFilter_->EndSlice(event.msgPtr->timestamp(), eventPid_, eventPid_, workQueueIndex_)) {
538 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_WORKQUEUE_EXECUTE_END, STAT_EVENT_NOTMATCH);
539 return false;
540 }
541 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_WORKQUEUE_EXECUTE_END, STAT_EVENT_RECEIVED);
542 return true;
543 }
IrqHandlerEntryEvent(const RawTraceEventInfo & event) const544 bool CpuDetailParser::IrqHandlerEntryEvent(const RawTraceEventInfo &event) const
545 {
546 auto irqEntryMsg = event.msgPtr->irq_handler_entry_format();
547 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_IRQ_HANDLER_ENTRY, STAT_EVENT_RECEIVED);
548 // The tostdstring() here cannot use temporary variables, which will cause occasional garbled characters under wasm
549 streamFilters_->irqFilter_->IrqHandlerEntry(event.msgPtr->timestamp(), event.cpuId,
550 traceDataCache_->GetDataIndex(irqEntryMsg.name()));
551 return true;
552 }
IrqHandlerExitEvent(const RawTraceEventInfo & event) const553 bool CpuDetailParser::IrqHandlerExitEvent(const RawTraceEventInfo &event) const
554 {
555 auto irqExitMsg = event.msgPtr->irq_handler_exit_format();
556 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_IRQ_HANDLER_EXIT, STAT_EVENT_RECEIVED);
557 streamFilters_->irqFilter_->IrqHandlerExit(event.msgPtr->timestamp(), event.cpuId, irqExitMsg.irq(),
558 static_cast<uint32_t>(irqExitMsg.ret()));
559 return true;
560 }
IpiHandlerEntryEvent(const RawTraceEventInfo & event) const561 bool CpuDetailParser::IpiHandlerEntryEvent(const RawTraceEventInfo &event) const
562 {
563 auto ipiEntryMsg = event.msgPtr->ipi_entry_format();
564 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_IPI_ENTRY, STAT_EVENT_RECEIVED);
565 streamFilters_->irqFilter_->IpiHandlerEntry(event.msgPtr->timestamp(), event.cpuId,
566 traceDataCache_->GetDataIndex(ipiEntryMsg.reason()));
567 return true;
568 }
IpiHandlerExitEvent(const RawTraceEventInfo & event) const569 bool CpuDetailParser::IpiHandlerExitEvent(const RawTraceEventInfo &event) const
570 {
571 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_IPI_EXIT, STAT_EVENT_RECEIVED);
572 streamFilters_->irqFilter_->IpiHandlerExit(event.msgPtr->timestamp(), event.cpuId);
573 return true;
574 }
SoftIrqEntryEvent(const RawTraceEventInfo & event) const575 bool CpuDetailParser::SoftIrqEntryEvent(const RawTraceEventInfo &event) const
576 {
577 auto softIrqEntryMsg = event.msgPtr->softirq_entry_format();
578 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_SOFTIRQ_ENTRY, STAT_EVENT_RECEIVED);
579 streamFilters_->irqFilter_->SoftIrqEntry(event.msgPtr->timestamp(), event.cpuId,
580 static_cast<uint32_t>(softIrqEntryMsg.vec()));
581 return true;
582 }
SoftIrqRaiseEvent(const RawTraceEventInfo & event) const583 bool CpuDetailParser::SoftIrqRaiseEvent(const RawTraceEventInfo &event) const
584 {
585 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_SOFTIRQ_RAISE, STAT_EVENT_RECEIVED);
586 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_SOFTIRQ_RAISE, STAT_EVENT_NOTSUPPORTED);
587 return true;
588 }
SoftIrqExitEvent(const RawTraceEventInfo & event) const589 bool CpuDetailParser::SoftIrqExitEvent(const RawTraceEventInfo &event) const
590 {
591 auto softIrqExitMsg = event.msgPtr->softirq_exit_format();
592 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_SOFTIRQ_EXIT, STAT_EVENT_RECEIVED);
593 streamFilters_->irqFilter_->SoftIrqExit(event.msgPtr->timestamp(), event.cpuId,
594 static_cast<uint32_t>(softIrqExitMsg.vec()));
595 return true;
596 }
SetRateEvent(const RawTraceEventInfo & event) const597 bool CpuDetailParser::SetRateEvent(const RawTraceEventInfo &event) const
598 {
599 auto clockSetRateMsg = event.msgPtr->clock_set_rate_format();
600 DataIndex nameIndex = traceDataCache_->GetDataIndex(clockSetRateMsg.name());
601 streamFilters_->clockRateFilter_->AppendNewMeasureData(clockSetRateMsg.cpu_id(), nameIndex,
602 event.msgPtr->timestamp(), clockSetRateMsg.state());
603 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CLOCK_SET_RATE, STAT_EVENT_RECEIVED);
604 return true;
605 }
ClockEnableEvent(const RawTraceEventInfo & event) const606 bool CpuDetailParser::ClockEnableEvent(const RawTraceEventInfo &event) const
607 {
608 auto clockEnableMsg = event.msgPtr->clock_enable_format();
609 DataIndex nameIndex = traceDataCache_->GetDataIndex(clockEnableMsg.name());
610 streamFilters_->clockEnableFilter_->AppendNewMeasureData(clockEnableMsg.cpu_id(), nameIndex,
611 event.msgPtr->timestamp(), clockEnableMsg.state());
612 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CLOCK_ENABLE, STAT_EVENT_RECEIVED);
613 return true;
614 }
ClockDisableEvent(const RawTraceEventInfo & event) const615 bool CpuDetailParser::ClockDisableEvent(const RawTraceEventInfo &event) const
616 {
617 auto clockDisableMsg = event.msgPtr->clock_disable_format();
618 DataIndex nameIndex = traceDataCache_->GetDataIndex(clockDisableMsg.name());
619 streamFilters_->clockDisableFilter_->AppendNewMeasureData(clockDisableMsg.cpu_id(), nameIndex,
620 event.msgPtr->timestamp(), clockDisableMsg.state());
621 streamFilters_->statFilter_->IncreaseStat(TRACE_EVENT_CLOCK_DISABLE, STAT_EVENT_RECEIVED);
622 return true;
623 }
RegulatorSetVoltageEvent(const RawTraceEventInfo & event) const624 bool CpuDetailParser::RegulatorSetVoltageEvent(const RawTraceEventInfo &event) const
625 {
626 Unused(event);
627 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_REGULATOR_SET_VOLTAGE, STAT_EVENT_NOTSUPPORTED);
628 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_REGULATOR_SET_VOLTAGE, STAT_EVENT_RECEIVED);
629 return true;
630 }
RegulatorSetVoltageCompleteEvent(const RawTraceEventInfo & event) const631 bool CpuDetailParser::RegulatorSetVoltageCompleteEvent(const RawTraceEventInfo &event) const
632 {
633 Unused(event);
634 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_REGULATOR_SET_VOLTAGE_COMPLETE,
635 STAT_EVENT_NOTSUPPORTED);
636 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_REGULATOR_SET_VOLTAGE_COMPLETE, STAT_EVENT_RECEIVED);
637 return true;
638 }
RegulatorDisableEvent(const RawTraceEventInfo & event) const639 bool CpuDetailParser::RegulatorDisableEvent(const RawTraceEventInfo &event) const
640 {
641 Unused(event);
642 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_REGULATOR_DISABLE, STAT_EVENT_NOTSUPPORTED);
643 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_REGULATOR_DISABLE, STAT_EVENT_RECEIVED);
644 return true;
645 }
RegulatorDisableCompleteEvent(const RawTraceEventInfo & event) const646 bool CpuDetailParser::RegulatorDisableCompleteEvent(const RawTraceEventInfo &event) const
647 {
648 Unused(event);
649 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_REGULATOR_DISABLE_COMPLETE, STAT_EVENT_NOTSUPPORTED);
650 traceDataCache_->GetStatAndInfo()->IncreaseStat(TRACE_EVENT_REGULATOR_DISABLE_COMPLETE, STAT_EVENT_RECEIVED);
651 return true;
652 }
653 } // namespace TraceStreamer
654 } // namespace SysTuning
655