diff --git a/BUILD.gn b/BUILD.gn index fc23c698274daa161258abb68748c08216c5a744..2310e0ec38ba449e4eda55d99f3b1410f9416006 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -203,7 +203,9 @@ ohos_source_set("hiperf_platform_common") { if (is_ohos) { external_deps = [ + "cJSON:cjson", "c_utils:utils", + "config_policy:configpolicy_util", "faultloggerd:libunwinder", "hilog:libhilog", "hisysevent:libhisysevent", @@ -211,6 +213,7 @@ ohos_source_set("hiperf_platform_common") { "ipc:ipc_core", "samgr:samgr_proxy", ] + defines += [ "CONFIG_HAS_CCM" ] if (bundle_framework_enable) { external_deps += [ "bundle_framework:appexecfwk_base", @@ -252,10 +255,12 @@ ohos_source_set("hiperf_platform_linux") { if (is_ohos) { external_deps = [ + "cJSON:cjson", "faultloggerd:libunwinder", "hilog:libhilog", "init:libbegetutil", ] + defines = [ "CONFIG_HAS_CCM" ] } else { external_deps = [ "faultloggerd:unwinder_host" ] } diff --git a/bundle.json b/bundle.json index b0746e845e1248815e31e4f26ffa9e1b7df34a3f..3d7200faee567d3915cf637caac8933c3c954a08 100644 --- a/bundle.json +++ b/bundle.json @@ -23,7 +23,9 @@ "abseil-cpp", "bounds_checking_function", "bundle_framework", + "cJSON", "c_utils", + "config_policy", "faultloggerd", "hilog", "hisysevent", diff --git a/include/perf_events.h b/include/perf_events.h index 38004e6c48f9fcae91633639a3681035609aa2c1..29abc2cd8a9f67968a7dcc05c0da9b58a595e577 100644 --- a/include/perf_events.h +++ b/include/perf_events.h @@ -574,6 +574,13 @@ private: bool HaveTargetsExit(const std::chrono::steady_clock::time_point &startTime); void ExitReadRecordBufThread(); +#ifdef CONFIG_HAS_CCM + static constexpr char PRODUCT_CONFIG_PATH[] = "etc/hiperf/hiperf_cfg.json"; + static constexpr char CFG_MAX_BUFFER_SIZE[] = "MaxBufferSize"; + static constexpr char CFG_MIN_BUFFER_SIZE[] = "MinBufferSize"; + void GetBufferSizeCfg(size_t &maxBufferSize, size_t &minBufferSize); +#endif + enum EventSpaceType { UNKNOW = 0, USER = 1, diff --git a/include/subcommand_record.h b/include/subcommand_record.h index 35f06d2edffd651f85d81f42e7726543cae94820..ec04145e61a3606d00739b053082cb1ec4950934 100644 --- a/include/subcommand_record.h +++ b/include/subcommand_record.h @@ -280,6 +280,12 @@ private: void OutputRecordFile(); bool PostOutputRecordFile(bool output); +#ifdef CONFIG_HAS_CCM + static constexpr char PRODUCT_CONFIG_PATH[] = "etc/hiperf/hiperf_cfg.json"; + static constexpr char CFG_MAP_PAGES[] = "MmapPages"; + void GetMmapPagesCfg(); +#endif + bool GetOptions(std::vector &args); bool CheckArgsRange(); bool CheckExcludeArgs(); diff --git a/include/utilities.h b/include/utilities.h index b8923343f9ec08e4f58425b157b42ec1bcb14991..c585986c9740f85362de39eac3cec890d5994b7b 100644 --- a/include/utilities.h +++ b/include/utilities.h @@ -41,6 +41,11 @@ #include #endif #include + +#ifdef CONFIG_HAS_CCM +#include "cJSON.h" +#endif + #include "debug_logger.h" #include "noncopyable.h" @@ -399,6 +404,12 @@ inline bool CheckOutOfRange(const T& value, const T& min, const T& max) } \ } while (0) +#ifdef CONFIG_HAS_CCM +cJSON* GetProductCfgRoot(const char* cfgPath); +cJSON* ParseJson(const std::string &filePath); +bool GetJsonNum(cJSON* tag, const char* key, size_t &value); +bool GetCfgValue(const char* cfgPath, const char* cfgKey, size_t &value); +#endif } // namespace HiPerf } // namespace Developtools } // namespace OHOS diff --git a/src/perf_events.cpp b/src/perf_events.cpp index 6c98ef9ae3dbfc69ca8436df1a31e24723764cd3..6e7c89a4d3b6b8f33585a32d3b21793392fb12f1 100644 --- a/src/perf_events.cpp +++ b/src/perf_events.cpp @@ -1333,7 +1333,7 @@ bool PerfEvents::CreateMmap(const FdItem &item, const perf_event_attr &attr) cpuMmap_[item.cpu] = mmapItem; pollFds_.emplace_back(pollfd {mmapItem.fd, POLLIN, 0}); - HLOGD("CreateMmap success cpu %d fd %d", item.cpu, mmapItem.fd); + HLOGD("CreateMmap success cpu %d fd %d mmapPages_ %u", item.cpu, mmapItem.fd, mmapPages_); } else { const MmapFd &mmapItem = it->second; int rc = ioctl(item.fd.Get(), PERF_EVENT_IOC_SET_OUTPUT, mmapItem.fd); @@ -1368,6 +1368,32 @@ std::vector PerfEvents::GetAttrWithId() const return result; } +#ifdef CONFIG_HAS_CCM +void PerfEvents::GetBufferSizeCfg(size_t &maxBufferSize, size_t &minBufferSize) +{ + size_t tmpMaxBufferSize = 0; + size_t tmpMinBufferSize = 0; + if (GetCfgValue(PRODUCT_CONFIG_PATH, CFG_MAX_BUFFER_SIZE, tmpMaxBufferSize)) { + if (!CheckOutOfRange(tmpMaxBufferSize, BUFFER_LOW_LEVEL, MAX_BUFFER_SIZE_LARGE)) { + maxBufferSize = tmpMaxBufferSize; + HIPERF_HILOGI(MODULE_DEFAULT, "GetCfgValue %s: %zu", CFG_MAX_BUFFER_SIZE, maxBufferSize); + } else { + HIPERF_HILOGE(MODULE_DEFAULT, "GetCfgValue %s failed, %zu out of range", + CFG_MAX_BUFFER_SIZE, tmpMaxBufferSize); + } + } + if (GetCfgValue(PRODUCT_CONFIG_PATH, CFG_MIN_BUFFER_SIZE, tmpMinBufferSize)) { + if (!CheckOutOfRange(tmpMinBufferSize, BUFFER_LOW_LEVEL, MAX_BUFFER_SIZE_LARGE)) { + minBufferSize = tmpMinBufferSize; + HIPERF_HILOGI(MODULE_DEFAULT, "GetCfgValue %s: %zu", CFG_MIN_BUFFER_SIZE, minBufferSize); + } else { + HIPERF_HILOGE(MODULE_DEFAULT, "GetCfgValue %s failed, %zu out of range", + CFG_MIN_BUFFER_SIZE, tmpMinBufferSize); + } + } +} +#endif + size_t PerfEvents::CalcBufferSize() { size_t maxBufferSize; @@ -1376,14 +1402,18 @@ size_t PerfEvents::CalcBufferSize() } else { maxBufferSize = MAX_BUFFER_SIZE_LARGE; } + size_t minBufferSize = MIN_BUFFER_SIZE; +#ifdef CONFIG_HAS_CCM + GetBufferSizeCfg(maxBufferSize, minBufferSize); +#endif size_t bufferSize = maxBufferSize; if (backtrack_ || !systemTarget_) { // suppose ring buffer is 4 times as much as mmap static constexpr int TIMES = 4; bufferSize = cpuMmap_.size() * mmapPages_ * pageSize_ * TIMES; - if (bufferSize < MIN_BUFFER_SIZE) { - bufferSize = MIN_BUFFER_SIZE; + if (bufferSize < minBufferSize) { + bufferSize = minBufferSize; } else if (bufferSize > maxBufferSize) { bufferSize = maxBufferSize; } diff --git a/src/subcommand_record.cpp b/src/subcommand_record.cpp index 330aa753fd7f8bf7127c62d46690a08dfe95fdfb..f183b7092594a589471707c336297c5c8602f0fd 100644 --- a/src/subcommand_record.cpp +++ b/src/subcommand_record.cpp @@ -550,8 +550,27 @@ bool SubCommandRecord::CheckOptions() return true; } +#ifdef CONFIG_HAS_CCM +void SubCommandRecord::GetMmapPagesCfg() +{ + size_t tmpPages = 0; + if (GetCfgValue(PRODUCT_CONFIG_PATH, CFG_MAP_PAGES, tmpPages)) { + int tmpValue = static_cast(tmpPages); + if (CheckOutOfRange(tmpValue, MIN_PERF_MMAP_PAGE, MAX_PERF_MMAP_PAGE) || !PowerOfTwo(tmpValue)) { + HIPERF_HILOGE(MODULE_DEFAULT, "GetCfgValue %s faile, %d out of range", CFG_MAP_PAGES, tmpValue); + } else { + mmapPages_ = tmpValue; + HIPERF_HILOGI(MODULE_DEFAULT, "GetCfgValue %s : %d", CFG_MAP_PAGES, mmapPages_); + } + } +} +#endif + bool SubCommandRecord::ParseOption(std::vector &args) { +#ifdef CONFIG_HAS_CCM + GetMmapPagesCfg(); +#endif if (!GetOptions(args)) { return false; } diff --git a/src/utilities.cpp b/src/utilities.cpp index 821870ee8f14576579df22ee11e8909f93b89cf9..4847eecf3e22fc54efebacd94c756899db2dce85 100644 --- a/src/utilities.cpp +++ b/src/utilities.cpp @@ -24,6 +24,9 @@ #include #endif +#ifdef CONFIG_HAS_CCM +#include "config_policy_utils.h" +#endif #include "hiperf_hilog.h" #include "ipc_utilities.h" @@ -892,6 +895,60 @@ bool IsNumeric(const std::string& str) } return true; } + +#ifdef CONFIG_HAS_CCM +cJSON* GetProductCfgRoot(const char* cfgPath) +{ + char buf[PATH_MAX] = {0}; + char* configFilePath = GetOneCfgFile(cfgPath, buf, PATH_MAX); + if (configFilePath == nullptr || (configFilePath[0] == '\0') || (strlen(configFilePath) > PATH_MAX)) { + HLOGD("get configFilePath from cfgPath %s failed", cfgPath); + return nullptr; + } + HLOGD("get configFilePath %s from cfgPath %s", configFilePath, cfgPath); + return ParseJson(configFilePath); +} + +cJSON* ParseJson(const std::string &filePath) +{ + std::ifstream inFile(filePath, std::ios::in); + if (!inFile.is_open()) { + HLOGE("open file %s failed", filePath.c_str()); + return nullptr; + } + std::string fileContent((std::istreambuf_iterator(inFile)), std::istreambuf_iterator()); + cJSON* root = cJSON_Parse(fileContent.c_str()); + inFile.close(); + return root; +} + +bool GetJsonNum(cJSON* tag, const char* key, size_t &value) +{ + cJSON* subNode = cJSON_GetObjectItem(tag, key); + if (subNode != nullptr && cJSON_IsNumber(subNode)) { + value = static_cast(subNode->valuedouble); + return true; + } + HLOGE("GetJsonNum key %s failed", key); + return false; +} + +bool GetCfgValue(const char* cfgPath, const char* cfgKey, size_t &value) +{ + bool ret = false; + cJSON* root = GetProductCfgRoot(cfgPath); + if (root == nullptr) { + HLOGD("GetProductCfgRoot file %s failed", cfgPath); + return ret; + } + if (GetJsonNum(root, cfgKey, value)) { + ret = true; + HLOGD("GetCfgValue %s: %zu", cfgKey, value); + } + cJSON_Delete(root); + return ret; +} +#endif } // namespace HiPerf } // namespace Developtools } // namespace OHOS diff --git a/test/BUILD.gn b/test/BUILD.gn index b513fd3b36854d28021bbf050eeb17fc68c76b50..22bc8a42b80703b9268ecaea42d693d8b9b7812d 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -105,6 +105,7 @@ ohos_unittest("hiperf_unittest") { defines = [ "SUPPORT_PERF_EVENT", "HIPERF_UNITTEST", + "CONFIG_HAS_CCM", ] public_deps = [] @@ -114,7 +115,9 @@ ohos_unittest("hiperf_unittest") { "abseil-cpp:absl_log", "abseil-cpp:absl_strings", "bounds_checking_function:libsec_shared", + "cJSON:cjson", "c_utils:utils", + "config_policy:configpolicy_util", "faultloggerd:libunwinder", "googletest:gmock", "hilog:libhilog", diff --git a/test/unittest/common/native/perf_events_test.cpp b/test/unittest/common/native/perf_events_test.cpp index 9fbca2335fd80c180e61254f6408b3a58939b1d8..2c2681b6eaba65c19eb42c0127ac6fe161b56c17 100644 --- a/test/unittest/common/native/perf_events_test.cpp +++ b/test/unittest/common/native/perf_events_test.cpp @@ -426,18 +426,22 @@ HWTEST_F(PerfEventsTest, CalcBufferSizeLargeMemory, TestSize.Level1) } PerfEvents event; + size_t maxBufferSize = PerfEvents::MAX_BUFFER_SIZE_LARGE; + size_t minBufferSize = PerfEvents::MIN_BUFFER_SIZE; + event.GetBufferSizeCfg(maxBufferSize, minBufferSize); + event.backtrack_ = false; event.systemTarget_ = true; - EXPECT_EQ(event.CalcBufferSize(), PerfEvents::MAX_BUFFER_SIZE_LARGE); + EXPECT_EQ(event.CalcBufferSize(), maxBufferSize); event.backtrack_ = true; event.cpuMmap_.clear(); - EXPECT_EQ(event.CalcBufferSize(), PerfEvents::MIN_BUFFER_SIZE); + EXPECT_EQ(event.CalcBufferSize(), minBufferSize); event.cpuMmap_[0] = {}; event.mmapPages_ = TEN_THOUSAND; event.pageSize_ = TEN_THOUSAND; - EXPECT_EQ(event.CalcBufferSize(), PerfEvents::MAX_BUFFER_SIZE_LARGE); + EXPECT_EQ(event.CalcBufferSize(), maxBufferSize); while (event.cpuMmap_.size() < SEVENTEEN) { event.cpuMmap_[event.cpuMmap_.size()] = {}; @@ -445,7 +449,9 @@ HWTEST_F(PerfEventsTest, CalcBufferSizeLargeMemory, TestSize.Level1) event.mmapPages_ = PAGE_SIZE; event.pageSize_ = PAGE_SIZE; static constexpr size_t EXPECT_SIZE = SEVENTEEN * PAGE_SIZE * PAGE_SIZE * 4; - EXPECT_EQ(event.CalcBufferSize(), EXPECT_SIZE); + if (!CheckOutOfRange(EXPECT_SIZE, minBufferSize, maxBufferSize)) { + EXPECT_EQ(event.CalcBufferSize(), EXPECT_SIZE); + } } HWTEST_F(PerfEventsTest, IsSkipRecordForBacktrack1, TestSize.Level1) diff --git a/test/unittest/common/native/subcommand_record_test.cpp b/test/unittest/common/native/subcommand_record_test.cpp index 24f62115112ddbf85129e1af24c99bd0cf6b4cb4..dce22265bbebba2b253ef644070a4e242fc8dc87 100644 --- a/test/unittest/common/native/subcommand_record_test.cpp +++ b/test/unittest/common/native/subcommand_record_test.cpp @@ -2176,6 +2176,18 @@ HWTEST_F(SubCommandRecordTest, CheckGetCountFromFile, TestSize.Level1) uint32_t cpuOnline = cmd.GetCountFromFile("/sys/devices/system/cpu/online"); ASSERT_GT(cpuOnline, 1); } + +HWTEST_F(SubCommandRecordTest, CheckProductCfg, TestSize.Level1) +{ + SubCommandRecord cmd; + cJSON* root = GetProductCfgRoot(cmd.PRODUCT_CONFIG_PATH); + if (root) { + size_t mmapPages = 0; + EXPECT_EQ(GetCfgValue(cmd.PRODUCT_CONFIG_PATH, cmd.CFG_MAP_PAGES, mmapPages), true); + cmd.GetMmapPagesCfg(); + cJSON_Delete(root); + } +} } // namespace HiPerf } // namespace Developtools } // namespace OHOS