1 /* 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #ifndef SUBCOMMAND_STAT_H_ 16 #define SUBCOMMAND_STAT_H_ 17 18 #include "option.h" 19 #include "perf_events.h" 20 #include "subcommand.h" 21 22 namespace OHOS { 23 namespace Developtools { 24 namespace HiPerf { 25 class SubCommandStat : public SubCommand { 26 public: 27 static constexpr int DEFAULT_CHECK_APP_MS = 10; 28 static constexpr int MIN_CHECK_APP_MS = 1; 29 static constexpr int MAX_CHECK_APP_MS = 200; SubCommandStat()30 SubCommandStat() 31 : SubCommand("stat", "Collect performance counter information", 32 // clang-format off 33 "Usage: hiperf stat [options] [command [command-args]]\n" 34 " Collect performance counter information of running [command].\n" 35 " The default options are: -c -1 -d 10000.0\n" 36 " -a\n" 37 " Collect system-wide information.\n" 38 " for measures all processes/threads\n" 39 " This requires CAP_PERFMON (since Linux 5.8) or\n" 40 " CAP_SYS_ADMIN capability or a\n" 41 " /proc/sys/kernel/perf_event_paranoid value of less than 1.\n" 42 " -c <cpuid>[<,cpuid>]\n" 43 " cpuid should be 0,1,2...\n" 44 " Limit the CPU that collects data.\n" 45 " 0 means cpu0, 1 means cpu1 ...\n" 46 " -d <sec>\n" 47 " stop in <sec> seconds.\n" 48 " floating point number.\n" 49 " default is 10000.0\n" 50 " -i <ms>\n" 51 " print stat info every <ms>.\n" 52 " -e event1[:<u|k>][,event1[:<u|k>]]...\n" 53 " Customize the name of the event that needs to be counted.\n" 54 " The name can use the names listed in the list parameter.\n" 55 " It can also be represented by the value of 0x<hex>.\n" 56 " u - monitor user space events only\n" 57 " k - monitor kernel space events only\n" 58 " -g <event1[:<u|k>]>[,event1[:<u|k>]]...\n" 59 " The grouping function is added on the basis of the function of the -e parameter\n" 60 " PMU is required to report data in designated groups\n" 61 " limited by HW capability, too many events cannot be reported in the same sampling)\n" 62 " --no-inherit\n" 63 " Don't track new processes/threads.\n" 64 " -p <pid1>[,pid2]...\n" 65 " Limit the process id of the collection target. Conflicts with the -a option.\n" 66 " -t <tid1>[,tid2]...\n" 67 " Limit the thread id of the collection target. Conflicts with the -a option.\n" 68 " --app <package_name>\n" 69 " Collect profile info for an OHOS app, the app must be debuggable.\n" 70 " Record will exit if the process is not started within 10 seconds.\n" 71 " --chkms <millisec>\n" 72 " Set the interval of querying the <package_name>.\n" 73 " <millisec> is in range [1-200], default is 10.\n" 74 " --per-core\n" 75 " Print counters for each cpu core.\n" 76 " --per-thread\n" 77 " Print counters for each thread.\n" 78 " --restart\n" 79 " Collect performance counter information of application startup.\n" 80 " Record will exit if the process is not started within 30 seconds.\n" 81 " --verbose\n" 82 " Show more detailed reports.\n" 83 " --dumpoptions\n" 84 " Dump command options.\n" 85 // clang-format on 86 ), 87 targetSystemWide_(false) 88 { 89 } 90 91 bool OnSubCommand(std::vector<std::string> &args) override; 92 bool ParseOption(std::vector<std::string> &args) override; 93 bool ParseSpecialOption(std::vector<std::string> &args); 94 void DumpOptions(void) const override; 95 96 private: 97 PerfEvents perfEvents_; 98 bool targetSystemWide_ {false}; 99 std::vector<int> selectCpus_ = {}; 100 float timeStopSec_ = PerfEvents::DEFAULT_TIMEOUT; 101 int timeReportMs_ {0}; 102 std::vector<std::vector<std::string>> selectEvents_; 103 std::vector<std::vector<std::string>> selectGroups_; 104 bool restart_ {false}; 105 bool noCreateNew_ {false}; 106 std::string appPackage_ = {}; 107 int checkAppMs_ = DEFAULT_CHECK_APP_MS; 108 std::vector<pid_t> selectPids_; 109 std::vector<pid_t> selectTids_; 110 bool perCpus_ {false}; 111 bool perThreads_ {false}; 112 bool verboseReport_ {false}; 113 std::vector<std::string> trackedCommand_ {}; 114 bool helpOption_ {false}; 115 bool CheckOptionPidAndApp(std::vector<pid_t> pids); 116 bool CheckOptionPid(std::vector<pid_t> pids); 117 static bool FindEventCount( 118 const std::map<std::string, std::unique_ptr<PerfEvents::CountEvent>> &countEvents, 119 const std::string &configName, const __u64 group_id, __u64 &eventcount, double &scale); 120 static void GetComments( 121 const std::map<std::string, std::unique_ptr<PerfEvents::CountEvent>> &countEvents, 122 std::map<std::string, std::string> &comments); 123 static bool FindRunningTime( 124 const std::map<std::string, std::unique_ptr<PerfEvents::CountEvent>> &countEvents, 125 double &running_time_in_sec, __u64 &group_id, double &main_scale); 126 static bool IsMonitoredAtAllTime(const double &scale); 127 static std::string GetCommentConfigName( 128 const std::unique_ptr<PerfEvents::CountEvent> &countEvent, std::string eventName); 129 130 static void Report(const std::map<std::string, std::unique_ptr<PerfEvents::CountEvent>> &countEvents); 131 static void PrintPerHead(); 132 static void GetPerKey(std::string &perKey, const PerfEvents::Summary &summary); 133 static void MakeComments(const std::unique_ptr<PerfEvents::ReportSum> &reportSum, std::string &commentStr); 134 static void ReportNormal(const std::map<std::string, std::unique_ptr<PerfEvents::CountEvent>> &countEvents); 135 static void ReportDetailInfos(const std::map<std::string, std::unique_ptr<PerfEvents::CountEvent>> &countEvents); 136 static void PrintPerValue(const std::unique_ptr<PerfEvents::ReportSum> &reportSum, const float &ratio, 137 std::string &configName); 138 static void InitPerMap(const std::unique_ptr<PerfEvents::ReportSum> &newPerMap, 139 const PerfEvents::Summary &summary, VirtualRuntime& virtualInstance); 140 static bool FindPerCoreEventCount(PerfEvents::Summary &summary, __u64 &eventCount, double &scale); 141 static bool FindPercoreRunningTime(PerfEvents::Summary &summary, double &running_time_in_sec, double &main_scale); 142 static std::string GetDetailComments(const std::unique_ptr<PerfEvents::CountEvent> &countEvent, double &comment, 143 PerfEvents::Summary &summary, std::string &configName); 144 static std::string HandleOtherConfig(double &comment, PerfEvents::Summary &summary, 145 double running_time_in_sec, double scale, bool findRunningTime); 146 147 void PrintUsage(); HelpOption()148 inline bool HelpOption() 149 { 150 return helpOption_; 151 } 152 bool PrepairEvents(); 153 bool CheckOptions(const std::vector<pid_t> &pids); 154 bool CheckSelectCpuPidOption(); 155 void SetReportFlags(bool cpuFlag, bool threadFlag); 156 void SetPerfEvent(); 157 }; 158 159 bool RegisterSubCommandStat(void); 160 } // namespace HiPerf 161 } // namespace Developtools 162 } // namespace OHOS 163 #endif // SUBCOMMAND_STAT_H_ 164