106f6ba60Sopenharmony_ci/* 206f6ba60Sopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved. 306f6ba60Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 406f6ba60Sopenharmony_ci * you may not use this file except in compliance with the License. 506f6ba60Sopenharmony_ci * You may obtain a copy of the License at 606f6ba60Sopenharmony_ci * 706f6ba60Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 806f6ba60Sopenharmony_ci * 906f6ba60Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1006f6ba60Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1106f6ba60Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1206f6ba60Sopenharmony_ci * See the License for the specific language governing permissions and 1306f6ba60Sopenharmony_ci * limitations under the License. 1406f6ba60Sopenharmony_ci * 1506f6ba60Sopenharmony_ci * Description: FlowController implements 1606f6ba60Sopenharmony_ci */ 1706f6ba60Sopenharmony_ci#include "flow_controller.h" 1806f6ba60Sopenharmony_ci 1906f6ba60Sopenharmony_ci#include <algorithm> 2006f6ba60Sopenharmony_ci#include <cinttypes> 2106f6ba60Sopenharmony_ci#include <set> 2206f6ba60Sopenharmony_ci#include <sys/stat.h> 2306f6ba60Sopenharmony_ci#include <sys/types.h> 2406f6ba60Sopenharmony_ci#include <unistd.h> 2506f6ba60Sopenharmony_ci#include <regex> 2606f6ba60Sopenharmony_ci 2706f6ba60Sopenharmony_ci#include "file_utils.h" 2806f6ba60Sopenharmony_ci#include "ftrace_field_parser.h" 2906f6ba60Sopenharmony_ci#include "ftrace_fs_ops.h" 3006f6ba60Sopenharmony_ci#include "logging.h" 3106f6ba60Sopenharmony_ci#include "parameters.h" 3206f6ba60Sopenharmony_ci 3306f6ba60Sopenharmony_cinamespace { 3406f6ba60Sopenharmony_ciusing namespace OHOS::Developtools::Profiler; 3506f6ba60Sopenharmony_ci#ifndef PAGE_SIZE 3606f6ba60Sopenharmony_ci constexpr uint32_t PAGE_SIZE = 4096; 3706f6ba60Sopenharmony_ci#endif 3806f6ba60Sopenharmony_ci constexpr int KB_PER_PAGE = PAGE_SIZE / 1024; 3906f6ba60Sopenharmony_ci constexpr uint32_t BYTE_PER_KB = 1024; 4006f6ba60Sopenharmony_ci constexpr uint32_t MAX_FLUSH_INTERVAL = 1800 * 1000; 4106f6ba60Sopenharmony_ci constexpr uint32_t MAX_FLUSH_THRESHOLD = 128 * 1024 * 1024; 4206f6ba60Sopenharmony_ci constexpr uint32_t MAX_TRACE_PERIOD_MS = 720 * 1000; 4306f6ba60Sopenharmony_ci constexpr uint32_t MAX_BUFFER_SIZE_KB = 64 * 1024; // 64MB 4406f6ba60Sopenharmony_ci constexpr uint32_t HM_MAX_BUFFER_SIZE_KB = 512 * 1024; // 512MB 4506f6ba60Sopenharmony_ci constexpr uint32_t MIN_BUFFER_SIZE_KB = 1024; // 1 MB 4606f6ba60Sopenharmony_ci constexpr uint32_t DEFAULT_TRACE_PERIOD_MS = 250; // 250 ms 4706f6ba60Sopenharmony_ci constexpr uint32_t MAX_BLOCK_SIZE_PAGES = 4096; // 16 MB 4806f6ba60Sopenharmony_ci constexpr uint32_t MIN_BLOCK_SIZE_PAGES = 256; // 1 MB 4906f6ba60Sopenharmony_ci constexpr uint32_t PARSE_CMDLINE_COUNT = 1000; 5006f6ba60Sopenharmony_ci const std::set<std::string> g_availableClocks = { "boot", "global", "local", "mono" }; 5106f6ba60Sopenharmony_ci constexpr uint32_t SAVED_CMDLINE_SIZE_SMALL = 1024; // save cmdline sizes for cpu num less than 8 5206f6ba60Sopenharmony_ci constexpr uint32_t SAVED_CMDLINE_SIZE_LARGE = 4096; // save cmdline sizes for cpu num no less than 8 5306f6ba60Sopenharmony_ci constexpr int OCTA_CORE_CPU = 8; // 8 core 5406f6ba60Sopenharmony_ci constexpr unsigned int RMQ_ENTRY_ALIGN_MASK = (1U << 2) - 1; 5506f6ba60Sopenharmony_ci const std::string TRACE_PROPERTY = "debug.hitrace.tags.enableflags"; 5606f6ba60Sopenharmony_ci const std::string BGSRV_PROPERTY = "5456538433239656448"; 5706f6ba60Sopenharmony_ci} // namespace 5806f6ba60Sopenharmony_ci 5906f6ba60Sopenharmony_ciFTRACE_NS_BEGIN 6006f6ba60Sopenharmony_ciFlowController::FlowController() 6106f6ba60Sopenharmony_ci{ 6206f6ba60Sopenharmony_ci ftraceParser_ = std::make_unique<FtraceParser>(); 6306f6ba60Sopenharmony_ci ksymsParser_ = std::make_unique<KernelSymbolsParser>(); 6406f6ba60Sopenharmony_ci ftraceSupported_ = FtraceFsOps::GetInstance().GetFtraceRoot().size() > 0; 6506f6ba60Sopenharmony_ci traceCollector_ = OHOS::HiviewDFX::UCollectClient::TraceCollector::Create(); 6606f6ba60Sopenharmony_ci} 6706f6ba60Sopenharmony_ci 6806f6ba60Sopenharmony_ciFlowController::~FlowController(void) 6906f6ba60Sopenharmony_ci{ 7006f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "FlowController destroy!"); 7106f6ba60Sopenharmony_ci} 7206f6ba60Sopenharmony_ci 7306f6ba60Sopenharmony_ciint FlowController::SetWriter(const WriterStructPtr& writer) 7406f6ba60Sopenharmony_ci{ 7506f6ba60Sopenharmony_ci CHECK_TRUE(ftraceSupported_, -1, "current kernel not support ftrace!"); 7606f6ba60Sopenharmony_ci CHECK_TRUE(resultWriter_ == nullptr, 0, "writer already setted!"); 7706f6ba60Sopenharmony_ci 7806f6ba60Sopenharmony_ci CHECK_NOTNULL(writer, -1, "writer null!"); 7906f6ba60Sopenharmony_ci auto transmiter = std::make_unique<ResultTransporter>("Transporter", writer); 8006f6ba60Sopenharmony_ci CHECK_NOTNULL(transmiter, -1, "create ResultTransporter FAILED!"); 8106f6ba60Sopenharmony_ci 8206f6ba60Sopenharmony_ci // get CPU core numbers 8306f6ba60Sopenharmony_ci int nprocs = static_cast<int>(sysconf(_SC_NPROCESSORS_ONLN)); 8406f6ba60Sopenharmony_ci CHECK_TRUE(nprocs > 0, -1, "get processor number failed!"); 8506f6ba60Sopenharmony_ci platformCpuNum_ = nprocs; 8606f6ba60Sopenharmony_ci 8706f6ba60Sopenharmony_ci // init FtraceParser 8806f6ba60Sopenharmony_ci CHECK_NOTNULL(ftraceParser_, 0, "FtraceParser create FAILED!"); 8906f6ba60Sopenharmony_ci CHECK_TRUE(ftraceParser_->Init(), -1, "ftrace parser init failed!"); 9006f6ba60Sopenharmony_ci 9106f6ba60Sopenharmony_ci // init KernelSymbolsParser 9206f6ba60Sopenharmony_ci CHECK_NOTNULL(ksymsParser_, 0, "KernelSymbolsParser create FAILED!"); 9306f6ba60Sopenharmony_ci ksymsParser_->Parse(FtraceFsOps::GetInstance().GetKernelSymbols()); 9406f6ba60Sopenharmony_ci 9506f6ba60Sopenharmony_ci CHECK_TRUE(AddPlatformEventsToParser(), -1, "add platform events to parser failed!"); 9606f6ba60Sopenharmony_ci // disable all trace events 9706f6ba60Sopenharmony_ci DisableAllCategories(); 9806f6ba60Sopenharmony_ci 9906f6ba60Sopenharmony_ci resultWriter_ = writer; 10006f6ba60Sopenharmony_ci tansporter_ = std::move(transmiter); 10106f6ba60Sopenharmony_ci return 0; 10206f6ba60Sopenharmony_ci} 10306f6ba60Sopenharmony_ci 10406f6ba60Sopenharmony_cibool FlowController::CreateRawDataReaders() 10506f6ba60Sopenharmony_ci{ 10606f6ba60Sopenharmony_ci if (FtraceFsOps::GetInstance().IsHmKernel()) { 10706f6ba60Sopenharmony_ci auto reader = std::make_unique<FtraceDataReader>(FtraceFsOps::GetInstance().GetHmRawTracePath()); 10806f6ba60Sopenharmony_ci CHECK_NOTNULL(reader, false, "create hm raw trace reader FAILED!"); 10906f6ba60Sopenharmony_ci ftraceReaders_.emplace_back(std::move(reader)); 11006f6ba60Sopenharmony_ci return true; 11106f6ba60Sopenharmony_ci } 11206f6ba60Sopenharmony_ci 11306f6ba60Sopenharmony_ci for (int i = 0; i < platformCpuNum_; i++) { 11406f6ba60Sopenharmony_ci auto rawPath = FtraceFsOps::GetInstance().GetRawTracePath(i); 11506f6ba60Sopenharmony_ci if (fakePath_ != "") { 11606f6ba60Sopenharmony_ci rawPath = fakePath_ + "test_raw_" + std::to_string(i); 11706f6ba60Sopenharmony_ci CHECK_NOTNULL(ftraceParser_, false, "create FtraceParser FAILED!"); 11806f6ba60Sopenharmony_ci ftraceParser_->ParseSavedCmdlines(FileUtils::ReadFile(fakePath_ + "test_comm")); 11906f6ba60Sopenharmony_ci ftraceParser_->ParseSavedTgid(FileUtils::ReadFile(fakePath_ + "test_tgid")); 12006f6ba60Sopenharmony_ci } 12106f6ba60Sopenharmony_ci auto reader = std::make_unique<FtraceDataReader>(rawPath); 12206f6ba60Sopenharmony_ci CHECK_NOTNULL(reader, false, "create reader %d FAILED!", i); 12306f6ba60Sopenharmony_ci ftraceReaders_.emplace_back(std::move(reader)); 12406f6ba60Sopenharmony_ci } 12506f6ba60Sopenharmony_ci return true; 12606f6ba60Sopenharmony_ci} 12706f6ba60Sopenharmony_ci 12806f6ba60Sopenharmony_cibool FlowController::CreatePagedMemoryPool() 12906f6ba60Sopenharmony_ci{ 13006f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "create memory pool, buffer_size_kb = %u", bufferSizeKb_); 13106f6ba60Sopenharmony_ci if (KB_PER_PAGE == 0 || platformCpuNum_ == 0) { 13206f6ba60Sopenharmony_ci return false; 13306f6ba60Sopenharmony_ci } 13406f6ba60Sopenharmony_ci size_t bufferSizePages = bufferSizeKb_ / KB_PER_PAGE; 13506f6ba60Sopenharmony_ci size_t pagesPerBlock = bufferSizePages / static_cast<size_t>(platformCpuNum_); 13606f6ba60Sopenharmony_ci if (pagesPerBlock < MIN_BLOCK_SIZE_PAGES) { 13706f6ba60Sopenharmony_ci pagesPerBlock = MIN_BLOCK_SIZE_PAGES; 13806f6ba60Sopenharmony_ci } 13906f6ba60Sopenharmony_ci if (pagesPerBlock > MAX_BLOCK_SIZE_PAGES) { 14006f6ba60Sopenharmony_ci pagesPerBlock = MAX_BLOCK_SIZE_PAGES; 14106f6ba60Sopenharmony_ci } 14206f6ba60Sopenharmony_ci 14306f6ba60Sopenharmony_ci if (FtraceFsOps::GetInstance().IsHmKernel()) { 14406f6ba60Sopenharmony_ci memPool_ = std::make_unique<PagedMemPool>(bufferSizePages, 1); 14506f6ba60Sopenharmony_ci } else { 14606f6ba60Sopenharmony_ci memPool_ = std::make_unique<PagedMemPool>(pagesPerBlock, platformCpuNum_); 14706f6ba60Sopenharmony_ci } 14806f6ba60Sopenharmony_ci CHECK_NOTNULL(memPool_, false, "create PagedMemPool FAILED!"); 14906f6ba60Sopenharmony_ci return true; 15006f6ba60Sopenharmony_ci} 15106f6ba60Sopenharmony_ci 15206f6ba60Sopenharmony_cibool FlowController::CreateRawDataBuffers() 15306f6ba60Sopenharmony_ci{ 15406f6ba60Sopenharmony_ci int num = platformCpuNum_; 15506f6ba60Sopenharmony_ci if (FtraceFsOps::GetInstance().IsHmKernel()) { 15606f6ba60Sopenharmony_ci num = 1; 15706f6ba60Sopenharmony_ci } 15806f6ba60Sopenharmony_ci for (int i = 0; i < num; i++) { 15906f6ba60Sopenharmony_ci using u8ptr = std::unique_ptr<uint8_t>::pointer; 16006f6ba60Sopenharmony_ci auto buffer = std::shared_ptr<uint8_t>(reinterpret_cast<u8ptr>(memPool_->Allocate()), 16106f6ba60Sopenharmony_ci [&](u8ptr block) { this->memPool_->Recycle(block); }); 16206f6ba60Sopenharmony_ci CHECK_NOTNULL(buffer, false, "create buffer %d failed!", i); 16306f6ba60Sopenharmony_ci ftraceBuffers_.push_back(buffer); 16406f6ba60Sopenharmony_ci }; 16506f6ba60Sopenharmony_ci return true; 16606f6ba60Sopenharmony_ci} 16706f6ba60Sopenharmony_ci 16806f6ba60Sopenharmony_cibool FlowController::CreateRawDataCaches() 16906f6ba60Sopenharmony_ci{ 17006f6ba60Sopenharmony_ci char fileName[] = "/data/local/tmp/ftrace_rawdata.XXXXXX"; 17106f6ba60Sopenharmony_ci CHECK_TRUE(mkstemp(fileName) >= 0, false, "Create temp file failed!"); 17206f6ba60Sopenharmony_ci rawDataFile_ = std::shared_ptr<FILE>(fopen(fileName, "wb+"), [](FILE* fp) { fclose(fp); }); 17306f6ba60Sopenharmony_ci unlink(fileName); 17406f6ba60Sopenharmony_ci return true; 17506f6ba60Sopenharmony_ci} 17606f6ba60Sopenharmony_ci 17706f6ba60Sopenharmony_cibool FlowController::ParseBasicData() 17806f6ba60Sopenharmony_ci{ 17906f6ba60Sopenharmony_ci CHECK_NOTNULL(resultWriter_, false, "%s: resultWriter_ nullptr", __func__); 18006f6ba60Sopenharmony_ci // get clock times 18106f6ba60Sopenharmony_ci if (getClockTimes_) { 18206f6ba60Sopenharmony_ci if (resultWriter_->isProtobufSerialize) { 18306f6ba60Sopenharmony_ci auto traceResult = std::make_unique<TracePluginResult>(); 18406f6ba60Sopenharmony_ci CHECK_TRUE(ReportClockTimes(traceResult), false, "parse clock times FAILED!"); 18506f6ba60Sopenharmony_ci CHECK_TRUE(tansporter_->Submit(std::move(traceResult)), false, "report clock times FAILED!"); 18606f6ba60Sopenharmony_ci } else { 18706f6ba60Sopenharmony_ci auto ctx = resultWriter_->startReport(resultWriter_); 18806f6ba60Sopenharmony_ci CHECK_NOTNULL(ctx, false, "%s: get RandomWriteCtx FAILED!", __func__); 18906f6ba60Sopenharmony_ci auto traceResult = std::make_unique<ProtoEncoder::TracePluginResult>(ctx); 19006f6ba60Sopenharmony_ci CHECK_TRUE(ReportClockTimes(traceResult), false, "parse clock times FAILED!"); 19106f6ba60Sopenharmony_ci int32_t msgSize = traceResult->Finish(); 19206f6ba60Sopenharmony_ci resultWriter_->finishReport(resultWriter_, msgSize); 19306f6ba60Sopenharmony_ci tansporter_->Report(static_cast<size_t>(msgSize)); 19406f6ba60Sopenharmony_ci } 19506f6ba60Sopenharmony_ci } 19606f6ba60Sopenharmony_ci 19706f6ba60Sopenharmony_ci // parse kernel symbols 19806f6ba60Sopenharmony_ci if (parseKsyms_) { 19906f6ba60Sopenharmony_ci if (resultWriter_->isProtobufSerialize) { 20006f6ba60Sopenharmony_ci auto traceResult = std::make_unique<TracePluginResult>(); 20106f6ba60Sopenharmony_ci CHECK_TRUE(ParseKernelSymbols(traceResult), false, "parse kernel symbols FAILED!"); 20206f6ba60Sopenharmony_ci CHECK_TRUE(tansporter_->Submit(std::move(traceResult)), false, "report kernel symbols FAILED!"); 20306f6ba60Sopenharmony_ci } else { 20406f6ba60Sopenharmony_ci auto ctx = resultWriter_->startReport(resultWriter_); 20506f6ba60Sopenharmony_ci CHECK_NOTNULL(ctx, false, "%s: get RandomWriteCtx FAILED!", __func__); 20606f6ba60Sopenharmony_ci auto traceResult = std::make_unique<ProtoEncoder::TracePluginResult>(ctx); 20706f6ba60Sopenharmony_ci CHECK_TRUE(ParseKernelSymbols(traceResult), false, "parse kernel symbols FAILED!"); 20806f6ba60Sopenharmony_ci int32_t msgSize = traceResult->Finish(); 20906f6ba60Sopenharmony_ci resultWriter_->finishReport(resultWriter_, msgSize); 21006f6ba60Sopenharmony_ci tansporter_->Report(static_cast<size_t>(msgSize)); 21106f6ba60Sopenharmony_ci } 21206f6ba60Sopenharmony_ci } 21306f6ba60Sopenharmony_ci if (resultWriter_->isProtobufSerialize) { 21406f6ba60Sopenharmony_ci auto traceResult = std::make_unique<TracePluginResult>(); 21506f6ba60Sopenharmony_ci CHECK_TRUE(ParsePerCpuStatus(traceResult, TRACE_START), false, "parse TRACE_START stats failed!"); 21606f6ba60Sopenharmony_ci CHECK_TRUE(tansporter_->Submit(std::move(traceResult)), false, "report TRACE_START stats failed!"); 21706f6ba60Sopenharmony_ci } else { 21806f6ba60Sopenharmony_ci auto ctx = resultWriter_->startReport(resultWriter_); 21906f6ba60Sopenharmony_ci CHECK_NOTNULL(ctx, false, "%s: get RandomWriteCtx FAILED!", __func__); 22006f6ba60Sopenharmony_ci auto traceResult = std::make_unique<ProtoEncoder::TracePluginResult>(ctx); 22106f6ba60Sopenharmony_ci CHECK_TRUE(ParsePerCpuStatus(traceResult, TRACE_START), false, "parse TRACE_START stats failed!"); 22206f6ba60Sopenharmony_ci int32_t msgSize = traceResult->Finish(); 22306f6ba60Sopenharmony_ci resultWriter_->finishReport(resultWriter_, msgSize); 22406f6ba60Sopenharmony_ci tansporter_->Report(static_cast<size_t>(msgSize)); 22506f6ba60Sopenharmony_ci } 22606f6ba60Sopenharmony_ci return true; 22706f6ba60Sopenharmony_ci} 22806f6ba60Sopenharmony_ci 22906f6ba60Sopenharmony_cistd::string FlowController::ReloadTraceArgs() 23006f6ba60Sopenharmony_ci{ 23106f6ba60Sopenharmony_ci std::string args; 23206f6ba60Sopenharmony_ci for (size_t i = 0; i < traceCategories_.size(); i++) { 23306f6ba60Sopenharmony_ci if (i == 0) { 23406f6ba60Sopenharmony_ci args += ("tags:" + traceCategories_[i]); 23506f6ba60Sopenharmony_ci } else { 23606f6ba60Sopenharmony_ci args += ("," + traceCategories_[i]); 23706f6ba60Sopenharmony_ci } 23806f6ba60Sopenharmony_ci } 23906f6ba60Sopenharmony_ci 24006f6ba60Sopenharmony_ci if (traceClock_.size() > 0) { 24106f6ba60Sopenharmony_ci args += (" clockType:" + traceClock_); 24206f6ba60Sopenharmony_ci } 24306f6ba60Sopenharmony_ci 24406f6ba60Sopenharmony_ci if (bufferSizeKb_ > 0) { 24506f6ba60Sopenharmony_ci args += (" bufferSize:" + std::to_string(bufferSizeKb_)); 24606f6ba60Sopenharmony_ci } 24706f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "trace args: %s", args.c_str()); 24806f6ba60Sopenharmony_ci return args; 24906f6ba60Sopenharmony_ci} 25006f6ba60Sopenharmony_ci 25106f6ba60Sopenharmony_ciint FlowController::StartCapture(void) 25206f6ba60Sopenharmony_ci{ 25306f6ba60Sopenharmony_ci CHECK_TRUE(ftraceSupported_, -1, "current kernel not support ftrace!"); 25406f6ba60Sopenharmony_ci CHECK_NOTNULL(ftraceParser_, -1, "create FtraceParser FAILED!"); 25506f6ba60Sopenharmony_ci CHECK_NOTNULL(ksymsParser_, -1, "create KernelSymbolsParser FAILED!"); 25606f6ba60Sopenharmony_ci CHECK_NOTNULL(tansporter_, -1, "create ResultTransporter FAILED!"); 25706f6ba60Sopenharmony_ci CHECK_NOTNULL(traceCollector_, -1, "create TraceCollector FAILED!"); 25806f6ba60Sopenharmony_ci CHECK_NOTNULL(resultWriter_, -1, "%s: resultWriter_ nullptr", __func__); 25906f6ba60Sopenharmony_ci 26006f6ba60Sopenharmony_ci CHECK_TRUE(ParseBasicData(), -1, "parse basic data failed!"); 26106f6ba60Sopenharmony_ci 26206f6ba60Sopenharmony_ci // create memory pool, and raw data readers, buffers, caches. 26306f6ba60Sopenharmony_ci CHECK_TRUE(CreatePagedMemoryPool(), -1, "create paged memory pool failed!"); 26406f6ba60Sopenharmony_ci CHECK_TRUE(CreateRawDataReaders(), -1, "create raw data readers failed!"); 26506f6ba60Sopenharmony_ci CHECK_TRUE(CreateRawDataBuffers(), -1, "create raw data buffers failed!"); 26606f6ba60Sopenharmony_ci 26706f6ba60Sopenharmony_ci // clear old trace 26806f6ba60Sopenharmony_ci FtraceFsOps::GetInstance().ClearTraceBuffer(); 26906f6ba60Sopenharmony_ci // recover the hitrace 27006f6ba60Sopenharmony_ci std::string param = OHOS::system::GetParameter(TRACE_PROPERTY, ""); 27106f6ba60Sopenharmony_ci if (param != "0" && param != BGSRV_PROPERTY) { 27206f6ba60Sopenharmony_ci traceCollector_->Recover(); 27306f6ba60Sopenharmony_ci } 27406f6ba60Sopenharmony_ci 27506f6ba60Sopenharmony_ci uint32_t savedCmdlinesSize = platformCpuNum_ < OCTA_CORE_CPU ? SAVED_CMDLINE_SIZE_SMALL : SAVED_CMDLINE_SIZE_LARGE; 27606f6ba60Sopenharmony_ci if (!FtraceFsOps::GetInstance().SetSavedCmdLinesSize(savedCmdlinesSize)) { 27706f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, "SetSavedCmdLinesSize %u fail.", savedCmdlinesSize); 27806f6ba60Sopenharmony_ci } 27906f6ba60Sopenharmony_ci 28006f6ba60Sopenharmony_ci // enable additional record options 28106f6ba60Sopenharmony_ci FtraceFsOps::GetInstance().SetRecordCmdOption(true); 28206f6ba60Sopenharmony_ci FtraceFsOps::GetInstance().SetRecordTgidOption(true); 28306f6ba60Sopenharmony_ci 28406f6ba60Sopenharmony_ci // start ftrace event data polling thread 28506f6ba60Sopenharmony_ci keepRunning_ = true; 28606f6ba60Sopenharmony_ci 28706f6ba60Sopenharmony_ci if (parseMode_ == TracePluginConfig_ParseMode_NORMAL) { 28806f6ba60Sopenharmony_ci pollThread_ = std::thread([this] { this->CaptureWorkOnNomalMode(); }); 28906f6ba60Sopenharmony_ci } else if (parseMode_ == TracePluginConfig_ParseMode_DELAY_PARSE) { 29006f6ba60Sopenharmony_ci CHECK_TRUE(CreateRawDataCaches(), -1, "create raw data caches failed!"); 29106f6ba60Sopenharmony_ci pollThread_ = std::thread([this] { this->CaptureWorkOnDelayMode(); }); 29206f6ba60Sopenharmony_ci } else { 29306f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, "ParseMode is Illegal parameter!"); 29406f6ba60Sopenharmony_ci return -1; 29506f6ba60Sopenharmony_ci } 29606f6ba60Sopenharmony_ci 29706f6ba60Sopenharmony_ci // set trace_clock and enable all tag categories with hiview::TraceCollector 29806f6ba60Sopenharmony_ci auto openRet = traceCollector_->OpenRecording(ReloadTraceArgs()); 29906f6ba60Sopenharmony_ci if (openRet.retCode != OHOS::HiviewDFX::UCollect::UcError::SUCCESS) { 30006f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, "Enable tag categories failed, trace error code is %d!", openRet.retCode); 30106f6ba60Sopenharmony_ci return -1; 30206f6ba60Sopenharmony_ci } 30306f6ba60Sopenharmony_ci EnableTraceEvents(); 30406f6ba60Sopenharmony_ci return 0; 30506f6ba60Sopenharmony_ci} 30606f6ba60Sopenharmony_ci 30706f6ba60Sopenharmony_civoid FlowController::CaptureWorkOnNomalModeInner() 30806f6ba60Sopenharmony_ci{ 30906f6ba60Sopenharmony_ci pthread_setname_np(pthread_self(), "TraceReader"); 31006f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "FlowController::CaptureWorkOnNomalMode start!"); 31106f6ba60Sopenharmony_ci auto tracePeriod = std::chrono::milliseconds(tracePeriodMs_); 31206f6ba60Sopenharmony_ci std::vector<long> rawDataBytes(platformCpuNum_, 0); 31306f6ba60Sopenharmony_ci while (keepRunning_) { 31406f6ba60Sopenharmony_ci std::this_thread::sleep_for(tracePeriod); 31506f6ba60Sopenharmony_ci // read data from percpu trace_pipe_raw, consume kernel ring buffers 31606f6ba60Sopenharmony_ci for (size_t i = 0; i < rawDataBytes.size(); i++) { 31706f6ba60Sopenharmony_ci if (flushCacheData_ && !keepRunning_) { 31806f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "flushCacheData_ is true, return"); 31906f6ba60Sopenharmony_ci return; 32006f6ba60Sopenharmony_ci } 32106f6ba60Sopenharmony_ci long nbytes = ReadEventData(i); 32206f6ba60Sopenharmony_ci rawDataBytes[i] = nbytes; 32306f6ba60Sopenharmony_ci } 32406f6ba60Sopenharmony_ci // parse ftrace metadata 32506f6ba60Sopenharmony_ci ftraceParser_->ParseSavedCmdlines(FtraceFsOps::GetInstance().GetSavedCmdLines()); 32606f6ba60Sopenharmony_ci // parse ftrace percpu event data 32706f6ba60Sopenharmony_ci for (size_t i = 0; i < rawDataBytes.size(); i++) { 32806f6ba60Sopenharmony_ci if (flushCacheData_ && !keepRunning_) { 32906f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "flushCacheData_ is true, return"); 33006f6ba60Sopenharmony_ci return; 33106f6ba60Sopenharmony_ci } 33206f6ba60Sopenharmony_ci if (rawDataBytes[i] == 0) { 33306f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "Get raw data from CPU%zu is 0 bytes.", i); 33406f6ba60Sopenharmony_ci continue; 33506f6ba60Sopenharmony_ci } 33606f6ba60Sopenharmony_ci if (!ParseEventDataOnNomalMode(i, rawDataBytes[i])) { 33706f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, "%s:ParseEventData failed!", __func__); 33806f6ba60Sopenharmony_ci } 33906f6ba60Sopenharmony_ci } 34006f6ba60Sopenharmony_ci if (isReportBasicData_.load()) { 34106f6ba60Sopenharmony_ci ParseBasicData(); 34206f6ba60Sopenharmony_ci isReportBasicData_ = false; 34306f6ba60Sopenharmony_ci } 34406f6ba60Sopenharmony_ci } 34506f6ba60Sopenharmony_ci tansporter_->Flush(); 34606f6ba60Sopenharmony_ci PROFILER_LOG_DEBUG(LOG_CORE, "FlowController::CaptureWorkOnNomalMode done!"); 34706f6ba60Sopenharmony_ci} 34806f6ba60Sopenharmony_ci 34906f6ba60Sopenharmony_cilong FlowController::HmReadEventData() 35006f6ba60Sopenharmony_ci{ 35106f6ba60Sopenharmony_ci auto buffer = ftraceBuffers_[0].get(); 35206f6ba60Sopenharmony_ci auto reader = ftraceReaders_[0].get(); 35306f6ba60Sopenharmony_ci auto bufferSize = static_cast<long>(memPool_->GetBlockSize()); 35406f6ba60Sopenharmony_ci 35506f6ba60Sopenharmony_ci long nbytes = 0; 35606f6ba60Sopenharmony_ci long used = 0; 35706f6ba60Sopenharmony_ci long rest = bufferSize; 35806f6ba60Sopenharmony_ci while ((nbytes = reader->Read(&buffer[used], rest)) > 0 && used < bufferSize) { 35906f6ba60Sopenharmony_ci used += nbytes; 36006f6ba60Sopenharmony_ci rest -= nbytes; 36106f6ba60Sopenharmony_ci } 36206f6ba60Sopenharmony_ci if (used == bufferSize) { 36306f6ba60Sopenharmony_ci PROFILER_LOG_WARN(LOG_CORE, "hm trace raw data may overwrite. current buffer size = %u.", 36406f6ba60Sopenharmony_ci (unsigned int)bufferSize); 36506f6ba60Sopenharmony_ci } 36606f6ba60Sopenharmony_ci return used; 36706f6ba60Sopenharmony_ci} 36806f6ba60Sopenharmony_ci 36906f6ba60Sopenharmony_civoid FlowController::HmCaptureWorkOnNomalModeInner() 37006f6ba60Sopenharmony_ci{ 37106f6ba60Sopenharmony_ci pthread_setname_np(pthread_self(), "HmTraceReader"); 37206f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "FlowController::HmCaptureWorkOnNomalMode start!"); 37306f6ba60Sopenharmony_ci auto tracePeriod = std::chrono::milliseconds(tracePeriodMs_); 37406f6ba60Sopenharmony_ci while (keepRunning_) { 37506f6ba60Sopenharmony_ci std::this_thread::sleep_for(tracePeriod); 37606f6ba60Sopenharmony_ci if (flushCacheData_ && !keepRunning_) { 37706f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "flushCacheData_ is true, return"); 37806f6ba60Sopenharmony_ci return; 37906f6ba60Sopenharmony_ci } 38006f6ba60Sopenharmony_ci long rawDataBytes = HmReadEventData(); 38106f6ba60Sopenharmony_ci ftraceParser_->ParseSavedCmdlines(FtraceFsOps::GetInstance().GetSavedCmdLines()); 38206f6ba60Sopenharmony_ci if (flushCacheData_ && !keepRunning_) { 38306f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "flushCacheData_ is true, return"); 38406f6ba60Sopenharmony_ci return; 38506f6ba60Sopenharmony_ci } 38606f6ba60Sopenharmony_ci if (rawDataBytes == 0) { 38706f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "Get hm raw data is 0 bytes."); 38806f6ba60Sopenharmony_ci continue; 38906f6ba60Sopenharmony_ci } 39006f6ba60Sopenharmony_ci if (!HmParseEventDataOnNomalMode(rawDataBytes)) { 39106f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, "HmParseEventData failed!"); 39206f6ba60Sopenharmony_ci } 39306f6ba60Sopenharmony_ci } 39406f6ba60Sopenharmony_ci tansporter_->Flush(); 39506f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "FlowController::HmCaptureWorkOnNomalMode done!"); 39606f6ba60Sopenharmony_ci} 39706f6ba60Sopenharmony_ci 39806f6ba60Sopenharmony_civoid FlowController::CaptureWorkOnNomalMode() 39906f6ba60Sopenharmony_ci{ 40006f6ba60Sopenharmony_ci if (FtraceFsOps::GetInstance().IsHmKernel()) { 40106f6ba60Sopenharmony_ci HmCaptureWorkOnNomalModeInner(); 40206f6ba60Sopenharmony_ci } else { 40306f6ba60Sopenharmony_ci CaptureWorkOnNomalModeInner(); 40406f6ba60Sopenharmony_ci } 40506f6ba60Sopenharmony_ci} 40606f6ba60Sopenharmony_ci 40706f6ba60Sopenharmony_civoid FlowController::CaptureWorkOnDelayMode() 40806f6ba60Sopenharmony_ci{ 40906f6ba60Sopenharmony_ci pthread_setname_np(pthread_self(), "TraceReader"); 41006f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "FlowController::CaptureWorkOnDelayMode start!"); 41106f6ba60Sopenharmony_ci 41206f6ba60Sopenharmony_ci auto tracePeriod = std::chrono::milliseconds(tracePeriodMs_); 41306f6ba60Sopenharmony_ci int writeDataCount = 0; 41406f6ba60Sopenharmony_ci while (keepRunning_) { 41506f6ba60Sopenharmony_ci std::this_thread::sleep_for(tracePeriod); 41606f6ba60Sopenharmony_ci 41706f6ba60Sopenharmony_ci // read data from percpu trace_pipe_raw, consume kernel ring buffers 41806f6ba60Sopenharmony_ci for (int cpuIdx = 0; cpuIdx < platformCpuNum_; cpuIdx++) { 41906f6ba60Sopenharmony_ci if (flushCacheData_ && !keepRunning_) { 42006f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "flushCacheData_ is true, return"); 42106f6ba60Sopenharmony_ci return; 42206f6ba60Sopenharmony_ci } 42306f6ba60Sopenharmony_ci long nbytes = ReadEventData(cpuIdx); 42406f6ba60Sopenharmony_ci if (nbytes == 0) { 42506f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "Get raw data from CPU%d is 0 bytes.", cpuIdx); 42606f6ba60Sopenharmony_ci continue; 42706f6ba60Sopenharmony_ci } 42806f6ba60Sopenharmony_ci fwrite(&cpuIdx, sizeof(uint8_t), 1, rawDataFile_.get()); 42906f6ba60Sopenharmony_ci fwrite(&nbytes, sizeof(long), 1, rawDataFile_.get()); 43006f6ba60Sopenharmony_ci fwrite(ftraceBuffers_[cpuIdx].get(), sizeof(uint8_t), nbytes, rawDataFile_.get()); 43106f6ba60Sopenharmony_ci } 43206f6ba60Sopenharmony_ci writeDataCount++; 43306f6ba60Sopenharmony_ci if (writeDataCount == PARSE_CMDLINE_COUNT) { 43406f6ba60Sopenharmony_ci // parse ftrace metadata 43506f6ba60Sopenharmony_ci ftraceParser_->ParseSavedCmdlines(FtraceFsOps::GetInstance().GetSavedCmdLines()); 43606f6ba60Sopenharmony_ci writeDataCount = 0; 43706f6ba60Sopenharmony_ci } 43806f6ba60Sopenharmony_ci } 43906f6ba60Sopenharmony_ci 44006f6ba60Sopenharmony_ci CHECK_TRUE(ParseEventDataOnDelayMode(), NO_RETVAL, "ParseEventData failed!"); 44106f6ba60Sopenharmony_ci tansporter_->Flush(); 44206f6ba60Sopenharmony_ci PROFILER_LOG_DEBUG(LOG_CORE, "FlowController::CaptureWorkOnDelayMode done!"); 44306f6ba60Sopenharmony_ci} 44406f6ba60Sopenharmony_ci 44506f6ba60Sopenharmony_cistatic inline int RmqEntryTotalSize(unsigned int size) 44606f6ba60Sopenharmony_ci{ 44706f6ba60Sopenharmony_ci return sizeof(struct RmqEntry) + ((size + RMQ_ENTRY_ALIGN_MASK) & (~RMQ_ENTRY_ALIGN_MASK)); 44806f6ba60Sopenharmony_ci} 44906f6ba60Sopenharmony_ci 45006f6ba60Sopenharmony_citemplate <typename T, typename E> 45106f6ba60Sopenharmony_cibool FlowController::HmParseEventData(T* traceResult, uint8_t*& data, E* ftraceEvent) 45206f6ba60Sopenharmony_ci{ 45306f6ba60Sopenharmony_ci struct RmqConsumerData* rmqData = reinterpret_cast<struct RmqConsumerData*>(data); 45406f6ba60Sopenharmony_ci uint64_t timeStampBase = rmqData->timeStamp; 45506f6ba60Sopenharmony_ci auto cpuDetailMsg = traceResult->add_ftrace_cpu_detail(); 45606f6ba60Sopenharmony_ci struct RmqEntry* event; 45706f6ba60Sopenharmony_ci cpuDetailMsg->set_cpu(rmqData->coreId); 45806f6ba60Sopenharmony_ci cpuDetailMsg->set_overwrite(0); 45906f6ba60Sopenharmony_ci auto curPtr = rmqData->data; 46006f6ba60Sopenharmony_ci auto endPtr = rmqData->data + rmqData->length; 46106f6ba60Sopenharmony_ci while (curPtr < endPtr) { 46206f6ba60Sopenharmony_ci event = reinterpret_cast<struct RmqEntry*>(curPtr); 46306f6ba60Sopenharmony_ci unsigned int evtSize = event->size; 46406f6ba60Sopenharmony_ci if (evtSize == 0U) { 46506f6ba60Sopenharmony_ci break; 46606f6ba60Sopenharmony_ci } 46706f6ba60Sopenharmony_ci struct HmTraceHeader* header = reinterpret_cast<struct HmTraceHeader*>(event->data); 46806f6ba60Sopenharmony_ci auto parseEventCtx = SubEventParser<E>::GetInstance().GetParseEventCtx(header->commonType); 46906f6ba60Sopenharmony_ci if (parseEventCtx == NULL) { 47006f6ba60Sopenharmony_ci curPtr += RmqEntryTotalSize(evtSize); 47106f6ba60Sopenharmony_ci continue; 47206f6ba60Sopenharmony_ci } 47306f6ba60Sopenharmony_ci ftraceEvent = cpuDetailMsg->add_event(); 47406f6ba60Sopenharmony_ci ftraceEvent->set_timestamp(event->timeStampOffset + timeStampBase); 47506f6ba60Sopenharmony_ci if (!ftraceParser_->HmParseFtraceEvent(*ftraceEvent, reinterpret_cast<uint8_t*>(header), evtSize, 47606f6ba60Sopenharmony_ci parseEventCtx)) { 47706f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, "hm parse event failed!"); 47806f6ba60Sopenharmony_ci } 47906f6ba60Sopenharmony_ci curPtr += RmqEntryTotalSize(evtSize); 48006f6ba60Sopenharmony_ci } 48106f6ba60Sopenharmony_ci data += PAGE_SIZE; 48206f6ba60Sopenharmony_ci return true; 48306f6ba60Sopenharmony_ci} 48406f6ba60Sopenharmony_ci 48506f6ba60Sopenharmony_cibool FlowController::HmParseEventDataOnNomalMode(long dataSize) 48606f6ba60Sopenharmony_ci{ 48706f6ba60Sopenharmony_ci CHECK_NOTNULL(resultWriter_, false, "%s: resultWriter_ nullptr", __func__); 48806f6ba60Sopenharmony_ci auto buffer = ftraceBuffers_[0].get(); 48906f6ba60Sopenharmony_ci auto endPtr = buffer + dataSize; 49006f6ba60Sopenharmony_ci 49106f6ba60Sopenharmony_ci for (auto data = buffer; data < endPtr;) { 49206f6ba60Sopenharmony_ci if (resultWriter_->isProtobufSerialize) { 49306f6ba60Sopenharmony_ci auto traceResult = std::make_unique<TracePluginResult>(); 49406f6ba60Sopenharmony_ci FtraceEvent* event = nullptr; 49506f6ba60Sopenharmony_ci CHECK_TRUE(HmParseEventData(traceResult.get(), data, event), false, "hm parse raw data failed!"); 49606f6ba60Sopenharmony_ci CHECK_TRUE(tansporter_->Submit(std::move(traceResult)), false, "report hm raw event failed!"); 49706f6ba60Sopenharmony_ci } else { 49806f6ba60Sopenharmony_ci auto ctx = resultWriter_->startReport(resultWriter_); 49906f6ba60Sopenharmony_ci CHECK_NOTNULL(ctx, false, "%s: get RandomWriteCtx FAILED!", __func__); 50006f6ba60Sopenharmony_ci static ProtoEncoder::MessagePool msgPool; 50106f6ba60Sopenharmony_ci static ProtoEncoder::TracePluginResult traceResult; 50206f6ba60Sopenharmony_ci msgPool.Reset(); 50306f6ba60Sopenharmony_ci traceResult.Reset(ctx, &msgPool); 50406f6ba60Sopenharmony_ci ProtoEncoder::FtraceEvent* event = nullptr; 50506f6ba60Sopenharmony_ci CHECK_TRUE(HmParseEventData(&traceResult, data, event), false, "hm parse raw data failed!"); 50606f6ba60Sopenharmony_ci int32_t msgSize = traceResult.Finish(); 50706f6ba60Sopenharmony_ci resultWriter_->finishReport(resultWriter_, msgSize); 50806f6ba60Sopenharmony_ci tansporter_->Report(static_cast<size_t>(msgSize)); 50906f6ba60Sopenharmony_ci } 51006f6ba60Sopenharmony_ci } 51106f6ba60Sopenharmony_ci 51206f6ba60Sopenharmony_ci return true; 51306f6ba60Sopenharmony_ci} 51406f6ba60Sopenharmony_ci 51506f6ba60Sopenharmony_cilong FlowController::ReadEventData(int cpuid) 51606f6ba60Sopenharmony_ci{ 51706f6ba60Sopenharmony_ci auto buffer = ftraceBuffers_[cpuid].get(); 51806f6ba60Sopenharmony_ci auto reader = ftraceReaders_[cpuid].get(); 51906f6ba60Sopenharmony_ci auto bufferSize = static_cast<long>(memPool_->GetBlockSize()); 52006f6ba60Sopenharmony_ci 52106f6ba60Sopenharmony_ci long nbytes = 0; 52206f6ba60Sopenharmony_ci long used = 0; 52306f6ba60Sopenharmony_ci long rest = bufferSize; 52406f6ba60Sopenharmony_ci while ((nbytes = reader->Read(&buffer[used], rest)) > 0 && used < bufferSize) { 52506f6ba60Sopenharmony_ci CHECK_TRUE(used % PAGE_SIZE == 0, used, "used invalid!"); 52606f6ba60Sopenharmony_ci used += nbytes; 52706f6ba60Sopenharmony_ci rest -= nbytes; 52806f6ba60Sopenharmony_ci } 52906f6ba60Sopenharmony_ci 53006f6ba60Sopenharmony_ci if (used == bufferSize) { 53106f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, 53206f6ba60Sopenharmony_ci "used(%ld) equals bufferSize(%ld), please expand buffer_size_kb, otherwise the kernel may lose data\n", 53306f6ba60Sopenharmony_ci used, bufferSize); 53406f6ba60Sopenharmony_ci } 53506f6ba60Sopenharmony_ci return used; 53606f6ba60Sopenharmony_ci} 53706f6ba60Sopenharmony_ci 53806f6ba60Sopenharmony_cibool FlowController::ParseEventData(int cpuid, uint8_t* page) 53906f6ba60Sopenharmony_ci{ 54006f6ba60Sopenharmony_ci if (resultWriter_->isProtobufSerialize) { 54106f6ba60Sopenharmony_ci auto traceResult = std::make_unique<TracePluginResult>(); 54206f6ba60Sopenharmony_ci FtraceEvent* event = nullptr; // Used to distinguish between SubEventParser instance types. 54306f6ba60Sopenharmony_ci CHECK_TRUE(ParseFtraceEvent(traceResult.get(), cpuid, page, event), false, "parse raw event for cpu-%d failed!", 54406f6ba60Sopenharmony_ci cpuid); 54506f6ba60Sopenharmony_ci CHECK_TRUE(tansporter_->Submit(std::move(traceResult)), false, "report raw event for cpu-%d failed!", cpuid); 54606f6ba60Sopenharmony_ci } else { 54706f6ba60Sopenharmony_ci auto ctx = resultWriter_->startReport(resultWriter_); 54806f6ba60Sopenharmony_ci CHECK_NOTNULL(ctx, false, "%s: get RandomWriteCtx FAILED!", __func__); 54906f6ba60Sopenharmony_ci static ProtoEncoder::MessagePool msgPool; 55006f6ba60Sopenharmony_ci static ProtoEncoder::TracePluginResult traceResult; 55106f6ba60Sopenharmony_ci msgPool.Reset(); 55206f6ba60Sopenharmony_ci traceResult.Reset(ctx, &msgPool); 55306f6ba60Sopenharmony_ci ProtoEncoder::FtraceEvent* event = nullptr; // Used to distinguish between SubEventParser instance types. 55406f6ba60Sopenharmony_ci CHECK_TRUE(ParseFtraceEvent(&traceResult, cpuid, page, event), false, "parse raw event for cpu-%d failed!", 55506f6ba60Sopenharmony_ci cpuid); 55606f6ba60Sopenharmony_ci int32_t msgSize = traceResult.Finish(); 55706f6ba60Sopenharmony_ci resultWriter_->finishReport(resultWriter_, msgSize); 55806f6ba60Sopenharmony_ci tansporter_->Report(static_cast<size_t>(msgSize)); 55906f6ba60Sopenharmony_ci } 56006f6ba60Sopenharmony_ci return true; 56106f6ba60Sopenharmony_ci} 56206f6ba60Sopenharmony_ci 56306f6ba60Sopenharmony_cibool FlowController::ParseEventDataOnNomalMode(int cpuid, long dataSize) 56406f6ba60Sopenharmony_ci{ 56506f6ba60Sopenharmony_ci CHECK_NOTNULL(resultWriter_, false, "%s: resultWriter_ nullptr", __func__); 56606f6ba60Sopenharmony_ci auto buffer = ftraceBuffers_[cpuid].get(); 56706f6ba60Sopenharmony_ci auto endPtr = buffer + dataSize; 56806f6ba60Sopenharmony_ci for (auto page = buffer; page < endPtr; page += PAGE_SIZE) { 56906f6ba60Sopenharmony_ci if (!ParseEventData(cpuid, page)) { 57006f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, "%s:ParseEventData for cpu-%d failed!", __func__, cpuid); 57106f6ba60Sopenharmony_ci } 57206f6ba60Sopenharmony_ci } 57306f6ba60Sopenharmony_ci return true; 57406f6ba60Sopenharmony_ci} 57506f6ba60Sopenharmony_ci 57606f6ba60Sopenharmony_cibool FlowController::ParseEventDataOnDelayMode() 57706f6ba60Sopenharmony_ci{ 57806f6ba60Sopenharmony_ci CHECK_TRUE(fseek(rawDataFile_.get(), 0, SEEK_SET) == 0, false, "fseek failed!"); 57906f6ba60Sopenharmony_ci while (!feof(rawDataFile_.get())) { 58006f6ba60Sopenharmony_ci uint8_t cpuId = 0; 58106f6ba60Sopenharmony_ci long dataBytes = 0; 58206f6ba60Sopenharmony_ci fread(&cpuId, sizeof(uint8_t), 1, rawDataFile_.get()); 58306f6ba60Sopenharmony_ci fread(&dataBytes, sizeof(long), 1, rawDataFile_.get()); 58406f6ba60Sopenharmony_ci for (long i = 0; i < dataBytes; i += PAGE_SIZE) { 58506f6ba60Sopenharmony_ci uint8_t page[PAGE_SIZE] = {0}; 58606f6ba60Sopenharmony_ci fread(page, sizeof(uint8_t), PAGE_SIZE, rawDataFile_.get()); 58706f6ba60Sopenharmony_ci if (!ParseEventData(cpuId, page)) { 58806f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, "%s:ParseEventData for cpu-%d failed!", __func__, cpuId); 58906f6ba60Sopenharmony_ci } 59006f6ba60Sopenharmony_ci } 59106f6ba60Sopenharmony_ci } 59206f6ba60Sopenharmony_ci return true; 59306f6ba60Sopenharmony_ci} 59406f6ba60Sopenharmony_ci 59506f6ba60Sopenharmony_ciint FlowController::StopCapture(void) 59606f6ba60Sopenharmony_ci{ 59706f6ba60Sopenharmony_ci CHECK_TRUE(ftraceSupported_, -1, "current kernel not support ftrace!"); 59806f6ba60Sopenharmony_ci CHECK_NOTNULL(tansporter_, -1, "crate ResultTransporter FAILED!"); 59906f6ba60Sopenharmony_ci 60006f6ba60Sopenharmony_ci CHECK_TRUE(requestEvents_.size() != 0 || traceApps_.size() != 0 || traceCategories_.size() != 0, -1, 60106f6ba60Sopenharmony_ci "StopCapture: ftrace event is not set, return false"); 60206f6ba60Sopenharmony_ci 60306f6ba60Sopenharmony_ci // disable ftrace event switches 60406f6ba60Sopenharmony_ci DisableTraceEvents(); 60506f6ba60Sopenharmony_ci 60606f6ba60Sopenharmony_ci // stop ftrace event data polling thread 60706f6ba60Sopenharmony_ci keepRunning_ = false; 60806f6ba60Sopenharmony_ci if (pollThread_.joinable()) { 60906f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "join thread start!\n"); 61006f6ba60Sopenharmony_ci pollThread_.join(); 61106f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "join thread done!\n"); 61206f6ba60Sopenharmony_ci } 61306f6ba60Sopenharmony_ci // parse per cpu stats 61406f6ba60Sopenharmony_ci if (resultWriter_->isProtobufSerialize) { 61506f6ba60Sopenharmony_ci auto traceResult = std::make_unique<TracePluginResult>(); 61606f6ba60Sopenharmony_ci CHECK_TRUE(ParsePerCpuStatus(traceResult, TRACE_END), -1, "parse TRACE_END stats FAILED!"); 61706f6ba60Sopenharmony_ci CHECK_TRUE(tansporter_->Submit(std::move(traceResult)), -1, "report TRACE_END stats FAILED!"); 61806f6ba60Sopenharmony_ci } else { 61906f6ba60Sopenharmony_ci auto ctx = resultWriter_->startReport(resultWriter_); 62006f6ba60Sopenharmony_ci CHECK_NOTNULL(ctx, -1, "%s: get RandomWriteCtx FAILED!", __func__); 62106f6ba60Sopenharmony_ci auto traceResult = std::make_unique<ProtoEncoder::TracePluginResult>(ctx); 62206f6ba60Sopenharmony_ci CHECK_TRUE(ParsePerCpuStatus(traceResult, TRACE_END), -1, "parse TRACE_END stats FAILED!"); 62306f6ba60Sopenharmony_ci int32_t msgSize = traceResult->Finish(); 62406f6ba60Sopenharmony_ci resultWriter_->finishReport(resultWriter_, msgSize); 62506f6ba60Sopenharmony_ci tansporter_->Report(static_cast<size_t>(msgSize)); 62606f6ba60Sopenharmony_ci } 62706f6ba60Sopenharmony_ci 62806f6ba60Sopenharmony_ci // disable userspace trace triggers 62906f6ba60Sopenharmony_ci // because trace cmd will read trace buffer, 63006f6ba60Sopenharmony_ci // so we to this action after polling thread exit. 63106f6ba60Sopenharmony_ci traceCollector_->Recover(); 63206f6ba60Sopenharmony_ci tansporter_->Flush(); 63306f6ba60Sopenharmony_ci 63406f6ba60Sopenharmony_ci // release resources 63506f6ba60Sopenharmony_ci ftraceReaders_.clear(); // release ftrace data readers 63606f6ba60Sopenharmony_ci ftraceBuffers_.clear(); // release ftrace event read buffers 63706f6ba60Sopenharmony_ci memPool_.reset(); // release memory pool 63806f6ba60Sopenharmony_ci return 0; 63906f6ba60Sopenharmony_ci} 64006f6ba60Sopenharmony_ci 64106f6ba60Sopenharmony_citemplate <typename T> bool FlowController::ParsePerCpuStatus(T& tracePluginResult, int stage) 64206f6ba60Sopenharmony_ci{ 64306f6ba60Sopenharmony_ci CHECK_NOTNULL(tracePluginResult, false, "create TracePluginResult FAILED!"); 64406f6ba60Sopenharmony_ci 64506f6ba60Sopenharmony_ci auto cpuStatsMsg = tracePluginResult->add_ftrace_cpu_stats(); 64606f6ba60Sopenharmony_ci if (stage == TRACE_START) { 64706f6ba60Sopenharmony_ci cpuStatsMsg->set_status(FtraceCpuStatsMsg_Status_TRACE_START); 64806f6ba60Sopenharmony_ci } else { 64906f6ba60Sopenharmony_ci cpuStatsMsg->set_status(FtraceCpuStatsMsg_Status_TRACE_END); 65006f6ba60Sopenharmony_ci } 65106f6ba60Sopenharmony_ci 65206f6ba60Sopenharmony_ci std::string traceClock = FtraceFsOps::GetInstance().GetTraceClock(); 65306f6ba60Sopenharmony_ci if (traceClock.size() > 0) { 65406f6ba60Sopenharmony_ci cpuStatsMsg->set_trace_clock(traceClock); 65506f6ba60Sopenharmony_ci } 65606f6ba60Sopenharmony_ci 65706f6ba60Sopenharmony_ci for (int i = 0; i < platformCpuNum_; i++) { 65806f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "[%d] ParsePerCpuStatus %d!", i, stage); 65906f6ba60Sopenharmony_ci PerCpuStats stats = {}; 66006f6ba60Sopenharmony_ci stats.cpuIndex = i; 66106f6ba60Sopenharmony_ci ftraceParser_->ParsePerCpuStatus(stats, FtraceFsOps::GetInstance().GetPerCpuStats(i)); 66206f6ba60Sopenharmony_ci auto perCpuMsg = cpuStatsMsg->add_per_cpu_stats(); 66306f6ba60Sopenharmony_ci perCpuMsg->set_cpu(stats.cpuIndex); 66406f6ba60Sopenharmony_ci perCpuMsg->set_entries(stats.entries); 66506f6ba60Sopenharmony_ci perCpuMsg->set_overrun(stats.overrun); 66606f6ba60Sopenharmony_ci perCpuMsg->set_commit_overrun(stats.commitOverrun); 66706f6ba60Sopenharmony_ci perCpuMsg->set_bytes(stats.bytes); 66806f6ba60Sopenharmony_ci perCpuMsg->set_oldest_event_ts(stats.oldestEventTs); 66906f6ba60Sopenharmony_ci perCpuMsg->set_now_ts(stats.nowTs); 67006f6ba60Sopenharmony_ci perCpuMsg->set_dropped_events(stats.droppedEvents); 67106f6ba60Sopenharmony_ci perCpuMsg->set_read_events(stats.readEvents); 67206f6ba60Sopenharmony_ci } 67306f6ba60Sopenharmony_ci 67406f6ba60Sopenharmony_ci return true; 67506f6ba60Sopenharmony_ci} 67606f6ba60Sopenharmony_ci 67706f6ba60Sopenharmony_citemplate <typename T> bool FlowController::ReportClockTimes(T& tracePluginResult) 67806f6ba60Sopenharmony_ci{ 67906f6ba60Sopenharmony_ci CHECK_NOTNULL(tracePluginResult, false, "create TracePluginResult FAILED!"); 68006f6ba60Sopenharmony_ci 68106f6ba60Sopenharmony_ci std::map<clockid_t, ClockDetailMsg::ClockId> clocksMap = { 68206f6ba60Sopenharmony_ci {CLOCK_REALTIME, ClockDetailMsg::REALTIME}, 68306f6ba60Sopenharmony_ci {CLOCK_REALTIME_COARSE, ClockDetailMsg::REALTIME_COARSE}, 68406f6ba60Sopenharmony_ci {CLOCK_MONOTONIC, ClockDetailMsg::MONOTONIC}, 68506f6ba60Sopenharmony_ci {CLOCK_MONOTONIC_COARSE, ClockDetailMsg::MONOTONIC_COARSE}, 68606f6ba60Sopenharmony_ci {CLOCK_MONOTONIC_RAW, ClockDetailMsg::MONOTONIC_RAW}, 68706f6ba60Sopenharmony_ci {CLOCK_BOOTTIME, ClockDetailMsg::BOOTTIME}, 68806f6ba60Sopenharmony_ci }; 68906f6ba60Sopenharmony_ci for (auto& entry : clocksMap) { 69006f6ba60Sopenharmony_ci struct timespec ts = {}; 69106f6ba60Sopenharmony_ci clock_gettime(entry.first, &ts); 69206f6ba60Sopenharmony_ci auto clockMsg = tracePluginResult->add_clocks_detail(); 69306f6ba60Sopenharmony_ci CHECK_NOTNULL(clockMsg, false, "add clock_detail failed for %d!", entry.first); 69406f6ba60Sopenharmony_ci clockMsg->set_id(entry.second); 69506f6ba60Sopenharmony_ci auto timeMsg = clockMsg->mutable_time(); 69606f6ba60Sopenharmony_ci timeMsg->set_tv_sec(ts.tv_sec); 69706f6ba60Sopenharmony_ci timeMsg->set_tv_nsec(ts.tv_nsec); 69806f6ba60Sopenharmony_ci 69906f6ba60Sopenharmony_ci struct timespec tsResolution = {}; 70006f6ba60Sopenharmony_ci clock_getres(entry.first, &tsResolution); 70106f6ba60Sopenharmony_ci auto resolutionMsg = clockMsg->mutable_resolution(); 70206f6ba60Sopenharmony_ci resolutionMsg->set_tv_sec(tsResolution.tv_sec); 70306f6ba60Sopenharmony_ci resolutionMsg->set_tv_nsec(tsResolution.tv_nsec); 70406f6ba60Sopenharmony_ci } 70506f6ba60Sopenharmony_ci return true; 70606f6ba60Sopenharmony_ci} 70706f6ba60Sopenharmony_ci 70806f6ba60Sopenharmony_citemplate <typename T> bool FlowController::ParseKernelSymbols(T& tracePluginResult) 70906f6ba60Sopenharmony_ci{ 71006f6ba60Sopenharmony_ci CHECK_NOTNULL(tracePluginResult, false, "create TracePluginResult FAILED!"); 71106f6ba60Sopenharmony_ci 71206f6ba60Sopenharmony_ci ksymsParser_->Accept([&tracePluginResult](const KernelSymbol& symbol) { 71306f6ba60Sopenharmony_ci auto symbolDetail = tracePluginResult->add_symbols_detail(); 71406f6ba60Sopenharmony_ci symbolDetail->set_symbol_addr(symbol.addr); 71506f6ba60Sopenharmony_ci symbolDetail->set_symbol_name(symbol.name); 71606f6ba60Sopenharmony_ci }); 71706f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "parse kernel symbol message done!"); 71806f6ba60Sopenharmony_ci return true; 71906f6ba60Sopenharmony_ci} 72006f6ba60Sopenharmony_ci 72106f6ba60Sopenharmony_citemplate <typename T, typename E> 72206f6ba60Sopenharmony_cibool FlowController::ParseFtraceEvent(T* tracePluginResult, int cpuid, uint8_t page[], E* ftraceEvent) 72306f6ba60Sopenharmony_ci{ 72406f6ba60Sopenharmony_ci CHECK_NOTNULL(tracePluginResult, false, "create TracePluginResult FAILED!"); 72506f6ba60Sopenharmony_ci 72606f6ba60Sopenharmony_ci auto cpudetail = tracePluginResult->add_ftrace_cpu_detail(); 72706f6ba60Sopenharmony_ci cpudetail->set_cpu(static_cast<uint32_t>(cpuid)); 72806f6ba60Sopenharmony_ci 72906f6ba60Sopenharmony_ci CHECK_TRUE(ftraceParser_->ParsePage(*cpudetail, page, PAGE_SIZE, ftraceEvent), false, "parse page failed!"); 73006f6ba60Sopenharmony_ci return true; 73106f6ba60Sopenharmony_ci} 73206f6ba60Sopenharmony_ci 73306f6ba60Sopenharmony_cibool FlowController::AddPlatformEventsToParser(void) 73406f6ba60Sopenharmony_ci{ 73506f6ba60Sopenharmony_ci CHECK_TRUE(ftraceSupported_, false, "current kernel not support ftrace!"); 73606f6ba60Sopenharmony_ci 73706f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "Add platform events to parser start!"); 73806f6ba60Sopenharmony_ci for (auto& typeName : FtraceFsOps::GetInstance().GetPlatformEvents()) { 73906f6ba60Sopenharmony_ci std::string type = typeName.first; 74006f6ba60Sopenharmony_ci std::string name = typeName.second; 74106f6ba60Sopenharmony_ci if (ftraceParser_->SetupEvent(type, name)) { 74206f6ba60Sopenharmony_ci supportedEvents_.push_back(typeName); 74306f6ba60Sopenharmony_ci } 74406f6ba60Sopenharmony_ci } 74506f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "Add platform events to parser done, events: %zu!", supportedEvents_.size()); 74606f6ba60Sopenharmony_ci return true; 74706f6ba60Sopenharmony_ci} 74806f6ba60Sopenharmony_ci 74906f6ba60Sopenharmony_ciint FlowController::LoadConfig(const uint8_t configData[], uint32_t size) 75006f6ba60Sopenharmony_ci{ 75106f6ba60Sopenharmony_ci CHECK_TRUE(size > 0, -1, "config data size is zero!"); 75206f6ba60Sopenharmony_ci CHECK_NOTNULL(configData, -1, "config data is null!"); 75306f6ba60Sopenharmony_ci CHECK_TRUE(ftraceSupported_, -1, "current kernel not support ftrace!"); 75406f6ba60Sopenharmony_ci CHECK_NOTNULL(tansporter_, -1, "ResultTransporter crated FAILED!"); 75506f6ba60Sopenharmony_ci 75606f6ba60Sopenharmony_ci TracePluginConfig traceConfig; 75706f6ba60Sopenharmony_ci CHECK_TRUE(traceConfig.ParseFromArray(configData, size), -1, "parse %u bytes configData failed!", size); 75806f6ba60Sopenharmony_ci 75906f6ba60Sopenharmony_ci // sort and save user requested trace events 76006f6ba60Sopenharmony_ci std::set<std::string> events(traceConfig.ftrace_events().begin(), traceConfig.ftrace_events().end()); 76106f6ba60Sopenharmony_ci for (auto ftraceEvent : events) { 76206f6ba60Sopenharmony_ci requestEvents_.push_back(ftraceEvent); 76306f6ba60Sopenharmony_ci } 76406f6ba60Sopenharmony_ci 76506f6ba60Sopenharmony_ci traceApps_.assign(traceConfig.hitrace_apps().begin(), traceConfig.hitrace_apps().end()); 76606f6ba60Sopenharmony_ci traceCategories_.assign(traceConfig.hitrace_categories().begin(), traceConfig.hitrace_categories().end()); 76706f6ba60Sopenharmony_ci 76806f6ba60Sopenharmony_ci CHECK_TRUE(requestEvents_.size() != 0 || traceApps_.size() != 0 || traceCategories_.size() != 0, -1, 76906f6ba60Sopenharmony_ci "LoadConfig: ftrace event is not set, return false"); 77006f6ba60Sopenharmony_ci 77106f6ba60Sopenharmony_ci // setup trace clock 77206f6ba60Sopenharmony_ci if (g_availableClocks.count(traceConfig.clock()) > 0) { 77306f6ba60Sopenharmony_ci traceClock_ = traceConfig.clock(); 77406f6ba60Sopenharmony_ci FtraceFsOps::GetInstance().SetTraceClock(traceConfig.clock()); 77506f6ba60Sopenharmony_ci } 77606f6ba60Sopenharmony_ci 77706f6ba60Sopenharmony_ci // setup parse kernel symbol option 77806f6ba60Sopenharmony_ci parseKsyms_ = traceConfig.parse_ksyms(); 77906f6ba60Sopenharmony_ci parseMode_ = traceConfig.parse_mode(); 78006f6ba60Sopenharmony_ci // setup trace buffer size 78106f6ba60Sopenharmony_ci SetupTraceBufferSize(traceConfig.buffer_size_kb()); 78206f6ba60Sopenharmony_ci 78306f6ba60Sopenharmony_ci // setup transporter flush params 78406f6ba60Sopenharmony_ci SetupTransporterFlushParams(traceConfig.flush_interval_ms(), traceConfig.flush_threshold_kb()); 78506f6ba60Sopenharmony_ci 78606f6ba60Sopenharmony_ci // generate raw data file names 78706f6ba60Sopenharmony_ci GenerateRawDataFileNames(traceConfig.raw_data_prefix()); 78806f6ba60Sopenharmony_ci 78906f6ba60Sopenharmony_ci // setup trace period param 79006f6ba60Sopenharmony_ci SetupTraceReadPeriod(traceConfig.trace_period_ms()); 79106f6ba60Sopenharmony_ci flushCacheData_ = traceConfig.discard_cache_data(); 79206f6ba60Sopenharmony_ci hitraceTime_ = traceConfig.hitrace_time(); 79306f6ba60Sopenharmony_ci return 0; 79406f6ba60Sopenharmony_ci} 79506f6ba60Sopenharmony_ci 79606f6ba60Sopenharmony_civoid FlowController::SetupTraceBufferSize(uint32_t sizeKb) 79706f6ba60Sopenharmony_ci{ 79806f6ba60Sopenharmony_ci uint32_t maxBufferSizeKb = MAX_BUFFER_SIZE_KB; 79906f6ba60Sopenharmony_ci if (FtraceFsOps::GetInstance().IsHmKernel()) { 80006f6ba60Sopenharmony_ci maxBufferSizeKb = HM_MAX_BUFFER_SIZE_KB; 80106f6ba60Sopenharmony_ci } 80206f6ba60Sopenharmony_ci if (sizeKb < MIN_BUFFER_SIZE_KB) { 80306f6ba60Sopenharmony_ci bufferSizeKb_ = MIN_BUFFER_SIZE_KB; 80406f6ba60Sopenharmony_ci } else if (sizeKb > maxBufferSizeKb) { 80506f6ba60Sopenharmony_ci bufferSizeKb_ = maxBufferSizeKb; 80606f6ba60Sopenharmony_ci } else { 80706f6ba60Sopenharmony_ci bufferSizeKb_ = sizeKb / KB_PER_PAGE * KB_PER_PAGE; 80806f6ba60Sopenharmony_ci } 80906f6ba60Sopenharmony_ci} 81006f6ba60Sopenharmony_ci 81106f6ba60Sopenharmony_civoid FlowController::SetupTransporterFlushParams(uint32_t flushInterval, uint32_t flushThresholdKb) 81206f6ba60Sopenharmony_ci{ 81306f6ba60Sopenharmony_ci if (flushInterval > 0 && flushInterval <= MAX_FLUSH_INTERVAL) { 81406f6ba60Sopenharmony_ci tansporter_->SetFlushInterval(flushInterval); 81506f6ba60Sopenharmony_ci } 81606f6ba60Sopenharmony_ci if (flushThresholdKb > 0 && flushThresholdKb <= MAX_FLUSH_THRESHOLD) { 81706f6ba60Sopenharmony_ci tansporter_->SetFlushThreshold(flushThresholdKb * BYTE_PER_KB); 81806f6ba60Sopenharmony_ci } 81906f6ba60Sopenharmony_ci} 82006f6ba60Sopenharmony_ci 82106f6ba60Sopenharmony_civoid FlowController::GenerateRawDataFileNames(const std::string& prefix) 82206f6ba60Sopenharmony_ci{ 82306f6ba60Sopenharmony_ci if (prefix.size() > 0) { 82406f6ba60Sopenharmony_ci for (int i = 0; i < platformCpuNum_; i++) { 82506f6ba60Sopenharmony_ci std::string path = prefix + std::to_string(i); 82606f6ba60Sopenharmony_ci rawDataDumpPath_.push_back(path); 82706f6ba60Sopenharmony_ci } 82806f6ba60Sopenharmony_ci } 82906f6ba60Sopenharmony_ci} 83006f6ba60Sopenharmony_ci 83106f6ba60Sopenharmony_civoid FlowController::SetupTraceReadPeriod(uint32_t tracePeriod) 83206f6ba60Sopenharmony_ci{ 83306f6ba60Sopenharmony_ci if (tracePeriod > 0 && tracePeriod <= MAX_TRACE_PERIOD_MS) { 83406f6ba60Sopenharmony_ci tracePeriodMs_ = tracePeriod; 83506f6ba60Sopenharmony_ci } else { 83606f6ba60Sopenharmony_ci tracePeriodMs_ = DEFAULT_TRACE_PERIOD_MS; 83706f6ba60Sopenharmony_ci } 83806f6ba60Sopenharmony_ci} 83906f6ba60Sopenharmony_ci 84006f6ba60Sopenharmony_civoid FlowController::EnableTraceEvents(void) 84106f6ba60Sopenharmony_ci{ 84206f6ba60Sopenharmony_ci std::unordered_set<std::string> userEventSet(requestEvents_.begin(), requestEvents_.end()); 84306f6ba60Sopenharmony_ci for (auto& event : supportedEvents_) { 84406f6ba60Sopenharmony_ci std::string type = event.first; 84506f6ba60Sopenharmony_ci std::string name = event.second; 84606f6ba60Sopenharmony_ci std::string fmtType = type; 84706f6ba60Sopenharmony_ci if (type == "power_kernel") { 84806f6ba60Sopenharmony_ci fmtType = "power"; 84906f6ba60Sopenharmony_ci } 85006f6ba60Sopenharmony_ci if (userEventSet.count(fmtType + "/" + name)) { // user config format 85106f6ba60Sopenharmony_ci if (FtraceFsOps::GetInstance().EnableEvent(type, name)) { 85206f6ba60Sopenharmony_ci FtraceFsOps::GetInstance().AppendSetEvent(type, name); 85306f6ba60Sopenharmony_ci enabledEvents_.push_back(event); 85406f6ba60Sopenharmony_ci } 85506f6ba60Sopenharmony_ci } 85606f6ba60Sopenharmony_ci } 85706f6ba60Sopenharmony_ci FtraceFsOps::GetInstance().EnableTracing(); 85806f6ba60Sopenharmony_ci} 85906f6ba60Sopenharmony_ci 86006f6ba60Sopenharmony_civoid FlowController::DisableTraceEvents(void) 86106f6ba60Sopenharmony_ci{ 86206f6ba60Sopenharmony_ci FtraceFsOps::GetInstance().DisableTracing(); 86306f6ba60Sopenharmony_ci for (auto& event : enabledEvents_) { 86406f6ba60Sopenharmony_ci std::string type = event.first; 86506f6ba60Sopenharmony_ci std::string name = event.second; 86606f6ba60Sopenharmony_ci FtraceFsOps::GetInstance().DisableEvent(type, name); 86706f6ba60Sopenharmony_ci } 86806f6ba60Sopenharmony_ci enabledEvents_.clear(); 86906f6ba60Sopenharmony_ci} 87006f6ba60Sopenharmony_ci 87106f6ba60Sopenharmony_civoid FlowController::DisableAllCategories(void) 87206f6ba60Sopenharmony_ci{ 87306f6ba60Sopenharmony_ci for (auto& event : supportedEvents_) { 87406f6ba60Sopenharmony_ci std::string type = event.first; 87506f6ba60Sopenharmony_ci std::string name = event.second; 87606f6ba60Sopenharmony_ci FtraceFsOps::GetInstance().DisableCategories(type); 87706f6ba60Sopenharmony_ci } 87806f6ba60Sopenharmony_ci} 87906f6ba60Sopenharmony_ci 88006f6ba60Sopenharmony_civoid FlowController::SetReportBasicData(bool isReportBasicData) 88106f6ba60Sopenharmony_ci{ 88206f6ba60Sopenharmony_ci isReportBasicData_ = isReportBasicData; 88306f6ba60Sopenharmony_ci} 88406f6ba60Sopenharmony_ciFTRACE_NS_END 885