106f6ba60Sopenharmony_ci/* 206f6ba60Sopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2021. 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 1606f6ba60Sopenharmony_ci#include "cpu_data_plugin.h" 1706f6ba60Sopenharmony_ci 1806f6ba60Sopenharmony_ci#include <ctime> 1906f6ba60Sopenharmony_ci#include <vector> 2006f6ba60Sopenharmony_ci#include <sstream> 2106f6ba60Sopenharmony_ci#include "cpu_plugin_result.pbencoder.h" 2206f6ba60Sopenharmony_ci#include "buffer_splitter.h" 2306f6ba60Sopenharmony_ci 2406f6ba60Sopenharmony_cinamespace { 2506f6ba60Sopenharmony_ciusing namespace OHOS::Developtools::Profiler; 2606f6ba60Sopenharmony_ciconstexpr size_t READ_BUFFER_SIZE = 1024 * 16; 2706f6ba60Sopenharmony_ciconstexpr int SYSTEM_STAT_COUNT = 9; 2806f6ba60Sopenharmony_ciconstexpr int STAT_COUNT = 17; 2906f6ba60Sopenharmony_ciconstexpr int STAT_START = 13; 3006f6ba60Sopenharmony_ciconstexpr int THREAD_NAME_POS = 1; 3106f6ba60Sopenharmony_ciconstexpr int THREAD_STATE_POS = 2; 3206f6ba60Sopenharmony_ciconstexpr int CPU_USER_HZ_L = 100; 3306f6ba60Sopenharmony_ciconstexpr int CPU_USER_HZ_H = 1000; 3406f6ba60Sopenharmony_ciconstexpr int CPU_HZ_H = 10; 3506f6ba60Sopenharmony_ciconst int PERCENT = 100; 3606f6ba60Sopenharmony_ci 3706f6ba60Sopenharmony_ciconst std::string FREQUENCY_PATH = "/sys/devices/system/cpu"; 3806f6ba60Sopenharmony_ciconst std::string FREQUENCY_MIN_PATH = "/cpufreq/cpuinfo_min_freq"; 3906f6ba60Sopenharmony_ciconst std::string FREQUENCY_MAX_PATH = "/cpufreq/cpuinfo_max_freq"; 4006f6ba60Sopenharmony_ciconst std::string FREQUENCY_CUR_PATH = "/cpufreq/cpuinfo_cur_freq"; 4106f6ba60Sopenharmony_ci} // namespace 4206f6ba60Sopenharmony_ci 4306f6ba60Sopenharmony_ciCpuDataPlugin::CpuDataPlugin() 4406f6ba60Sopenharmony_ci{ 4506f6ba60Sopenharmony_ci buffer_ = nullptr; 4606f6ba60Sopenharmony_ci path_ = "/proc/"; 4706f6ba60Sopenharmony_ci err_ = -1; 4806f6ba60Sopenharmony_ci pid_ = -1; 4906f6ba60Sopenharmony_ci prevProcessCpuTime_ = 0; 5006f6ba60Sopenharmony_ci prevCpuTimeData_ = {}; 5106f6ba60Sopenharmony_ci maxFreqIndex_ = -1; 5206f6ba60Sopenharmony_ci freqPath_ = FREQUENCY_PATH; 5306f6ba60Sopenharmony_ci} 5406f6ba60Sopenharmony_ci 5506f6ba60Sopenharmony_ciCpuDataPlugin::~CpuDataPlugin() 5606f6ba60Sopenharmony_ci{ 5706f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "%s:~CpuDataPlugin!", __func__); 5806f6ba60Sopenharmony_ci if (buffer_ != nullptr) { 5906f6ba60Sopenharmony_ci free(buffer_); 6006f6ba60Sopenharmony_ci buffer_ = nullptr; 6106f6ba60Sopenharmony_ci } 6206f6ba60Sopenharmony_ci 6306f6ba60Sopenharmony_ci tidVec_.clear(); 6406f6ba60Sopenharmony_ci prevThreadCpuTimeMap_.clear(); 6506f6ba60Sopenharmony_ci prevCoreSystemCpuTimeMap_.clear(); 6606f6ba60Sopenharmony_ci prevCoreSystemBootTimeMap_.clear(); 6706f6ba60Sopenharmony_ci maxFrequencyVec_.clear(); 6806f6ba60Sopenharmony_ci minFrequencyVec_.clear(); 6906f6ba60Sopenharmony_ci} 7006f6ba60Sopenharmony_ci 7106f6ba60Sopenharmony_ciint CpuDataPlugin::Start(const uint8_t* configData, uint32_t configSize) 7206f6ba60Sopenharmony_ci{ 7306f6ba60Sopenharmony_ci buffer_ = malloc(READ_BUFFER_SIZE); 7406f6ba60Sopenharmony_ci CHECK_NOTNULL(buffer_, RET_FAIL, "%s:malloc buffer_ failed!", __func__); 7506f6ba60Sopenharmony_ci if (memset_s(buffer_, READ_BUFFER_SIZE, 0, READ_BUFFER_SIZE) != EOK) { 7606f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, "%s:memset_s error!", __func__); 7706f6ba60Sopenharmony_ci } 7806f6ba60Sopenharmony_ci CHECK_TRUE(protoConfig_.ParseFromArray(configData, configSize) > 0, RET_FAIL, 7906f6ba60Sopenharmony_ci "%s:parseFromArray failed!", __func__); 8006f6ba60Sopenharmony_ci if (protoConfig_.pid() > 0) { 8106f6ba60Sopenharmony_ci pid_ = protoConfig_.pid(); 8206f6ba60Sopenharmony_ci } else if (protoConfig_.report_process_info()) { 8306f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "%s:need report process info", __func__); 8406f6ba60Sopenharmony_ci } else { 8506f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, "%s:invalid pid", __func__); 8606f6ba60Sopenharmony_ci return RET_FAIL; 8706f6ba60Sopenharmony_ci } 8806f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "%s:start success!", __func__); 8906f6ba60Sopenharmony_ci return RET_SUCC; 9006f6ba60Sopenharmony_ci} 9106f6ba60Sopenharmony_ci 9206f6ba60Sopenharmony_ciint CpuDataPlugin::ReportOptimize(RandomWriteCtx* randomWrite) 9306f6ba60Sopenharmony_ci{ 9406f6ba60Sopenharmony_ci ProtoEncoder::CpuData dataProto(randomWrite); 9506f6ba60Sopenharmony_ci 9606f6ba60Sopenharmony_ci ProtoEncoder::CpuUsageInfo* cpuUsageInfo = nullptr; 9706f6ba60Sopenharmony_ci WriteCpuUsageInfo(dataProto, cpuUsageInfo); 9806f6ba60Sopenharmony_ci 9906f6ba60Sopenharmony_ci if (pid_ > 0) { 10006f6ba60Sopenharmony_ci WriteThreadInfo(dataProto); 10106f6ba60Sopenharmony_ci } 10206f6ba60Sopenharmony_ci if (protoConfig_.report_process_info()) { 10306f6ba60Sopenharmony_ci WriteProcnum(dataProto); 10406f6ba60Sopenharmony_ci } 10506f6ba60Sopenharmony_ci 10606f6ba60Sopenharmony_ci int msgSize = dataProto.Finish(); 10706f6ba60Sopenharmony_ci return msgSize; 10806f6ba60Sopenharmony_ci} 10906f6ba60Sopenharmony_ci 11006f6ba60Sopenharmony_ciint CpuDataPlugin::Report(uint8_t* data, uint32_t dataSize) 11106f6ba60Sopenharmony_ci{ 11206f6ba60Sopenharmony_ci CpuData dataProto; 11306f6ba60Sopenharmony_ci uint32_t length; 11406f6ba60Sopenharmony_ci 11506f6ba60Sopenharmony_ci CpuUsageInfo* cpuUsageInfo = nullptr; 11606f6ba60Sopenharmony_ci WriteCpuUsageInfo(dataProto, cpuUsageInfo); 11706f6ba60Sopenharmony_ci 11806f6ba60Sopenharmony_ci if (pid_ > 0) { 11906f6ba60Sopenharmony_ci WriteThreadInfo(dataProto); 12006f6ba60Sopenharmony_ci } 12106f6ba60Sopenharmony_ci if (protoConfig_.report_process_info()) { 12206f6ba60Sopenharmony_ci WriteProcnum(dataProto); 12306f6ba60Sopenharmony_ci } 12406f6ba60Sopenharmony_ci 12506f6ba60Sopenharmony_ci length = dataProto.ByteSizeLong(); 12606f6ba60Sopenharmony_ci if (length > dataSize) { 12706f6ba60Sopenharmony_ci return -length; 12806f6ba60Sopenharmony_ci } 12906f6ba60Sopenharmony_ci if (dataProto.SerializeToArray(data, length) > 0) { 13006f6ba60Sopenharmony_ci return length; 13106f6ba60Sopenharmony_ci } 13206f6ba60Sopenharmony_ci return 0; 13306f6ba60Sopenharmony_ci} 13406f6ba60Sopenharmony_ci 13506f6ba60Sopenharmony_citemplate <typename T> bool CpuDataPlugin::WriteProcnum(T& cpuData) 13606f6ba60Sopenharmony_ci{ 13706f6ba60Sopenharmony_ci DIR* procDir = nullptr; 13806f6ba60Sopenharmony_ci procDir = OpenDestDir(path_); 13906f6ba60Sopenharmony_ci if (procDir == nullptr) { 14006f6ba60Sopenharmony_ci return false; 14106f6ba60Sopenharmony_ci } 14206f6ba60Sopenharmony_ci 14306f6ba60Sopenharmony_ci uint32_t i = 0; 14406f6ba60Sopenharmony_ci while (int32_t tid = GetValidTid(procDir)) { 14506f6ba60Sopenharmony_ci if (tid <= 0) { 14606f6ba60Sopenharmony_ci closedir(procDir); 14706f6ba60Sopenharmony_ci PROFILER_LOG_WARN(LOG_CORE, "%s: get pid[%d] failed", __func__, tid); 14806f6ba60Sopenharmony_ci return false; 14906f6ba60Sopenharmony_ci } 15006f6ba60Sopenharmony_ci i++; 15106f6ba60Sopenharmony_ci } 15206f6ba60Sopenharmony_ci cpuData.set_process_num(i); 15306f6ba60Sopenharmony_ci closedir(procDir); 15406f6ba60Sopenharmony_ci 15506f6ba60Sopenharmony_ci return true; 15606f6ba60Sopenharmony_ci} 15706f6ba60Sopenharmony_ci 15806f6ba60Sopenharmony_ciint CpuDataPlugin::Stop() 15906f6ba60Sopenharmony_ci{ 16006f6ba60Sopenharmony_ci if (buffer_ != nullptr) { 16106f6ba60Sopenharmony_ci free(buffer_); 16206f6ba60Sopenharmony_ci buffer_ = nullptr; 16306f6ba60Sopenharmony_ci } 16406f6ba60Sopenharmony_ci 16506f6ba60Sopenharmony_ci tidVec_.clear(); 16606f6ba60Sopenharmony_ci prevThreadCpuTimeMap_.clear(); 16706f6ba60Sopenharmony_ci prevCoreSystemCpuTimeMap_.clear(); 16806f6ba60Sopenharmony_ci prevCoreSystemBootTimeMap_.clear(); 16906f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "%s:stop success!", __func__); 17006f6ba60Sopenharmony_ci return 0; 17106f6ba60Sopenharmony_ci} 17206f6ba60Sopenharmony_ci 17306f6ba60Sopenharmony_ciint32_t CpuDataPlugin::ReadFile(std::string& fileName) 17406f6ba60Sopenharmony_ci{ 17506f6ba60Sopenharmony_ci int fd = -1; 17606f6ba60Sopenharmony_ci ssize_t bytesRead = 0; 17706f6ba60Sopenharmony_ci char filePath[PATH_MAX + 1] = {0}; 17806f6ba60Sopenharmony_ci char realPath[PATH_MAX + 1] = {0}; 17906f6ba60Sopenharmony_ci 18006f6ba60Sopenharmony_ci if (snprintf_s(filePath, sizeof(filePath), sizeof(filePath) - 1, "%s", fileName.c_str()) < 0) { 18106f6ba60Sopenharmony_ci const int bufSize = 256; 18206f6ba60Sopenharmony_ci char buf[bufSize] = { 0 }; 18306f6ba60Sopenharmony_ci strerror_r(errno, buf, bufSize); 18406f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, "snprintf_s(%s) error, errno(%d:%s)", fileName.c_str(), errno, buf); 18506f6ba60Sopenharmony_ci return RET_FAIL; 18606f6ba60Sopenharmony_ci } 18706f6ba60Sopenharmony_ci if (realpath(filePath, realPath) == nullptr) { 18806f6ba60Sopenharmony_ci const int bufSize = 256; 18906f6ba60Sopenharmony_ci char buf[bufSize] = { 0 }; 19006f6ba60Sopenharmony_ci strerror_r(errno, buf, bufSize); 19106f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, "realpath(%s) failed, errno(%d:%s)", fileName.c_str(), errno, buf); 19206f6ba60Sopenharmony_ci return RET_FAIL; 19306f6ba60Sopenharmony_ci } 19406f6ba60Sopenharmony_ci 19506f6ba60Sopenharmony_ci fd = open(realPath, O_RDONLY | O_CLOEXEC); 19606f6ba60Sopenharmony_ci if (fd == -1) { 19706f6ba60Sopenharmony_ci const int bufSize = 256; 19806f6ba60Sopenharmony_ci char buf[bufSize] = { 0 }; 19906f6ba60Sopenharmony_ci strerror_r(errno, buf, bufSize); 20006f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, "%s:failed to open(%s), errno(%d:%s)", __func__, realPath, errno, buf); 20106f6ba60Sopenharmony_ci err_ = errno; 20206f6ba60Sopenharmony_ci return RET_FAIL; 20306f6ba60Sopenharmony_ci } 20406f6ba60Sopenharmony_ci if (buffer_ == nullptr) { 20506f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, "%s:empty address, buffer_ is NULL", __func__); 20606f6ba60Sopenharmony_ci err_ = RET_NULL_ADDR; 20706f6ba60Sopenharmony_ci close(fd); 20806f6ba60Sopenharmony_ci return RET_FAIL; 20906f6ba60Sopenharmony_ci } 21006f6ba60Sopenharmony_ci if (memset_s(buffer_, READ_BUFFER_SIZE, 0, READ_BUFFER_SIZE) != EOK) { 21106f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, "%s:memset_s error!", __func__); 21206f6ba60Sopenharmony_ci } 21306f6ba60Sopenharmony_ci bytesRead = read(fd, buffer_, READ_BUFFER_SIZE - 1); 21406f6ba60Sopenharmony_ci if (bytesRead <= 0) { 21506f6ba60Sopenharmony_ci close(fd); 21606f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, "%s:failed to read(%s), errno=%d", __func__, realPath, errno); 21706f6ba60Sopenharmony_ci err_ = errno; 21806f6ba60Sopenharmony_ci return RET_FAIL; 21906f6ba60Sopenharmony_ci } 22006f6ba60Sopenharmony_ci close(fd); 22106f6ba60Sopenharmony_ci 22206f6ba60Sopenharmony_ci return bytesRead; 22306f6ba60Sopenharmony_ci} 22406f6ba60Sopenharmony_ci 22506f6ba60Sopenharmony_citemplate <typename T> void CpuDataPlugin::SetTimestamp(T& sampleTimeStamp) 22606f6ba60Sopenharmony_ci{ 22706f6ba60Sopenharmony_ci timespec time; 22806f6ba60Sopenharmony_ci clock_gettime(CLOCK_MONOTONIC, &time); 22906f6ba60Sopenharmony_ci sampleTimeStamp.set_tv_sec(time.tv_sec); 23006f6ba60Sopenharmony_ci sampleTimeStamp.set_tv_nsec(time.tv_nsec); 23106f6ba60Sopenharmony_ci} 23206f6ba60Sopenharmony_ci 23306f6ba60Sopenharmony_ciint64_t CpuDataPlugin::GetUserHz() 23406f6ba60Sopenharmony_ci{ 23506f6ba60Sopenharmony_ci int64_t hz = -1; 23606f6ba60Sopenharmony_ci int64_t user_hz = sysconf(_SC_CLK_TCK); 23706f6ba60Sopenharmony_ci switch (user_hz) { 23806f6ba60Sopenharmony_ci case CPU_USER_HZ_L: 23906f6ba60Sopenharmony_ci hz = CPU_HZ_H; 24006f6ba60Sopenharmony_ci break; 24106f6ba60Sopenharmony_ci case CPU_USER_HZ_H: 24206f6ba60Sopenharmony_ci hz = 1; 24306f6ba60Sopenharmony_ci break; 24406f6ba60Sopenharmony_ci default: 24506f6ba60Sopenharmony_ci break; 24606f6ba60Sopenharmony_ci } 24706f6ba60Sopenharmony_ci return hz; 24806f6ba60Sopenharmony_ci} 24906f6ba60Sopenharmony_ci 25006f6ba60Sopenharmony_ciint64_t CpuDataPlugin::GetCpuUsageTime(std::vector<std::string>& cpuUsageVec) 25106f6ba60Sopenharmony_ci{ 25206f6ba60Sopenharmony_ci int64_t utime = 0; 25306f6ba60Sopenharmony_ci int64_t stime = 0; 25406f6ba60Sopenharmony_ci int64_t usageTime = 0; 25506f6ba60Sopenharmony_ci utime = atoi(cpuUsageVec[PROCESS_UTIME].c_str()); 25606f6ba60Sopenharmony_ci stime = atoi(cpuUsageVec[PROCESS_STIME].c_str()); 25706f6ba60Sopenharmony_ci // 进程,线程CPU占用率只计算utime(用户态时间),stime(核心态时间) 25806f6ba60Sopenharmony_ci usageTime = (utime + stime) * GetUserHz(); 25906f6ba60Sopenharmony_ci 26006f6ba60Sopenharmony_ci return usageTime; 26106f6ba60Sopenharmony_ci} 26206f6ba60Sopenharmony_ci 26306f6ba60Sopenharmony_citemplate <typename T> void CpuDataPlugin::WriteProcessCpuUsage(T& cpuUsageInfo, const char* pFile, uint32_t fileLen) 26406f6ba60Sopenharmony_ci{ 26506f6ba60Sopenharmony_ci BufferSplitter totalbuffer(const_cast<char*>(pFile), fileLen + 1); 26606f6ba60Sopenharmony_ci std::vector<std::string> cpuUsageVec; 26706f6ba60Sopenharmony_ci for (int i = 0; i < STAT_COUNT; i++) { 26806f6ba60Sopenharmony_ci totalbuffer.NextWord(' '); 26906f6ba60Sopenharmony_ci if (!totalbuffer.CurWord()) { 27006f6ba60Sopenharmony_ci return; 27106f6ba60Sopenharmony_ci } 27206f6ba60Sopenharmony_ci 27306f6ba60Sopenharmony_ci if (i < STAT_START) { 27406f6ba60Sopenharmony_ci continue; 27506f6ba60Sopenharmony_ci } else { 27606f6ba60Sopenharmony_ci std::string curWord = std::string(totalbuffer.CurWord(), totalbuffer.CurWordSize()); 27706f6ba60Sopenharmony_ci cpuUsageVec.push_back(curWord); 27806f6ba60Sopenharmony_ci } 27906f6ba60Sopenharmony_ci } 28006f6ba60Sopenharmony_ci 28106f6ba60Sopenharmony_ci // 获取到的数据不包含utime、stime、cutime、cstime四个数值时返回 28206f6ba60Sopenharmony_ci if (cpuUsageVec.size() != PROCESS_UNSPECIFIED) { 28306f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, "%s:failed to get process cpu usage, size=%zu", __func__, cpuUsageVec.size()); 28406f6ba60Sopenharmony_ci return; 28506f6ba60Sopenharmony_ci } 28606f6ba60Sopenharmony_ci 28706f6ba60Sopenharmony_ci int64_t usageTime = GetCpuUsageTime(cpuUsageVec); 28806f6ba60Sopenharmony_ci cpuUsageInfo.set_prev_process_cpu_time_ms(prevProcessCpuTime_); 28906f6ba60Sopenharmony_ci cpuUsageInfo.set_process_cpu_time_ms(usageTime); 29006f6ba60Sopenharmony_ci prevProcessCpuTime_ = usageTime; 29106f6ba60Sopenharmony_ci} 29206f6ba60Sopenharmony_ci 29306f6ba60Sopenharmony_ciint32_t CpuDataPlugin::GetCpuFrequency(std::string fileName) 29406f6ba60Sopenharmony_ci{ 29506f6ba60Sopenharmony_ci int32_t frequency = 0; 29606f6ba60Sopenharmony_ci int32_t ret = ReadFile(fileName); 29706f6ba60Sopenharmony_ci if (ret != RET_FAIL) { 29806f6ba60Sopenharmony_ci std::string tempStr(static_cast<char*>(buffer_)); 29906f6ba60Sopenharmony_ci // 去掉首尾特殊字符 30006f6ba60Sopenharmony_ci size_t start = tempStr.find_first_not_of(" \t\n\r"); 30106f6ba60Sopenharmony_ci if (start == std::string::npos) { 30206f6ba60Sopenharmony_ci return frequency; 30306f6ba60Sopenharmony_ci } 30406f6ba60Sopenharmony_ci size_t end = tempStr.find_last_not_of(" \t\n\r"); 30506f6ba60Sopenharmony_ci tempStr = tempStr.substr(start, end - start + 1); 30606f6ba60Sopenharmony_ci if (std::all_of(tempStr.begin(), tempStr.end(), ::isdigit)) { 30706f6ba60Sopenharmony_ci frequency = atoi(static_cast<char*>(buffer_)); 30806f6ba60Sopenharmony_ci } 30906f6ba60Sopenharmony_ci } 31006f6ba60Sopenharmony_ci return frequency; 31106f6ba60Sopenharmony_ci} 31206f6ba60Sopenharmony_ci 31306f6ba60Sopenharmony_ciint CpuDataPlugin::GetCpuCoreSize() 31406f6ba60Sopenharmony_ci{ 31506f6ba60Sopenharmony_ci int coreSize = 0; 31606f6ba60Sopenharmony_ci DIR* procDir = nullptr; 31706f6ba60Sopenharmony_ci procDir = OpenDestDir(freqPath_); 31806f6ba60Sopenharmony_ci CHECK_NOTNULL(procDir, -1, "procDir is nullptr"); 31906f6ba60Sopenharmony_ci 32006f6ba60Sopenharmony_ci while (struct dirent* dirEnt = readdir(procDir)) { 32106f6ba60Sopenharmony_ci if (dirEnt->d_type != DT_DIR) { 32206f6ba60Sopenharmony_ci continue; 32306f6ba60Sopenharmony_ci } 32406f6ba60Sopenharmony_ci if (strncmp(dirEnt->d_name, "cpu", strlen("cpu")) == 0) { 32506f6ba60Sopenharmony_ci coreSize++; 32606f6ba60Sopenharmony_ci } 32706f6ba60Sopenharmony_ci } 32806f6ba60Sopenharmony_ci closedir(procDir); 32906f6ba60Sopenharmony_ci return coreSize; 33006f6ba60Sopenharmony_ci} 33106f6ba60Sopenharmony_ci 33206f6ba60Sopenharmony_ciint32_t CpuDataPlugin::GetMaxCpuFrequencyIndex() 33306f6ba60Sopenharmony_ci{ 33406f6ba60Sopenharmony_ci int coreSize = GetCpuCoreSize(); 33506f6ba60Sopenharmony_ci int index = -1; 33606f6ba60Sopenharmony_ci int32_t maxFreq = -1; 33706f6ba60Sopenharmony_ci maxFrequencyVec_.clear(); 33806f6ba60Sopenharmony_ci minFrequencyVec_.clear(); 33906f6ba60Sopenharmony_ci for (int i = 0; i < coreSize; i++) { 34006f6ba60Sopenharmony_ci std::string fileName = freqPath_ + "/cpu" + std::to_string(i) + FREQUENCY_MAX_PATH; 34106f6ba60Sopenharmony_ci int32_t maxFrequency = GetCpuFrequency(fileName); 34206f6ba60Sopenharmony_ci maxFrequencyVec_.push_back(maxFrequency); 34306f6ba60Sopenharmony_ci fileName = freqPath_ + "/cpu" + std::to_string(i) + FREQUENCY_MIN_PATH; 34406f6ba60Sopenharmony_ci int32_t minFrequency = GetCpuFrequency(fileName); 34506f6ba60Sopenharmony_ci minFrequencyVec_.push_back(minFrequency); 34606f6ba60Sopenharmony_ci 34706f6ba60Sopenharmony_ci if (maxFreq < maxFrequency) { 34806f6ba60Sopenharmony_ci maxFreq = maxFrequency; 34906f6ba60Sopenharmony_ci index = i; 35006f6ba60Sopenharmony_ci } 35106f6ba60Sopenharmony_ci } 35206f6ba60Sopenharmony_ci 35306f6ba60Sopenharmony_ci // 单核或所有核最大频率相同,默认小核 35406f6ba60Sopenharmony_ci if (coreSize == 1 || (coreSize > 1 && index == 0 && maxFreq == maxFrequencyVec_[1])) { 35506f6ba60Sopenharmony_ci index = -1; 35606f6ba60Sopenharmony_ci } 35706f6ba60Sopenharmony_ci 35806f6ba60Sopenharmony_ci return index; 35906f6ba60Sopenharmony_ci} 36006f6ba60Sopenharmony_ci 36106f6ba60Sopenharmony_citemplate <typename T> void CpuDataPlugin::SetCpuFrequency(T& cpuCoreUsageInfo, int32_t coreNum) 36206f6ba60Sopenharmony_ci{ 36306f6ba60Sopenharmony_ci // 第一次获取最大频率核位置,并保存各核最大最小频率到vector 36406f6ba60Sopenharmony_ci if (maxFrequencyVec_.empty() || minFrequencyVec_.empty()) { 36506f6ba60Sopenharmony_ci maxFreqIndex_ = GetMaxCpuFrequencyIndex(); 36606f6ba60Sopenharmony_ci } 36706f6ba60Sopenharmony_ci std::string fileName = freqPath_ + "/cpu" + std::to_string(coreNum) + FREQUENCY_CUR_PATH; 36806f6ba60Sopenharmony_ci int32_t curFrequency = GetCpuFrequency(fileName); 36906f6ba60Sopenharmony_ci int32_t maxFrequency = maxFrequencyVec_[coreNum]; 37006f6ba60Sopenharmony_ci int32_t minFrequency = minFrequencyVec_[coreNum]; 37106f6ba60Sopenharmony_ci 37206f6ba60Sopenharmony_ci if (coreNum == maxFreqIndex_) { 37306f6ba60Sopenharmony_ci cpuCoreUsageInfo.set_is_little_core(false); 37406f6ba60Sopenharmony_ci } else { 37506f6ba60Sopenharmony_ci cpuCoreUsageInfo.set_is_little_core(true); 37606f6ba60Sopenharmony_ci } 37706f6ba60Sopenharmony_ci auto* frequency = cpuCoreUsageInfo.mutable_frequency(); 37806f6ba60Sopenharmony_ci frequency->set_min_frequency_khz(minFrequency); 37906f6ba60Sopenharmony_ci frequency->set_max_frequency_khz(maxFrequency); 38006f6ba60Sopenharmony_ci frequency->set_cur_frequency_khz(curFrequency); 38106f6ba60Sopenharmony_ci} 38206f6ba60Sopenharmony_ci 38306f6ba60Sopenharmony_cibool CpuDataPlugin::GetSystemCpuTime(std::vector<std::string>& cpuUsageVec, CpuTimeData& cpuTimeData) 38406f6ba60Sopenharmony_ci{ 38506f6ba60Sopenharmony_ci // 获取到的数据不包含user, nice, system, idle, iowait, irq, softirq, steal八个数值时返回 38606f6ba60Sopenharmony_ci CHECK_TRUE(cpuUsageVec.size() == SYSTEM_UNSPECIFIED, false, 38706f6ba60Sopenharmony_ci "%s:failed to get system cpu usage, size=%zu", __func__, cpuUsageVec.size()); 38806f6ba60Sopenharmony_ci 38906f6ba60Sopenharmony_ci int64_t user = 0; 39006f6ba60Sopenharmony_ci int64_t nice = 0; 39106f6ba60Sopenharmony_ci int64_t system = 0; 39206f6ba60Sopenharmony_ci int64_t idle = 0; 39306f6ba60Sopenharmony_ci int64_t iowait = 0; 39406f6ba60Sopenharmony_ci int64_t irq = 0; 39506f6ba60Sopenharmony_ci int64_t softirq = 0; 39606f6ba60Sopenharmony_ci int64_t steal = 0; 39706f6ba60Sopenharmony_ci user = atoi(cpuUsageVec[SYSTEM_USER].c_str()); 39806f6ba60Sopenharmony_ci nice = atoi(cpuUsageVec[SYSTEM_NICE].c_str()); 39906f6ba60Sopenharmony_ci system = atoi(cpuUsageVec[SYSTEM_SYSTEM].c_str()); 40006f6ba60Sopenharmony_ci idle = atoi(cpuUsageVec[SYSTEM_IDLE].c_str()); 40106f6ba60Sopenharmony_ci iowait = atoi(cpuUsageVec[SYSTEM_IOWAIT].c_str()); 40206f6ba60Sopenharmony_ci irq = atoi(cpuUsageVec[SYSTEM_IRQ].c_str()); 40306f6ba60Sopenharmony_ci softirq = atoi(cpuUsageVec[SYSTEM_SOFTIRQ].c_str()); 40406f6ba60Sopenharmony_ci steal = atoi(cpuUsageVec[SYSTEM_STEAL].c_str()); 40506f6ba60Sopenharmony_ci 40606f6ba60Sopenharmony_ci cpuTimeData.userModeUsageTime = user * GetUserHz(); 40706f6ba60Sopenharmony_ci cpuTimeData.systemModeUsageTime = system * GetUserHz(); 40806f6ba60Sopenharmony_ci cpuTimeData.systemUsageTime = (user + nice + system + irq + softirq + steal) * GetUserHz(); 40906f6ba60Sopenharmony_ci cpuTimeData.systemBootTime = cpuTimeData.systemUsageTime + (idle + iowait) * GetUserHz(); 41006f6ba60Sopenharmony_ci return true; 41106f6ba60Sopenharmony_ci} 41206f6ba60Sopenharmony_ci 41306f6ba60Sopenharmony_citemplate <typename T> 41406f6ba60Sopenharmony_civoid CpuDataPlugin::WriteSystemCpuUsage(T& cpuUsageInfo, CpuLoadData& cpuLoadData, const char* pFile, uint32_t fileLen) 41506f6ba60Sopenharmony_ci{ 41606f6ba60Sopenharmony_ci std::vector<std::string> cpuUsageVec; 41706f6ba60Sopenharmony_ci size_t cpuLength = strlen("cpu"); 41806f6ba60Sopenharmony_ci std::stringstream ss(pFile); 41906f6ba60Sopenharmony_ci std::string line; 42006f6ba60Sopenharmony_ci while (std::getline(ss, line)) { 42106f6ba60Sopenharmony_ci BufferSplitter totalbuffer(const_cast<char*>(line.c_str()), line.length()); 42206f6ba60Sopenharmony_ci totalbuffer.NextWord(' '); 42306f6ba60Sopenharmony_ci if (!totalbuffer.CurWord() || strncmp(totalbuffer.CurWord(), "cpu", cpuLength) != 0) { 42406f6ba60Sopenharmony_ci return; 42506f6ba60Sopenharmony_ci } 42606f6ba60Sopenharmony_ci 42706f6ba60Sopenharmony_ci for (int i = 0; i < SYSTEM_STAT_COUNT; i++) { 42806f6ba60Sopenharmony_ci if (!totalbuffer.CurWord()) { 42906f6ba60Sopenharmony_ci return; 43006f6ba60Sopenharmony_ci } 43106f6ba60Sopenharmony_ci std::string curWord = std::string(totalbuffer.CurWord(), totalbuffer.CurWordSize()); 43206f6ba60Sopenharmony_ci cpuUsageVec.push_back(curWord); 43306f6ba60Sopenharmony_ci totalbuffer.NextWord(' '); 43406f6ba60Sopenharmony_ci } 43506f6ba60Sopenharmony_ci 43606f6ba60Sopenharmony_ci // 获取数据失败返回 43706f6ba60Sopenharmony_ci CpuTimeData cpuTimeData; 43806f6ba60Sopenharmony_ci if (!GetSystemCpuTime(cpuUsageVec, cpuTimeData)) { 43906f6ba60Sopenharmony_ci return; 44006f6ba60Sopenharmony_ci } 44106f6ba60Sopenharmony_ci 44206f6ba60Sopenharmony_ci if (strcmp(cpuUsageVec[0].c_str(), "cpu") == 0) { 44306f6ba60Sopenharmony_ci cpuUsageInfo.set_prev_system_cpu_time_ms(prevCpuTimeData_.systemUsageTime); 44406f6ba60Sopenharmony_ci cpuUsageInfo.set_prev_system_boot_time_ms(prevCpuTimeData_.systemBootTime); 44506f6ba60Sopenharmony_ci cpuUsageInfo.set_system_cpu_time_ms(cpuTimeData.systemUsageTime); 44606f6ba60Sopenharmony_ci cpuUsageInfo.set_system_boot_time_ms(cpuTimeData.systemBootTime); 44706f6ba60Sopenharmony_ci bool isTest = false; 44806f6ba60Sopenharmony_ci if (strncmp(path_.c_str(), "/proc/", strlen("/proc/")) != 0) { 44906f6ba60Sopenharmony_ci isTest = true; // UT needs report load data for the first time 45006f6ba60Sopenharmony_ci } 45106f6ba60Sopenharmony_ci if ((protoConfig_.report_process_info() && prevCpuTimeData_.systemBootTime != 0) || isTest) { 45206f6ba60Sopenharmony_ci cpuLoadData.userLoad = static_cast<double>(cpuTimeData.userModeUsageTime - 45306f6ba60Sopenharmony_ci prevCpuTimeData_.userModeUsageTime) / 45406f6ba60Sopenharmony_ci static_cast<double>(cpuTimeData.systemBootTime - 45506f6ba60Sopenharmony_ci prevCpuTimeData_.systemBootTime) * PERCENT; 45606f6ba60Sopenharmony_ci cpuLoadData.sysLoad = static_cast<double>(cpuTimeData.systemModeUsageTime - 45706f6ba60Sopenharmony_ci prevCpuTimeData_.systemModeUsageTime) / 45806f6ba60Sopenharmony_ci static_cast<double>(cpuTimeData.systemBootTime - 45906f6ba60Sopenharmony_ci prevCpuTimeData_.systemBootTime) * PERCENT; 46006f6ba60Sopenharmony_ci cpuLoadData.totalLoad = static_cast<double>(cpuTimeData.systemUsageTime - 46106f6ba60Sopenharmony_ci prevCpuTimeData_.systemUsageTime) / 46206f6ba60Sopenharmony_ci static_cast<double>(cpuTimeData.systemBootTime - 46306f6ba60Sopenharmony_ci prevCpuTimeData_.systemBootTime) * PERCENT; 46406f6ba60Sopenharmony_ci } 46506f6ba60Sopenharmony_ci prevCpuTimeData_ = cpuTimeData; 46606f6ba60Sopenharmony_ci if (pid_ < 0 && protoConfig_.report_process_info()) { 46706f6ba60Sopenharmony_ci return; 46806f6ba60Sopenharmony_ci } 46906f6ba60Sopenharmony_ci } else { 47006f6ba60Sopenharmony_ci std::string core = std::string(cpuUsageVec[0].c_str() + cpuLength, cpuUsageVec[0].size() - cpuLength); 47106f6ba60Sopenharmony_ci int32_t coreNum = atoi(core.c_str()); 47206f6ba60Sopenharmony_ci // 第一次获取数据时需要将前一个数据置为0 47306f6ba60Sopenharmony_ci if (prevCoreSystemCpuTimeMap_.size() == static_cast<size_t>(coreNum)) { 47406f6ba60Sopenharmony_ci prevCoreSystemCpuTimeMap_[coreNum] = 0; 47506f6ba60Sopenharmony_ci prevCoreSystemBootTimeMap_[coreNum] = 0; 47606f6ba60Sopenharmony_ci } 47706f6ba60Sopenharmony_ci auto* cpuCore = cpuUsageInfo.add_cores(); 47806f6ba60Sopenharmony_ci cpuCore->set_cpu_core(coreNum); 47906f6ba60Sopenharmony_ci cpuCore->set_prev_system_cpu_time_ms(prevCoreSystemCpuTimeMap_[coreNum]); 48006f6ba60Sopenharmony_ci cpuCore->set_prev_system_boot_time_ms(prevCoreSystemBootTimeMap_[coreNum]); 48106f6ba60Sopenharmony_ci cpuCore->set_system_cpu_time_ms(cpuTimeData.systemUsageTime); 48206f6ba60Sopenharmony_ci cpuCore->set_system_boot_time_ms(cpuTimeData.systemBootTime); 48306f6ba60Sopenharmony_ci 48406f6ba60Sopenharmony_ci SetCpuFrequency(*cpuCore, coreNum); 48506f6ba60Sopenharmony_ci prevCoreSystemCpuTimeMap_[coreNum] = cpuTimeData.systemUsageTime; 48606f6ba60Sopenharmony_ci prevCoreSystemBootTimeMap_[coreNum] = cpuTimeData.systemBootTime; 48706f6ba60Sopenharmony_ci } 48806f6ba60Sopenharmony_ci 48906f6ba60Sopenharmony_ci cpuUsageVec.clear(); 49006f6ba60Sopenharmony_ci } 49106f6ba60Sopenharmony_ci} 49206f6ba60Sopenharmony_ci 49306f6ba60Sopenharmony_citemplate <typename T, typename I> void CpuDataPlugin::WriteCpuUsageInfo(T& cpuData, I cpuUsageInfo) 49406f6ba60Sopenharmony_ci{ 49506f6ba60Sopenharmony_ci // write process info 49606f6ba60Sopenharmony_ci if (pid_ > 0) { 49706f6ba60Sopenharmony_ci std::string fileName = path_ + std::to_string(pid_) + "/stat"; 49806f6ba60Sopenharmony_ci int32_t ret = ReadFile(fileName); 49906f6ba60Sopenharmony_ci if (ret == RET_FAIL) { 50006f6ba60Sopenharmony_ci return; 50106f6ba60Sopenharmony_ci } 50206f6ba60Sopenharmony_ci if ((buffer_ == nullptr) || (ret == 0)) { 50306f6ba60Sopenharmony_ci return; 50406f6ba60Sopenharmony_ci } 50506f6ba60Sopenharmony_ci 50606f6ba60Sopenharmony_ci cpuUsageInfo = cpuData.mutable_cpu_usage_info(); 50706f6ba60Sopenharmony_ci WriteProcessCpuUsage(*cpuUsageInfo, reinterpret_cast<char*>(buffer_), ret); 50806f6ba60Sopenharmony_ci } 50906f6ba60Sopenharmony_ci 51006f6ba60Sopenharmony_ci // write system info 51106f6ba60Sopenharmony_ci std::string fileName = path_ + "stat"; 51206f6ba60Sopenharmony_ci int32_t ret = ReadFile(fileName); 51306f6ba60Sopenharmony_ci if (ret == RET_FAIL) { 51406f6ba60Sopenharmony_ci return; 51506f6ba60Sopenharmony_ci } 51606f6ba60Sopenharmony_ci if ((buffer_ == nullptr) || (ret == 0)) { 51706f6ba60Sopenharmony_ci return; 51806f6ba60Sopenharmony_ci } 51906f6ba60Sopenharmony_ci 52006f6ba60Sopenharmony_ci CpuLoadData cpuLoadData; 52106f6ba60Sopenharmony_ci if (cpuUsageInfo == nullptr) { 52206f6ba60Sopenharmony_ci cpuUsageInfo = cpuData.mutable_cpu_usage_info(); 52306f6ba60Sopenharmony_ci } 52406f6ba60Sopenharmony_ci WriteSystemCpuUsage(*cpuUsageInfo, cpuLoadData, reinterpret_cast<char*>(buffer_), ret); 52506f6ba60Sopenharmony_ci 52606f6ba60Sopenharmony_ci auto* timestamp = cpuUsageInfo->mutable_timestamp(); 52706f6ba60Sopenharmony_ci SetTimestamp(*timestamp); 52806f6ba60Sopenharmony_ci 52906f6ba60Sopenharmony_ci cpuData.set_user_load(cpuLoadData.userLoad); 53006f6ba60Sopenharmony_ci cpuData.set_sys_load(cpuLoadData.sysLoad); 53106f6ba60Sopenharmony_ci cpuData.set_total_load(cpuLoadData.totalLoad); 53206f6ba60Sopenharmony_ci} 53306f6ba60Sopenharmony_ci 53406f6ba60Sopenharmony_cibool CpuDataPlugin::addTidBySort(int32_t tid) 53506f6ba60Sopenharmony_ci{ 53606f6ba60Sopenharmony_ci auto tidsEnd = tidVec_.end(); 53706f6ba60Sopenharmony_ci auto it = std::lower_bound(tidVec_.begin(), tidsEnd, tid); 53806f6ba60Sopenharmony_ci CHECK_TRUE(!(it != tidsEnd && *it == tid), false, "addTidBySort failed"); 53906f6ba60Sopenharmony_ci it = tidVec_.insert(it, std::move(tid)); 54006f6ba60Sopenharmony_ci return true; 54106f6ba60Sopenharmony_ci} 54206f6ba60Sopenharmony_ci 54306f6ba60Sopenharmony_ciDIR* CpuDataPlugin::OpenDestDir(std::string& dirPath) 54406f6ba60Sopenharmony_ci{ 54506f6ba60Sopenharmony_ci DIR* destDir = nullptr; 54606f6ba60Sopenharmony_ci 54706f6ba60Sopenharmony_ci destDir = opendir(dirPath.c_str()); 54806f6ba60Sopenharmony_ci CHECK_NOTNULL(destDir, nullptr, "%s:failed to opendir(%s), errno=%d", __func__, dirPath.c_str(), errno); 54906f6ba60Sopenharmony_ci 55006f6ba60Sopenharmony_ci return destDir; 55106f6ba60Sopenharmony_ci} 55206f6ba60Sopenharmony_ci 55306f6ba60Sopenharmony_ciint32_t CpuDataPlugin::GetValidTid(DIR* dirp) 55406f6ba60Sopenharmony_ci{ 55506f6ba60Sopenharmony_ci CHECK_TRUE(dirp, 0, "dirp is nullptr"); 55606f6ba60Sopenharmony_ci while (struct dirent* dirEnt = readdir(dirp)) { 55706f6ba60Sopenharmony_ci if (dirEnt->d_type != DT_DIR) { 55806f6ba60Sopenharmony_ci continue; 55906f6ba60Sopenharmony_ci } 56006f6ba60Sopenharmony_ci 56106f6ba60Sopenharmony_ci int32_t tid = atoi(dirEnt->d_name); 56206f6ba60Sopenharmony_ci if (tid) { 56306f6ba60Sopenharmony_ci return tid; 56406f6ba60Sopenharmony_ci } 56506f6ba60Sopenharmony_ci } 56606f6ba60Sopenharmony_ci return 0; 56706f6ba60Sopenharmony_ci} 56806f6ba60Sopenharmony_ci 56906f6ba60Sopenharmony_ciThreadState CpuDataPlugin::GetThreadState(const char threadState) 57006f6ba60Sopenharmony_ci{ 57106f6ba60Sopenharmony_ci ThreadState state = THREAD_UNSPECIFIED; 57206f6ba60Sopenharmony_ci switch (threadState) { 57306f6ba60Sopenharmony_ci case 'R': 57406f6ba60Sopenharmony_ci state = THREAD_RUNNING; 57506f6ba60Sopenharmony_ci break; 57606f6ba60Sopenharmony_ci case 'S': 57706f6ba60Sopenharmony_ci state = THREAD_SLEEPING; 57806f6ba60Sopenharmony_ci break; 57906f6ba60Sopenharmony_ci case 'T': 58006f6ba60Sopenharmony_ci state = THREAD_STOPPED; 58106f6ba60Sopenharmony_ci break; 58206f6ba60Sopenharmony_ci case 'D': 58306f6ba60Sopenharmony_ci state = THREAD_WAITING; 58406f6ba60Sopenharmony_ci break; 58506f6ba60Sopenharmony_ci default: 58606f6ba60Sopenharmony_ci break; 58706f6ba60Sopenharmony_ci } 58806f6ba60Sopenharmony_ci 58906f6ba60Sopenharmony_ci return state; 59006f6ba60Sopenharmony_ci} 59106f6ba60Sopenharmony_ci 59206f6ba60Sopenharmony_citemplate <typename T> void CpuDataPlugin::WriteThread(T& threadInfo, const char* pFile, uint32_t fileLen, int32_t tid) 59306f6ba60Sopenharmony_ci{ 59406f6ba60Sopenharmony_ci BufferSplitter totalbuffer(const_cast<char*>(pFile), fileLen + 1); 59506f6ba60Sopenharmony_ci std::vector<std::string> cpuUsageVec; 59606f6ba60Sopenharmony_ci for (int i = 0; i < STAT_COUNT; i++) { 59706f6ba60Sopenharmony_ci if (i == THREAD_NAME_POS) { // 线程名是')'作为结束符 59806f6ba60Sopenharmony_ci totalbuffer.NextWord(')'); 59906f6ba60Sopenharmony_ci } else { 60006f6ba60Sopenharmony_ci totalbuffer.NextWord(' '); 60106f6ba60Sopenharmony_ci } 60206f6ba60Sopenharmony_ci 60306f6ba60Sopenharmony_ci if (!totalbuffer.CurWord()) { 60406f6ba60Sopenharmony_ci return; 60506f6ba60Sopenharmony_ci } 60606f6ba60Sopenharmony_ci 60706f6ba60Sopenharmony_ci if (i == THREAD_NAME_POS) { 60806f6ba60Sopenharmony_ci size_t nameLeng = totalbuffer.CurWordSize() > 1 ? static_cast<size_t>(totalbuffer.CurWordSize() - 1) : 0; 60906f6ba60Sopenharmony_ci std::string curWord = std::string(totalbuffer.CurWord() + 1, nameLeng); 61006f6ba60Sopenharmony_ci threadInfo.set_thread_name(curWord); 61106f6ba60Sopenharmony_ci } else if (i == THREAD_STATE_POS) { 61206f6ba60Sopenharmony_ci std::string curWord = std::string(totalbuffer.CurWord(), totalbuffer.CurWordSize()); 61306f6ba60Sopenharmony_ci ThreadState state = GetThreadState(curWord[0]); 61406f6ba60Sopenharmony_ci threadInfo.set_thread_state(state); 61506f6ba60Sopenharmony_ci } else if (i >= STAT_START) { 61606f6ba60Sopenharmony_ci std::string curWord = std::string(totalbuffer.CurWord(), totalbuffer.CurWordSize()); 61706f6ba60Sopenharmony_ci cpuUsageVec.push_back(curWord); 61806f6ba60Sopenharmony_ci } 61906f6ba60Sopenharmony_ci } 62006f6ba60Sopenharmony_ci 62106f6ba60Sopenharmony_ci // 获取到的数据不包含utime、stime、cutime、cstime四个数值时返回 62206f6ba60Sopenharmony_ci if (cpuUsageVec.size() != PROCESS_UNSPECIFIED) { 62306f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, "%s:failed to get thread cpu usage, size=%zu", __func__, cpuUsageVec.size()); 62406f6ba60Sopenharmony_ci return; 62506f6ba60Sopenharmony_ci } 62606f6ba60Sopenharmony_ci 62706f6ba60Sopenharmony_ci // 第一次获取该线程数据时需要将前一个数据置为0 62806f6ba60Sopenharmony_ci if (prevThreadCpuTimeMap_.find(tid) == prevThreadCpuTimeMap_.end()) { 62906f6ba60Sopenharmony_ci prevThreadCpuTimeMap_[tid] = 0; 63006f6ba60Sopenharmony_ci } 63106f6ba60Sopenharmony_ci 63206f6ba60Sopenharmony_ci int64_t usageTime = GetCpuUsageTime(cpuUsageVec); 63306f6ba60Sopenharmony_ci threadInfo.set_prev_thread_cpu_time_ms(prevThreadCpuTimeMap_[tid]); 63406f6ba60Sopenharmony_ci threadInfo.set_thread_cpu_time_ms(usageTime); 63506f6ba60Sopenharmony_ci prevThreadCpuTimeMap_[tid] = usageTime; 63606f6ba60Sopenharmony_ci threadInfo.set_tid(tid); 63706f6ba60Sopenharmony_ci 63806f6ba60Sopenharmony_ci auto* timestamp = threadInfo.mutable_timestamp(); 63906f6ba60Sopenharmony_ci SetTimestamp(*timestamp); 64006f6ba60Sopenharmony_ci} 64106f6ba60Sopenharmony_ci 64206f6ba60Sopenharmony_citemplate <typename T> void CpuDataPlugin::WriteSingleThreadInfo(T& cpuData, int32_t tid) 64306f6ba60Sopenharmony_ci{ 64406f6ba60Sopenharmony_ci std::string fileName = path_ + std::to_string(pid_) + "/task/" + std::to_string(tid) + "/stat"; 64506f6ba60Sopenharmony_ci int32_t ret = ReadFile(fileName); 64606f6ba60Sopenharmony_ci if (ret == RET_FAIL) { 64706f6ba60Sopenharmony_ci return; 64806f6ba60Sopenharmony_ci } 64906f6ba60Sopenharmony_ci if ((buffer_ == nullptr) || (ret == 0)) { 65006f6ba60Sopenharmony_ci return; 65106f6ba60Sopenharmony_ci } 65206f6ba60Sopenharmony_ci auto* threadInfo = cpuData.add_thread_info(); 65306f6ba60Sopenharmony_ci WriteThread(*threadInfo, reinterpret_cast<char*>(buffer_), ret, tid); 65406f6ba60Sopenharmony_ci} 65506f6ba60Sopenharmony_ci 65606f6ba60Sopenharmony_citemplate <typename T> void CpuDataPlugin::WriteThreadInfo(T& cpuData) 65706f6ba60Sopenharmony_ci{ 65806f6ba60Sopenharmony_ci DIR* procDir = nullptr; 65906f6ba60Sopenharmony_ci std::string path = path_ + std::to_string(pid_) + "/task"; 66006f6ba60Sopenharmony_ci procDir = OpenDestDir(path); 66106f6ba60Sopenharmony_ci if (procDir == nullptr) { 66206f6ba60Sopenharmony_ci return; 66306f6ba60Sopenharmony_ci } 66406f6ba60Sopenharmony_ci 66506f6ba60Sopenharmony_ci tidVec_.clear(); 66606f6ba60Sopenharmony_ci while (int32_t tid = GetValidTid(procDir)) { 66706f6ba60Sopenharmony_ci addTidBySort(tid); 66806f6ba60Sopenharmony_ci } 66906f6ba60Sopenharmony_ci 67006f6ba60Sopenharmony_ci for (unsigned int i = 0; i < tidVec_.size(); i++) { 67106f6ba60Sopenharmony_ci WriteSingleThreadInfo(cpuData, tidVec_[i]); 67206f6ba60Sopenharmony_ci } 67306f6ba60Sopenharmony_ci closedir(procDir); 67406f6ba60Sopenharmony_ci} 67506f6ba60Sopenharmony_ci 67606f6ba60Sopenharmony_ci// for UT 67706f6ba60Sopenharmony_civoid CpuDataPlugin::SetFreqPath(std::string path) 67806f6ba60Sopenharmony_ci{ 67906f6ba60Sopenharmony_ci freqPath_ = path + FREQUENCY_PATH; 68006f6ba60Sopenharmony_ci} 681